When network people talk about outbound connectivity, they mean a condition that private nodes can communicate (i.e. send and receive packets) with public nodes when they initiate the communication. This means that if a private node sends initial TCP SYN or UDP data packet(s) to a public node, it can send subsequent packets and also receive reply packets from the public node.
This website explains how we enable outbound connectivity using Linux iptables. To enable outbound connections, we need to set NAT to assign public IP:port to packets from private nodes and translate private IP:port into the public IP:port. Also reply packets from public nodes must be translated back to the original private IP:port. All of these can be done by using what is called "source NAT" or "masquerading" and we just need to run one iptables command. However, things may be not that simple because your network configuration may be not quite ready for this. Here, I am explaining various things that are necessary for outbound connectivity:
For NAT to be able to translate packet addresses, those packets must pass through the NAT. Obvious, right? Therefore, you have to make every machine inside a private network talk with outside machines through their NAT. This can be done by changing the routing table at private nodes. Easiest way is to set the default router as the NAT. The most popular way on Redhat is to have an entry in "/etc/sysconfig/network" file such as "GATEWAY=ip.addr.of.NAT". Another way is to run "/sbin/route" command in a network startup script.
A headnode must have at least two (Ethernet) interfaces up and running: one at the public side with a public IP address and the other at the private side with private IP address. If I run "/sbin/ifconfig -a" on my headnode, I get the following lines. You should get something similar to mine:
eth0 Link encap:Ethernet HWaddr 00:A0:CC:50:E5:3C inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:4561356 errors:0 dropped:0 overruns:0 frame:0 TX packets:4721689 errors:2 dropped:0 overruns:0 carrier:2 collisions:416051 txqueuelen:100 Interrupt:11 Base address:0xfc00 eth1 Link encap:Ethernet HWaddr 00:60:B0:5D:3C:0E inet addr:128.105.144.36 Bcast:128.105.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:7337489 errors:0 dropped:0 overruns:0 frame:0 TX packets:1737311 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 Interrupt:11 Base address:0xf8e0 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:6972 errors:0 dropped:0 overruns:0 frame:0 TX packets:6972 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0
The output above tells that my computer has two interfaces: one ("eth0") with private IP address "192.168.0.1" assigned and up and running, and the other ("eth1") with public IP address "128.105.144.36" and also up and running. The last 6 lines which starts with "lo Link ..." give information of local interface and you will get similar lines.
To bring interfaces up and running, you can use "/sbin/ifconfig" command. Running this command in a network startup script ("/etc/sysconfig/network-scripts/ifcfg-ifname", where "ifname" is the name of interface such as eth0 or eth1 in the above example) is a good idea.
Checking whether iptables is enabled or not can be done by running "/sbin/iptables -t nat -L". (Note: you should have the root privilige to run iptables commands.) If you get something (but not errors) from running the command, your system has iptables enabled. You may skip to the next section. FYI, the following lines are valid output, which basically say that no rule has been added to the kernel table
Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
However, if your machine has ipchains enabled instead of iptables (Redhat 7.1 is normally shipped with this option), you will get error messages something similar:
/lib/modules/2.4.2-2smp/kernel/net/ipv4/netfilter/ip_tables.o: init_module: Device or resource busy Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters /lib/modules/2.4.2-2smp/kernel/net/ipv4/netfilter/ip_tables.o: insmod /lib/modules/2.4.2-2smp/kernel/net/ipv4/netfilter/ip_tables.o failed /lib/modules/2.4.2-2smp/kernel/net/ipv4/netfilter/ip_tables.o: insmod ip_tables failed iptables v1.2.1a: can't initialize iptables table `nat': iptables who? (do you need to insmod?) Perhaps iptables or your kernel needs to be upgraded
In this case you have to disable ipchains and enable iptables. To be sure that the reason iptables not working is ipchains being enabled, run "/sbin/lsmod" and check if the module "ipchains.o" is installed. If you can't find the line with "ipchains.o" from running the command, you need to contact your system admin. Otherwise ipchains can be disabled by running "/sbin/chkconfig --level=2345 ipchains off" and rebooting the head node.
To make machines inside private network be able to talk to public and/or vice versa, you have to make your headnode act as a router, i.e. it should be able to route or forward packets from private network to public and vice versa.
In most Berkeley based systems, including Linux 2.4, you can check whether a machine is acting as a router by looking at the content of "/proc/sys/net/ipv4/ip_forward" This file is supposed to have a single character which is "0" or "1", and if it has "0", you need to enable "ip forwarding" by adding the line at "/etc/rc.d/rc.local":
/bin/echo "1" > /proc/sys/net/ipv4/ip_forward
and then running:
/etc/rc.d/rc.local
In addition to making your headnode route packets, you need to configure it to route packets to the correct machines by setting its routing table. If you can talk to both public and private nodes from your headnode, the routing table of the headnode must be good enough for correct packet forwarding. However, it is a good idea to check the routing table using "route" or "netstat -r" command. If the routing is not correct, you must change the routing table. The best way, not always but at least in this context, to setup the routing table is to statically change routing rules and make the change permanent by editing "/etc/sysconfig/static-routes" file. Below is an example of the file.
eth0 net 129.89.200.0 netmask 255.255.254.0 gw * eth1 net 129.89.57.0 netmask 255.255.255.0 gw * eth1 net default netmask 0.0.0.0 gw 129.89.57.1
The example file is for the system with two ethernet cards, eth0 and eth1. The interpretation of each line is as follow:
After editing "/etc/sysconfig/static-routes" appropriately, you have to run the following command to make the change take effect:
/etc/rc.d/init.d/network restart
You also need to run "/sbin/route -a" command to check the routing table has been setup correctly.
The last step of headnode configuration is enabling outbound connections. Now you need to use iptables commands. You can enable outbound connections either by source NAT or masquerading. Here, I just explain the former way.
Add the following line to any startup script, "/etc/rc.d/init.d/network" for example, and run the script:
/sbin/iptables -t nat -A POSTROUTING -o eth-pub -j SNAT --to pub-ip
In the command, "eth-pub" is the interface name (such as "eth0" or "eth1" that your headnode has at the public side. "pub-ip" is the (public) IP address assigned to "eth-pub". For those of you who are curious what the rule says, it basically says that "translate source addresses into pub-ip after routing decision is made and for packet that are going to be sent via eth-pub".
If you can ping from private machine to any public machine, you are all set in terms of private network setup. One warning is that some machines are set as not responding to ping request. So the fact that you can't ping to a public machine does not necessarily mean that your network has been setup in a wrong way.