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):
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
- Sharing your Internet connection
- man page of ipfw (FreeBSD)
- man page of divert(FreeBSD)
- Project Netfilter
- man page of natd (MacOS X)
- Mac OS X Server 10.2 as a NAT router