Thursday, 17 December 2015

How to setup port forwarding with iptables / Netfilter (properly)

The first command tells the host that it is allowed to forward IPv4 packets (effectively turning it into a network router):
echo "1" > /proc/sys/net/ipv4/conf/ppp0/forwarding
echo "1" > /proc/sys/net/ipv4/conf/eth0/forwarding
or better yet ensure that the ip forwarding persists after reboot:
sudo vi /etc/sysctl.conf
and add / amend:
net.ipv4.ip_forward = 1
and to apply changes we should run:
sudo sysctl -p
Simple port forwarding: This is often applied when you have a service running on the local machine that uses an obscure port - for example Tomcat on tcp/8080 - you  might want to provide external access to the service from port 80 - so we would do something like:
sudo iptables -t filter -I INPUT 1 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
OR (to be more restrictive)
sudo iptables -t filter -I INPUT 1 -i eth0 -s 8.9.10.11/24 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
and then:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
The first command permits inbound traffic on our 'eth0' interface to tcp/80.

The second command instructs traffic bound for tcp/80 to be redirected (effectively DNAT'ing it) to port tcp/8080.

Advanced port forwarding: Sometimes you might have the need to forward traffic on a local port to an external port of another machine (note: 'REDIRECT' will not work in the scenerio - it only works locally) - this could be achieved as follows:
sudo iptables -t filter -I INPUT 1 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
OR (to be more restrictive)
sudo iptables -t filter -I INPUT 1 -i eth0 -s 8.9.10.11/24 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
and then:
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.11.12.13:8080
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
The first command again permits inbound traffic on 'eth0' to tcp/80.

The second command performs a DNAT on traffic hitting port 80 to 10.11.12.13 on tcp/8080.

* The masquerade action is used so that traffic can be passed back from the destination host to the requesting host - otherwise the traffic will be dropped. *

you can also use SNAT do achieve the same thing:
iptables -t nat -A POSTROUTING -d 66.77.88.99 -s 11.12.13.14 -o eth0 -j SNAT --to-source 192.168.0.100
(where 192.168.0.100 is the interface you wish to NAT the traffic to, 11.12.13.14 is the requesting client and 66.77.88.99 is the destination address that should match for SNAT to be performed - which is the remote server in our case.)

If you have a default drop-all rule in your forward chain you should also include something like:
sudo iptables -t filter -A FORWARD -i eth0 -s <destination-ip> -d <client-ip> -p tcp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t filter -A FORWARD -i eth0 -s <client-ip> -d <destination-ip> -p tcp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
Client IP = The IP address (or subnet) from which want to use the port forwarding.
Destination IP = The end IP address you wish the client to hit after the port redirection process.

The first command permits the firewall to forward traffic from the destination ip (our Tomcat server) to the requesting client.

The second command permits the firewall to forward traffic from the client ip to the destination server.

Sometimes (although I strongly discourage it personally) you might want to put a blanket rule in to allow everything to be forwarded between interfaces on the host - this can be achieved with something like:
sudo iptables -t filter -A FORWARD -j ACCEPT
Finally to ensure they persist after a restart of the system we can use:
iptables-save > /etc/sysconfig/iptables

0 comments:

Post a Comment