I would like to try port forwarding with iptables.
I want to try it at hand, so the configuration is a little special, but it is as follows.
--There are smartphones and laptops in the LAN (192.168.0.0/24). --Set up a web server on your laptop and let it listen on port 4000. --The router in the LAN is omitted for the sake of simplicity.
What I want to achieve is when I access my laptop (192.168.0.9) from my smartphone browser It is to make the server on port 4000 respond.
TODO
Identify the TODO while reviewing the packet flow in the figure below. Reference: Iptables Tutorial 1.2.2 Chapter 6.1
The GET request packet of the smartphone browser has a Destination IP of 192.168.0.9 and a Destination Port of 80, and flows from "NETWORK" in the figure. The server is the "Local Process" in the figure.
Therefore, the request packet can reach the server by doing the following:
The initial state is as follows.
iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Use the whitelist method.
iptables -P INPUT DROP
iptables -P FORWARD DROP
The order of TODO is reversed, but first make the server accessible with the browser of the laptop.
iptables -A INPUT -d 127.0.0.1 -p tcp --dport 4000 -j ACCEPT
iptables -A INPUT -s 127.0.0.1 -p tcp --sport 4000 -j ACCEPT
It's confusing because it's local, but the settings and packets correspond as follows:
iptables -A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 4000 -j ACCEPT
The above allows packets from the browser to the server
iptables -A INPUT -s 127.0.0.1/32 -p tcp -m tcp --sport 4000 -j ACCEPT
The above allows packets from the server to the browser
NAPT (Network Address Port Translation) the destination of the request from the smartphone (192.168.0.2).
iptables -t nat -A PREROUTING -s 192.168.0.2 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:4000
To access from other than the smartphone in the LAN, do as follows.
iptables -t nat -A PREROUTING ! -s 192.168.0.9 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:4000
The destination IP and destination port are rewritten by using the DNAT target. 。 。 。 。 。 It seems to work above, but it didn't work.
It seems that it does not connect to localhost from the outside by default. Perhaps localhost should be isolated from the outside world.
This time it is for verification at hand, so change the setting.
sysctl -w net.ipv4.conf.eth0.route_localnet=1
You can now access it!
Did you have the question, "Isn't it necessary to SNAT the response packet from the server?" I had it. No conclusion is needed. For DNAT and SNAT, if one-way conversion is defined, the opposite direction will be performed automatically.
The final settings are as follows.
root@X1-Carbon-6th:~# iptables-save
Generated by iptables-save v1.6.1 on Sat Dec 28 14:15:30 2019
*nat
:PREROUTING ACCEPT [167:28771]
:INPUT ACCEPT [10:624]
:OUTPUT ACCEPT [314:29752]
:POSTROUTING ACCEPT [314:29752]
-A PREROUTING -s 192.168.0.2/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:4000
COMMIT
Completed on Sat Dec 28 14:15:30 2019
Generated by iptables-save v1.6.1 on Sat Dec 28 14:15:30 2019
*filter
:INPUT DROP [3377:278628]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [3560:414379]
-A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 4000 -j ACCEPT
-A INPUT -s 127.0.0.1/32 -p tcp -m tcp --sport 4000 -j ACCEPT
COMMIT
Completed on Sat Dec 28 14:15:30 2019
root@X1-Carbon-6th:~# sysctl -n net.ipv4.conf.enx7cc3a186ea62.route_localnet
1
Please be careful about the following when cleaning up.
--Erase the rule with the -F option for each table, and restore the policy --Returning this specially supported setting with sysctl
iptables -F && iptables -F -t nat
iptables -P INPUT ACCEPT && iptables -P FORWARD ACCEPT
sysctl -w net.ipv4.conf.enx7cc3a186ea62.route_localnet=0
I tried port forwarding in my environment. I confirmed that the packet flow diagram is very good and that it can be set sufficiently if you think about it while looking at it.
** "Like" Thank you. **: wink: