Posts Tagged: networks


5
Feb 07

Rant of a network admin

Just because all of the devices are connected does not mean that everything will work well. Always look out for switching loops.


6
Jul 06

Sharing an Internet connection

I was finally able to set up my computer as a gateway to share an Internet connection yesterday.

I had no idea what I was doing wrong at first because I thought that the only thing that needed to be done was network address translation to make packets from the other computers appear as if they came from my computer. I was really confused because I could communicate with the first network interface of my computer from computers connected to the second interface, but I was not getting anything in my iptables FORWARD chain. I tested with several setups, seeing which packets went through which chains, until I realized that there had to be something disallowing packet-forwarding, and that after traversing the PREROUTING chain, all the packets that are for any interface, regardless of which interface they came from, are directed to the INPUT chain.

I looked around /proc and saw values that seemed to need toggling. I also checked the descriptions of the /proc files to be sure. Apparently, packet-forwarding is not enabled in the kernel by default. Enabling that, plus source network address translation, did the trick.

Considering an interface eth0 that is assigned 192.168.0.2/16 which is allowed to access the Internet, and an interface eth1 that is assigned 10.71.0.1/24 to which those computers that need an Internet connection are connected, the following procedure may be done:

  1. Set iptables to do source network address translation for packets from eth1 for eth0.
    # iptables -A POSTROUTING -t nat -s 10.71.0.0/24 -d ! 10.71.0.0/24 -j SNAT --to 192.168.0.2
  2. Enable packet-forwarding in your machine.
    # echo -n "1" > /proc/sys/net/ipv4/ip_forward
  3. Allow packet-forwarding for the involved interfaces.
    # echo -n "1" > /proc/sys/net/ipv4/conf/eth0/forwarding
    # echo -n "1" > /proc/sys/net/ipv4/conf/eth1/forwarding
  4. Set the default route of each computer connected to eth1 to the proper address.
    # route add default gw 10.71.0.1

This is, of course, considering that the FORWARD chain already allows connections between 10.71.0.0/24 and 192.168.0.0/16. In a default Ubuntu installation, the FORWARD chain is empty and has a chain policy of ACCEPT, so it should already be okay.


25
Jun 06

Busy first weeks

The first few weeks of each semester have always been very busy weeks for me, not because of terror teachers who bombard their students with piles of readings on the first days of classes, nor because of the usual back-to-school errands that students have to do. During these weeks, the members of the dormitory committee Ateneo Cervini-Eliazo Network Team (ACENT) are always up on their feet, crimping cables, fixing up keystone jacks, assisting other dormers in registering for Internet access and in setting up their systems for use in the network, diagnosing problems with messed up operating systems of other dormers, and dealing with problems that arise from changes in the network usually implemented during the break.

I would say that, for me at least, the first few weeks of classes are usually more stressful than the finals week. There are the physical stress of going from room to room, and back and forth rooms and the wiring cabinet, the mental stress brought by thinking about the number of people who still have problems with their connections and, when applicable, diagnosing network-wide problems, the emotional stress of having to deal with other people who sometimes get rather high-strung, and the self-imposed time pressure from knowing that the subscribers ought to be offered the services they pay for. Interestingly, it is usually the latter two that do the most damage.

Of course, this is just a small part of the ACENT experience. The new knowledge and insights, work experience in a real environment, friends met along the way, and great opportunity to serve are all worth this.


6
Apr 06

Reverse proxy servers

I have been reading on the Hypertext Transfer Protocol (HTTP). The simplicity of information exchange between an HTTP server and an HTTP client amazes me: besides the encapsulation done for a TCP connection, all other information sent is in a fairly simple format. To request for the page at http://google.com, for instance, the client may just send the following line to the server:

GET http://google.com HTTP/1.1

Then, upon receiving a request, a server may just send back:

HTTP/1.1 200 OK
Content-Type: text/html

Content goes here.

The World Wide Web Consortium (W3C) defines standards for HTTP request and response packets.

Now, what is the place of a regular proxy server in all this? If an HTTP client is connected to the Internet without having to pass through a proxy server, the request is traditionally sent to TCP port 80 of the web host, and the proxy server is the one that produces the response. After a little experimentation, I learned that if a proxy server is involved, the only difference is that the same request is sent to the specified port of the proxy server instead of the port of the web server – the request is sent as it is. The following code is a rather dirty and simple implementation of a reverse proxy that will return a default page for HTTP requests for any web page:

/*
 * reverse-proxy-server.c
 *
 * Responds with default data upon receiving an HTTP request for any web page
 *
 * USAGE:
 *   reverse-proxy-server
 *
 * LIMITATIONS:
 * 1. This script does not make use of a separate configuration file, and not
 * include proper signal handling.
 * 2. This script assumes that all information received are HTTP requests. For
 * information on the format of valid HTTP requests, visit
 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html.
 */

#include 
#include 
#include 
#include 
#include 

#define DEFAULT_PORT 3128
#define MAXIMUM_CLIENT_NUMBER 256
#define MAXIMUM_MESSAGE_LENGTH 256

int main(int argc, char *argv[]) {
    int server_socket, client_socket, port, sockaddr_in_length, pid;
    struct sockaddr_in server_address, client_address;
    char buffer[256];

    sockaddr_in_length = sizeof(struct sockaddr_in);

    // Create the server socket
    if ((server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        perror("Error creating socket.");
        return 1;
    }

    // Set up the server address
    memset((void *) &server_address, 0, sockaddr_in_length);
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = INADDR_ANY;
    server_address.sin_port = htons(DEFAULT_PORT);

    // Bind the socket to an address
    if (bind(server_socket, (struct sockaddr *) &server_address, sockaddr_in_length) < 0) {
        perror("Error binding socket.");
        return 1;
    }

    // Listen for connections
    listen(server_socket, MAXIMUM_CLIENT_NUMBER);

    while (1) {
        printf("Listening for a connection...n");

        // Accept connection
        if ((client_socket = accept(server_socket, (struct sockaddr *) &client_address, &sockaddr_in_length))

< 0) {
            perror("Error accepting incoming socket connection.");
            return 1;
        }

        printf("Accepted connection.n");

        pid = fork();

        if (pid == 0) {
            printf("Reading HTTP request...n");

            // Receive HTTP request from the client
            bzero(buffer, MAXIMUM_MESSAGE_LENGTH);
            read(client_socket, buffer, MAXIMUM_MESSAGE_LENGTH);
            printf("%sn", buffer);

            printf("Sending HTTP response...n");

            // Send HTTP reply to the client
            bzero(buffer, MAXIMUM_MESSAGE_LENGTH);
            strcpy(buffer, "HTTP-Version: HTTP/1.1 200 OKnContent-Type:

text/htmlnContent-Length: 18nnContent goes here.");
            write(client_socket, buffer, MAXIMUM_MESSAGE_LENGTH);

            printf("Successful.n");

            // Close socket connection
            close(client_socket);

            return 0;
        }
    }

    return 0;
}

Play around with the code if you are interested. To see this work on localhost:

  1. Compile the code using gcc.
    $ gcc -o reverse-proxy-server reverse-proxy-server.c
  2. Run the reverse proxy server.
    $ ./reverse-proxy-server
  3. Open your web browser.
  4. Set the HTTP proxy for your browser to localhost, and set the corresponding port number to 3128.
  5. Try to access any web page through your browser.

It is amazing. Once the general idea of the protocol has been grasped, simple web servers are not too difficult to conceptualize.