$30
Introduction
In this assignment, you will implement a NAT application using the software library NFQUEUE. The NAT application can forward UDP traffic.
1 Setup
1.1 Topology
Inbound --> | <-- Outbound
packets
| packets
--------
| ---------
Dept |
| | VM A | <----- VM B / VM C
network|
| | (NAT) | UDP
--------
| ---------
Figure 1: Setup of the architecture.
Figure 1 shows the setup of this assignment. VM A has a network card configured with a public IP address (i.e., Apublic), and it will serve as the NAT gateway.
By properly configuring the route tables of VM B and VM C, VM A can relay any inbound/outbound traffic for VM B and VM C. Let Ain be the internal IP address of VM A. Then we execute the following command in both VM B and VM C to add the default gateway:
sudo route add default gw Ain
Note that you are NOT allowed to use any built-in NAT services, including the nat table in iptables.
Otherwise, you will get zero marks.
1.2 Assumptions and Restrictions
We make the following assumptions and restrictions.
You only need to relay UDP traffic. Other protocols (e.g., TCP and ICMP) can be ignored. We won’t generate any traffic aside UDP in our demo. To play safe, you can drop any unexpected packet.
All new flows are initiated from the internal network.
You only need to relay outbound traffic to one of the reachable workstations in the department.
The reachable workstations include: linux5 - linux16.
IP="10.3.1.54" # public interface
LAN="10.0.54.0" # private LAN network address (without subnet mask)
MASK="24" # subnet mask
echo "1" > /proc/sys/net/ipv4/ip_forward iptables -t nat -F iptables -t filter -F iptables -t mangle -F iptables -t filter -A FORWARD -j NFQUEUE --queue-num 0 -p udp -s ${LAN}/${MASK} \
! -d ${IP} --dport 10000:12000 iptables -t mangle -A PREROUTING -j NFQUEUE --queue-num 0 -p udp -d ${IP} \
--dport 10000:12000
Table 1: iptables configuration.
For each reachable workstation, you can only host a server on port 10000 - 12000 (inclusive) using UDP sockets.
The translated source port at VM A must also be in the range 10000 - 12000 (inclusive). We assume that no other processes are using the port 10000 - 12000 while the NAT program is running.
The NAT program maintains a translation table that keeps track of all NAT mappings of UDP. For each translation, the NAT program should always choose the smallest, available port number among all flows.
We will provide you the implementation of computing the checksums (for details, please refer to tutorials).
1.3 iptables
In VM A, you need to configure iptables to use NFQUEUE. Table 1 shows the rules to be used.
The first three iptables commands clear all the existing rules. The 4th and 5th iptables commands redirect outbound and inbound UDP traffic, respectively.
The above script takes three inputs: (i) $IP is the IP address of public interface of VM A (i.e., Apublic in Figure 1); (ii) $LAN is the network address of the private network (without the subnet mask); and (iii) $MASK is the subnet mask value. You must update the inputs for your own network.
2 UDP Translation
In UDP translation, the NAT program processes UDP packets as follows.
For each outbound packet,The NAT program searches if the source IP-port pair of the packet has already been stored in the translation table.
If yes, the NAT program uses the previously assigned port number for the outbound packet.
If not, then the NAT program creates a new entry in the translation table. The entry shouldcontain:the source IP-port pair;
the newly assigned port number (between 10000 and 12000)
the timestamp that the new entry is created.
Finally, the NAT program translates the source IP address and the source port number of thepacket, modifies the affected IP and UDP headers of the packet accordingly, and forwards the packet.
For each inbound packet,The NAT program searches if the destination port of the inbound packet matches any one ofthe entries in the translation table.
If yes, the NAT program translates its destination IP address and port number, modifies theIP and UDP headers of the packet accordingly, and sends the packet to the target VM.
If not, the NAT program should drop the packet.
Translation expiry requirement. For each entry, it should be valid for 10 seconds from the time since it is last accessed. In other words, if there is an inbound or outbound packet that matches the target entry, we restart the timer again. If no packet matches the target entry over the 10-second window, the entry should be removed.
Here, we use a lazy approach to remove expired entries. Instead of maintaining a timer, we trigger the expiry process only when the NAT program receives a packet. When the NAT program receives a packet, it first checks and removes any entry that has not been accessed in the last 10 seconds, followed by performing translation on the packet. Some entries may have been idle for a while (e.g., 60 seconds), but it is fine to remove them later because they have no impact on the translation until a packet is processed. Note: Laziness is bad for study, but it’s a very useful technique in systems research for performance improvements without hurting the correctness.
ICMP error translation. If an outbound UDP packet sends to an closed UDP port, the destination may reply an ICMP port unreachable error. You don’t need to worry about this case.
To enable us to check the content of the NAT table, you should display all NAT mappings on the screen whenever there is an update in the NAT table (e.g., a new entry is added or an existing entry is deleted). Each displayed mapping should show the four fields: original source address, original source port, translated source address, and translated source port. You are free to define the display format. Also, make sure to remove other debugging messages from your submission for us to check the NAT table.
3 Traffic Shaping
We use token bucket to control the transmission rate.
Token bucket. The token bucket holds a fixed number of logical tokens (bucket size). Tokens are generated and placed into the token bucket at a constant rate (fill rate), whose unit is the number of tokens generated per second (n/s). When the token bucket becomes full, subsequently generated tokens are discarded. So there are two parameters to configure a token bucket: bucket size and fill rate. The number of tokens in a bucket is initialized as the bucket size. When a packet arrives, transmit it if there is a token. Otherwise, wait until getting an available token. It consumes a token to transmit a packet.
The NAT program leverages multi-threading, which has at least two threads:A thread for receiving packets. It receives packet from the queue we specified (i.e., queue 0 as shown in Table 1) and then handles it, which triggers the callback function. In the callback function, your program requires to check whether there is available buffer in user space. If yes, buffer the packet in user space; if not, drop the packet. Here we define the maximum number of packets in buffer as 10.
A thread for processing packets. It conducts TCP translation for each buffered packet andsets verdict accordingly. Every transmission requires to get an available token from the token bucket.
4 Deliverables
Here are some possible testcases:
Connections using “nc -u”, meaning that UDP traffic is used;
Connections using “nc -u -p xxx”, meaning that the source port is set to “xxx”;
DNS lookup;
Parallel sessions;
Correctly displaying NAT mappings.