This article describles how to setup a portforwarding using iptables.
In this case we want to make the webserver on a virtual machine accessable from the internet. Since you normally have only one or a few public ip addresses we are using a techinque called Network Adress Translation.
We define how a client will have to talk to us in order for his packets get forwarded. The tool used for this task in linux is iptables.
Iptables is checking recieved IP packets and decides, based on complex rules, what should happen to them.
Before we can start working on this we have to allow the kernel to forward IP packets. To do this we open the file /etc/sysctl.conf
and change the following value from 0 to 1:
net.ipv4.ip_forward = 1
Afterwards we restart the service so the changes take place.
sudo service networking restart
2) Setup NAT
As of the TCP/OP standard every computer has 65535 ports we can address. The first 1024 are IANA maintained by the IANA and should not be used for NAT.
The standard ports for webservers are 80 (http) und 443 (https).
We decide on what port a requesting client should contact for his packets to be forwarded to the virtual webserver. In this example we use 2080 for http and 20443 for https.
Now we know the following facts about an incomming IP packet:
Also we know that the packet needs to be forwarded to:
In iptables the set of rules a packet will be handled by is called “table”. The table used by us is called “nat” and is made up of three parts:
We now wirte a rule for the table „nat“ that handels a packet if it:
If these creterias match iptables should:
In the syntax of iptables the command is looking like this:
sudo iptables -t nat -I PREROUTING -p tcp -d 213.73.97.133 --dport 20443 -j DNAT --to-destination 192.168.122.178:443
Since the source IP address remains intact we do not have to change anything on the route back.
The same rule for port 2080 to port 80:
sudo iptables -t nat -I PREROUTING -p tcp -d 213.73.97.133 --dport 2080 -j DNAT --to-destination 192.168.122.178:80
Lets take another look at the rule.
sudo iptables -L -t nat --line-numbers
3) Firewall configuration
First: Firewallrules get processed one after another. Second: If a rule triggers the traffic will be ALLOWED or DENIED
Depending on the firewall there are different philosophies on how Firewall rules work:
In iptables firewallrues are handeled in chains. Depending on what kind of traffic we are looking at different chains apply.
Since we are natting (forwarding) traffic, the Chain is called FORWARD.
As already mentioned iptables will drop all packets that are not handeled by a rule. A easy way to think of it is to immagine an invisible “deny any:any” rule beneath all other rules.
This means we have to configure a firewall rule that expicitly allows packets recieved on the inbound interface (in this case enp2s0) to be forwarded to the network 192.168.122.0/24.
To ensure that the traffic will not be blocked by a following rule we jump to the chain ACCEPT using the paramenter -j if the rule is triggered.
sudo iptables -i enp2s0 -I FORWARD -m state -d 192.168.122.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
Lets take a look final look at it.
sudo iptables -L FORWARD -v --line-numbers
Cheers, Ori
Thanks a lot to Fl@ und beegeees, who helped me alot wrapping my mind around this.