Saturday, December 20, 2008

Some notes about using de MacOS X NAT (Network address traslation),

This evening I have to us the NAT (network address traslation) infrestructres that came with MacOS X. The TCP/IP stack of MacOS X and the network utilities came from FreeBSD. The firewall is ipfw and is actived by default. The command line utility that controlles the firewall is ipfw. Unlike Linux, the nat engine is in user space, implemented in a proccess called natd. There are ipfw rules that select the ip packets and send to natd using the divert mechanism


Sharing your Internet connection


The easy way to share your internet connection is to use the Internet. We excecute de System Preferences application, next click in Sharing and the system show the next configuration pane (in spanish):


internet sharing


Now, we must select the public interface (the one is connected to Internet), in this example the airport and we also must select the private interface (where are the computers you want to access Internet throught NAT). Now, we push the Init button and the NAT is active.


We can see in changes that the GUI have done in the system now. We launch the Terminal Application and execute the ipfw show command. We can see the first rule that divert all traffic to the natd process:




00010  26221  16201955 divert 8668 ip from any to any via en1
02000 264607  23464758 allow ip from any to any via lo*
02010      0         0 deny ip from 127.0.0.0/8 to any in
02020      0         0 deny ip from any to 127.0.0.0/8 in
02030      0         0 deny ip from 224.0.0.0/3 to any in
02040      0         0 deny tcp from any to 224.0.0.0/3 in
02050 209103  38244907 allow tcp from any to any out
02060 333894 376385236 allow tcp from any to any established
02065      0         0 allow tcp from any to any frag
12190      3       192 deny tcp from any to any
65535   7662    912661 allow ip from any to any



We can also check that the natd is executing in the system:




ibookdrizzt:~ terron$ ps aux|grep natd
root       372   0.0  0.0    27332    580  ??  Ss   12:14AM   0:00.43 /usr/sbin/natd -alias_address 192.168.1.33 -interface en1
ibookdrizzt:~ terron$ 



That natd is done when the packet leave the machine throught the public interface. The return flow of packets, when arrive to the machine providing, are diverted to the natd process. If there is an entry in the translation table, the destination address is rewritten in accordance with the contents of the table.

Setting manual NAT


We want to configure the NAT in the next scenario:




We have a PowerMac G5 connected to a wireless network where there is a wifi router connectd to Internet.The wireless network uses the address range 192.168.1.0/24 and the PowerMac uses the IP address 192.168.1.100 (interface en1, Airport). Also, the PowerMac is connected an ethernet network and uses the IP address 192.168.2.1 (interface en0). We want that the PowerMac uses NAT to translate all the IP address in the 192.168.2.0/24 rango to a IP in the range 192.168.1.x, if possible the same IP assignated to the interface en1.


The NAT is done in MacOS X just before the packet leave the network interface. In the previus scheme, the packets go yo Internet via the interface en1. We must configure natd to intercept packets before leave the interface and traslate the source address and source port in case we need it. We must intercept any packet whose source address is in network 192.168.2.0/24 to any address. We add a rule to the ipfw firewall that select all packet from network 192,.168.2.0/24. In the Terminal application:




ipfw -f flush

ipfw add divert natd all from 192.168.2.0/24 to any via en1



Warning, the first command, delete all the firewall rules. If we want to keep the current ruleset, we must to insert the rule in the firewall and not use the ipfw -f flush command. We can see the actual rule set using the ipfw show command.


Now, we must run the natd command. This program traslate the source address and port from the packet being natted. The address traslated is called alias and usually is the same of the public interface. We also must use the -v parameter to natd if we want to debug the process because it automatically go to background. In theory, the next command will do the work:



/usr/sbin/natd -v -interface en1



But if we test the configuration, it doesn't work, why?. Because this configuration traslate adequately the packets the leave the machine, but the packets that came back from Internet no.This occurs because the implementation of NAT is a user program, and you must configure the firewall, ipfw, to send the packets back to the process natd. However, in Linux, this is done automatically because it maintains the translation tables in the kernel. In this sceneario the solution is easy, because we can use another alias address and another divert rule to send the traffic:


ifconfig en1 192.168.1.101 alias

ipfw -f flush

ipfw add divert natd all from 192.168.2.0/24 to any via en1

ipfw add divert natd all from any to 192.168.1.101 via en1

natd -a 192.168.1.101



Problems


The implementation of NAT using MacOS X isn't very efficient. The need to move packages from the kernel to user mode programs and then again to move to the kernel for transmission makes it slower to complete implementations in the Linux kernel and its NetFilter.


The support of inspection protocols is very limited, only supports FTP and IRC, with the rest of protocols that send information with embebbed ip addresses and ports not supported.

References




Technorati Tags: , ,