Home page of this blog

Thursday, December 1, 2011

IP alias or virtual ip address in Ubuntu Linux


Introduction 

Sometimes same physical ethernet device may need to impersonate to the outside world as n devices or n ip addresses. This maybe helpful in hosting n different servers without a need to goto n physical devices. Here comes the idea of virtual alias

Creating virtual ip or ip alias (this works in ubuntu)

Say my ipaddress is 192.168.2.2 and my ethernet device is eth0

then to create an ip alias 192.168.2.6 (provided this ip is not used by any in the network)


sudo ip addr add 192.168.2.6 dev eth0

To list down the alias names created

sudo ip addr show


Testing with a server hosted on two different ip now and see if it really works


To utilize the newly created alias I created a small webserver in java (java is super duper easy to test and I love java, C programmers can write the same code but with lots of lines and error handling … so leaving it for performance nuts, since this is just a concept I am sticking with java and I feel java is like scripting to me and free flowing from all my limbs, eyes and hands)

Again to compile/execute java you need openjdk or sun jdk
Name of program ServerTest.java



import java.net.*;
import java.io.*;
import java.util.*;

public class ServerTest implements Runnable
{

ServerSocket ser;
InetAddress inetAddress;

public ServerTest(byte[] address) throws Exception
{
inetAddress = InetAddress.getByAddress(address);

ser = new ServerSocket(80, //port of webserver
10, //backlog of 10
inetAddress);

Thread t = new Thread(this);

t.start();
}

public void run()
{

while(true)
try
{
Socket client = ser.accept();

InputStream inStream = client.getInputStream();
OutputStream outStream = client.getOutputStream();

BufferedReader in = new BufferedReader(new InputStreamReader(inStream));
PrintWriter out = new PrintWriter(outStream, true);


String line = in.readLine();

System.out.println(line);

String[] tokens = line.split(" ");

String method = tokens[0];
String uri = tokens[1];
String protocol = tokens[2];

out.println(protocol + " 200 OK");
out.println("Content-Type: text/html");


String greeting = "<html><body><h1>Welcome from " + inetAddress + "</h1></body></html>";


out.println("Content-Length: " + greeting.length());

out.println();

out.println(greeting);

out.close();
in.close();

}
catch(Exception ex)
{
ex.printStackTrace();
}
}

public static void main(String[] args) throws Exception
{
new ServerTest(new byte[]{(byte)192, (byte)168, (byte)2, (byte)6});
new ServerTest(new byte[]{(byte)192, (byte)168, (byte)2, (byte)2});
}
}


I assumed this program is pure http 1.1,  I will dissect and explain this program at the end of this article

to compile I used javac as follows

javac ServerTest.java

to run the program requires root privileges in Linux/Unix as I am listening on port 80 (if you want listen on some other port say 27000 which wont require root permissions, but while requesting webpage from browser, you need to use :27000 … and I am dead lazy )

so to run

sudo java ServerTest




and it will display nothing unless some browser hits this server…

Just wait, open another system/ipad/ipod touch/iphone/android phone/netbook/notebook/another device with a browser connected to same domain as the system running this java program

Here for testing, I opened my ipad browser

and accessed 192.168.2.2 (and it displayed a welcome with this ip identification), then accessed 192.168.2.6 (and it displayed welcome with this ip identification)


So what does it tell, each ip is virtual on its own, as good as a physical network. If you have linux and you are empowered (so dont buy another NIC … just create virtual ip and host different servers)

What say you?


Before winding up the article, here is a brief explanation of http protocol

Request comes from browser and response is given back from the server.

http request comes like this

METHOD URI PROTOCOL\r\n
Header-Name1: value\r\n
Header-Name2: value\r\n
\r\n
Entity or data


where each header-name is a key separated from value by colon and space
Each line ends with \r\n (CRLF)
and before data another blank line or CRLF

and followed by data. Usually headername almost always has Content-Length


and I parse the first line from the request thus

String line = in.readLine();

System.out.println(line);

String[] tokens = line.split(" ");

String method = tokens[0];
String uri = tokens[1];
String protocol = tokens[2];


see in.readLine() gets the first line from browser (once all tcp connections are made)

and I am using java’s powerful string to tokenize the line with space as delimiter (use strtok in C)

and the first token is method (which can be GET or POST or …)
and second is URI
third is protocol used by browser

I take the protocol and send back to the browser in my response

out.println(protocol + " 200 OK");
out.println("Content-Type: text/html");


String greeting = "<html><body><h1>Welcome from " + inetAddress + "</h1></body></html>";


out.println("Content-Length: " + greeting.length());

out.println();

out.println(greeting);

out.close();
in.close();


HTTP Response is of the form

PROTOCOL STATUSCODE MESSAGE\r\n
Header-Name1: value1\r\n

\r\n
Entity or data


See the line

String greeting = "<html><body><h1>Welcome from " + inetAddress + "</h1></body></html>";


Here I compose the greeting with the identifying virtual ip address (it means this instance is unique and tied only to its clients, not to clients of some other virtual ip address!!!!!!)

Rest I assume you would follow from code

References for virtual ip address on linux I followed and java it is my own or I wrote it for testing myself. HTTP well it is a protocol, go refer yourself

http://itsecureadmin.blogspot.com/2007/02/creating-virtual-ip-addresses-on-linux.html