SIP application level gateway

Using SIP proxy server, SIPD , build an application level gateway (ALG) that can work with network address translation (NAT) and firewalls on Linux.

Consider the above diagram on how NAT works. Network address translation (RFC 1631) is a technique for translating one set of IP addresses known in one network to another set of IP addresses known in another. Typically, an organization maps its local inside private addresses to one or more global external public IP addresses. There are pre-defined private IP address spaces, e.g., 10.0.0.0 to 10.255.255.255 is one such range. These IP addresses do not have any global routing significance in the public internet. The source IP address in the outgoing IP packet is translated from private to public, and the destination IP address in the incoming packets from public to private. NAT conserves the global IP address space by prividing independent islands of private IP address networks. Above figure shows an example NAT processing. Usually the mapping is established when a new session (e.g., a TCP connection or a UDP packet) is established from a node in the the private network to a node in the public network. The mapping exists as long as the session is active.

Network address and port translation (NAPT) allows use of the same external public IP address for more than one internal private nodes by using TCP/UDP port number for multiplexing multiple sessions. We use NAPT in our architecture. As shown in above figure, when host A, with private address 10.0.1.23, sends a TCP SYN connection establishment packet to an external node B with public address 128.59.16.149, the packet is intercepted by the NAT router (10.0.0.1). This NAT box with external IP 135.180.132.24, creates a mapping from 10.0.1.23 port 1987 to its external IP 135.180.132.24 and port 1734. The packet is forwarded to node B, as if it was originated from the NAT box, by changing the source IP and port to 135.180.132.24 and 1734 respectively. NAT intercepts incoming packets, and changes the destination to 10.0.1.23 at port 1987. Node A thinks that it is connected to node B's IP, whereas node B thinks that it is connected to NAT's IP.

NAT devices break the application level protocols like RTSP, FTP and SIP that use the host and port information in the application payload for signaling. For example, the RTSP client in private address space may ask the server in public address space to stream the video to 10.0.1.23. However, this IP address is not visible for the public address node B. This is achieved using application level gateways on the NAT box, that can modify the application specific signaling messages for FTP or RTSP.

Milestone 1

Compile sipd and test with the CGI script. Modify sipd to support global CGI scripts for all users
Originally, SIP has allowed each user can upload their own script on their profile and then the server will invoke the scripts once the messages come. For building an application level gateway, we need to have a global script at proxy server so that the script will parse the media (audio) IP address and port from the SIP INVITE request and 200 OK response messages, change the IP address and port number in the message before forwarding.

This global script should be create at a default user, where server always look at whever a message coming. The script was written in perl and splited into three parts, depended on what kind of message coming. The link to this SCRIPT file is here

The next step is modifying the CGI script handling in sipd such that it can allow global CGI scripts for all users, instead of having per-user CGI scripts. This was done by creating a Default user, and adding in DoUnique() function at method.c file to check for script of user Default if that is present then execute that instead of checking for per user script. The method.c file is here. The fragment code for doing so as below:

At this point sipd was able to recieve a SIP message and modify the message body (SDP) content before proxying the message.


Milestone 2

Modify the SIP messages to incorporate the application level gateway functions. This includes changing the IP and port in the SIP messages in both directions.

Enhance the previous part such that the CGI script invokes a packet forwarder application to forward RTP/RTCP packets. It was done by extend the global script from part 2 in using system() function to call Forwarder object in Java

The packet forwarder is a simple UDP based application that forwards packets from one port to another. This is done for both RTP and RTCP packets. The input to the application is the local address, the request IP/port and response IP/port to which the packets have to be forwarded. Here is the full implementaion of Forwarder.java

The first thing Forwarder does is opening local file port.table to check the next port available from 10000 (just in case having more than one phone at the same time), writing down the file the pick up ports at local host and create 4 Forward_helper objects to run 4 thread of UD programs. 2 for forwarding RTP and RTCP to the caller and 2 for forwarding RTP and RTCP to the callee.

Forward_helper is a UDB based application extended Thread object. By calling start() method Forwarder.java invoke the thread run at Forward_helper.java. The run() method at Forward_helper.java

At the end of this milestone, the program was able to correctly allow audio communication between an internal node and and external node using a SIP user agent like sipua or sipc. Please click here for viewing screen dump from testing.


Milestone 3

Configure a Linux router (with two interfaces cards) as a NAT box. Allocate private addresses in the range 10.x.x.x. Use the Linux netfilter/iptables modules for NAT and filter functions.

The machine I have supposed to use for doing NAT box is metropolitano at IRT lab. Following are steps that I should do to configure the Linux router as a NAT device:

The above configuring in iptables can also be done with ipchains where eth0 is connected to the internet and eth1 is connected to a private LAN:


Milestone 4

Modify the script to also support firewall functionality

This is similar to the previous part except that we have to also invoke the iptables functions to create holes in the linux firewall. This was done by call iptables command from the script in part 2 by using system() call


Source codes
  • SCRIPT
  • method.c
  • Forwarder.java
  • Forward_helper.java
  • test.html
    References
  • CINEMA, Columbia InterNet Extensible Multimedia Architecture, http://www.cs.columbia.edu/IRT/cinema/
  • SIP, Session Initiation Protocol, http://www.cs.columbia.edu/sip/
  • SIP redirect, proxy and registration server, http://www.cs.columbia.edu/IRT/cinema/doc/sipd.html
  • SIP User Agent, http://www.cs.columbia.edu/~xiaotaow/sipc
  • William R. Cheswick and Steven M. Bellovin, Firewalls and Internet Security, Addison Wesley, 1994
  • Douglas E. Comer and David L. Stevens, Internetworking with TCP/IP, Volume 3
  • Linux Guruz - IPTables/Filrewall, http://www.linuxguruz.org/iptables/
  • Netfilter, http://www.netfilter.org
    Linh Bui, November 17, 2002