IPTables – How to Configure SNAT for Just Two Ports

iptablesnat;

I want to set up some NAT policies so that certain machines will only have outbound access to http/https. They should not be able to do port scans or anything else from their machine.

Currently my NAT rules are:

-A PREROUTING -d 1.2.3.4 -j DNAT --to-destination 10.10.1.10
-A POSTROUTING -s 10.10.1.10 -j SNAT --to-source 1.2.3.4

And I have this shared rule:

-A POSTROUTING -o eth0 -j MASQUERADE

1.2.3.4 is a public IP, and 10.10.1.10 is an internal IP.

This allows all inbound and outbound access to NAT directly through.

I tried the following POSTROUTING rule instead of the one above:

-A POSTROUTING -s 10.10.1.10 -p tcp --dport 80 -j SNAT --to-source 1.2.3.4:80

However, that didn't seem to work. After adding that rule I could still use RDP from the workstation.

To recap, my goal is to allow certain workstations to only have http/https access to the Internet. All other outbound traffic should be blocked. All traffic should be allowed. I want all other workstations in the network to use the existing NAT policy to allow all outbound traffic to be NAT'ed.

Update
Based on @Zoredache's reply, I now have the following Postrouting rules.

-A POSTROUTING -s 10.10.1.10/32 -p tcp -m tcp --dport 80 -j SNAT --to-source 1.2.3.4:80
-A POSTROUTING -s 10.10.1.10/32 -p tcp -m tcp --dport 443 -j SNAT --to-source 1.2.3.4:443
-A POSTROUTING -s 10.10.1.10/32 -p tcp -m tcp --dport 53 -j SNAT --to-source 1.2.3.4:53
-A POSTROUTING -s 10.10.1.10/32 -p tcp -m udp --dport 53 -j SNAT --to-source 1.2.3.4:53
-A POSTROUTING -s 10.10.1.10/32 -j ACCEPT
-A POSTROUTING -o eth0 -j MASQUERADE

They don't quite work yet but they are getting close. More in my reply to @Zoredache below.

Best Answer

The key to iptables is the first match wins.

Assuming the client machine is 10.10.1.10 then you just have to look at these rules in order. If the first rule doesn't match it is going to pass down MASQ rule which it will match.

-A POSTROUTING -s 10.10.1.10 -p tcp --dport 80 -j SNAT --to-source 1.2.3.4:80
-A POSTROUTING -o eth0 -j MASQUERADE

If you were to add another rule before the final MASQUERADE rule should result in the NAT not happening. Since the packets from 10.10.1.10 will that are not destined to tcp/80 or tcp/443 will match the ACCEPT rule, meaning that they will not be translated by the SNAT/MASQ rules.

-A POSTROUTING -s 10.10.1.10 -p tcp --dport 80 -j SNAT --to-source 1.2.3.4:80
-A POSTROUTING -s 10.10.1.10 -p tcp --dport 443-j SNAT --to-source 1.2.3.4:443
-A POSTROUTING -s 10.10.1.10 -j ACCEPT
-A POSTROUTING -o eth0 -j MASQUERADE
Related Topic