The simple way of setting up NAT with iptables and Red Hat / CentOS and Scientific Linux

I always feel intimidated with setting NAT. I knew, of course, how to filter packets with iptables, but I always felt that NAT to be just a tad bit confusing. Then I studied for the RHCE exam and it turns out that it is a lot easier than I expected, with a little help from Red Hat’s firewall tool.

With earlier releases of Red Hat, the firewall tool is limited to just filtering by ports with no NAT or ACLs support. With version 6, the tool was significantly revamped. While ACLs are still not supported, you can now setup NAT with the firewall GUI. To get started, log yourself into the X-Windows GUI and run the following from the terminal.

[]{}system-config-firewall

Alternatively, you may run it from the menu -> System- Administration -> firewall. Or if you are logged remotely and you have X-Window running on your workstation, you can forward the tool over SSH to run it locally on your workstation by logging to the server with:

[]{}ssh -X username@hostname

and then run the “system-config-firewall.”

(One notable caution: if you have an existing iptables configuration, running this tool will wipe out your rules. Be sure to back /etc/system/iptables before you proceed further on this.)

From there, you will see the following options available:

NAT 1

Select “Masquerading” and then to your right, select the interface or interfaces you want your traffic to go through.

NAT 2

Congratulations, NAT is now setup! The next step is to setup forwarding to your devices or servers. Select “Port Forwarding” to your left:

NAT 3

Then click on add button at your right:

{stub}

Then near the top of the following screen under the Source heading, click on the interface button, select your interface and click on OK

NAT 4

Then click the protocol button, select your protocol and then click on OK

NAT 5

Then click on the port button and select (or enter) your port(s) and then click on OK:

NAT 6

Now under the Destination heading, select “Forward to another port” and enter the IP address of the machine you will forward the packets to in the field:

NAT 7

Then select the Port button or enter the port(s) you will be forwarding to:

NAT 8

Click on OK, then OK to return to the main screen

From there, click on apply (which will write to the /etc/sysconfig/iptables file) and then reload (which will restart iptables).

(If you have backed up your iptables file, you may be able restore them with the custom rules option. However, the iptable backup must be in the iptables-save format, which presumably means that a custom-made one will not work).

You are mostly done here, but there is a couple of more changes youneed to make. First of all, though, lets login in via the command and take a look at the iptables file:

[root@sl6vmware sysconfig]# cat iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o eth+ -j MASQUERADE
-A PREROUTING -i eth+ -p tcp --dport 20:21 -j DNAT --to-destination 192.168.15.36:20-21
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth+ -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -p icmp -j ACCEPT
-A FORWARD -i lo -j ACCEPT
-A FORWARD -i eth+ -j ACCEPT
-A FORWARD -o eth+ -j ACCEPT
-A FORWARD -i eth+ -m state --state NEW -m tcp -p tcp -d 192.168.15.36 --dport 20:21 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

As you can see there, setting up NAT comprised of a few steps:

1) you set the table type, which at the beginning, would be *nat. If you were to do it from the command line, it would be the first part of the following statement

[]{}iptables -t nat <statement>

2) Then, you would set POSTROUTING s. From the command line, it will the second part of the statement we mention earlier.

[]{}iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE

At that point, the nat is setup.

3) From this point, it is just the matter of forwarding the packets based on source port (you can add the ACLs at this point, but the GUI tool will most likely overwrite them. Again, make sure that you have a backup!) . That is done by setting up a PREROUTING rule for a port, with:

[]{}-A PREROUTING -i eth+ -p tcp –dport 20:21 -j DNAT –to-destination []{}192.168.15.36:20-21

From the command line, it would be:

[]{}iptables -t nat -A PREROUTING -i eth+ -p tcp –dport 20:21 -j DNAT –to-[]{}destination 192.168.15.36:20-21

And then, you would add a FORWARD rule with:

[]{}-A FORWARD -i eth+ -m state –state NEW -m tcp -p tcp -d 192.168.15.36 –[]{}dport 20:21 -j ACCEPT

Which, from the command line would be:

[]{}iptables -t filter -A FORWARD -i eth+ -m state –state NEW -m tcp -p tcp -d []{}192.168.15.36 –dport 20:21 -j ACCEPT

Note that statement must be under the filter table, not under the nat table.

Getting this right via the command-line is fairly tricky even for experienced administrations, which is why the firewall tool is a great way to manage your rules for NAT (assuming that they are simple enough)

But you are not done yet. First, you need to make sure that you actually enable IP forwarding with the kernel. You can set it dynamically with either:

[]{}sysctl -w net.ipv4.conf.all.forwarding =1

Or:

[]{}echo “1” > /proc/sys/net/ipv4/ip_forward

To change it permanently (which is what you want), add or change the net.ipv4.conf.all.forwarding value in /etc/sysctl.conf to:

[]{}net.ipv4.ip_forward = 1

And then reboot (assuming that you didn’t make the change dynamically).

At this point, there is one more thing you may need to do, , particularly if you are running a FTP service.

With FTP, when a client connects to a server, the FTP server returns the response via different port (usually a high-number port above 1024). That becomes a problem when the client attempts to respond to that same port when the server is behind either a firewall or a NAT , as that port will most likely be blocked.

So there are 4 options you choose to address this problem.

1) Use SFTP. It is is encrypted and travels through the same port (22), so that is the best option. However, not all clients would have thats support.

2) Have the FTP server return a response to a specific port and open that port.

3) Have the client use passive mode

4) Modify the nat/firewall dynamically as well as modify the PORT and PASV commands dynamically.

We will go with the last option. Fortunately, it is not complicated in this case. We just need the open the following file:

[]{}/etc/sysconfig/iptables-config

And add (or change) the following:

[]{}IPTABLES_MODULES=“nf_nat_ftp”

This is a helper module that allows us to dynamically set the ports and track the FTP connectivity. It will load once you restart type iptables, either from the gui or from the command line with:

[]{}service iptables restart

If you were to prefer the load the module manual, you would run:

[]{}modprobe nf_nat_ftp

Which will load that module as the other supporting modules. You confirm whether it is loaded by running:

[]{}lsmod | grep ftp

Which will present you with the following output

nf_nat_ftp 3473 0

nf_conntrack_ftp 12879 1 nf_nat_ftp

nf_nat 22788 3 nf_nat_ftp,ipt_MASQUERADE,iptable_nat

nf_conntrack 79611 8 nf_nat_ftp,nf_conntrack_ftp,ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state

Now you are done with NAT. You can start forwarding traffic to your internal servers and have them accessible from outside your network.

For more information on setting up NAT, go to the following links:

http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables - A longer guide to setting up IP tables, with a section for NAT.

http://debianclusters.org/index.php/NAT_with_IPTables - Setting up IP tables with Debian-type distributions.

http://www.ncftp.com/ncftpd/doc/misc/ftp_and_firewalls.html - The problems you will encounter with with NAT and FTP.