I have a project where I have a python script that spawns a modbus tcp "server". Modbus tcp binds normally to port 502. Non-root users cannot bind to ports <=1024 so if I want to run my python script as a non-root user, then I have a couple of options:
1. nc/socat as root. While this is not difficult, it has problems reconnecting when the python scripts restarts. I'd rather not use this
2. use setcap with setcap 'cap_net_bind_service=+ep' /path/to/python but I don't like it, it gives this python interpreter way to much "power", any script would be able to bind to port <= 1024.
3. use iptables to do port forwarding from port 1502 to port 502
I think that the third option is the better option, but I'm having trouble with it. I've looked up in google about it and there are tons of threads in stackoverflow & serverfault but after reading them I'm more confused, because the answers vary wildly.
My network setting:
- I have have an USB-eth (eth1) configured with 192.168.100.1/24
- A tap in0 configured with 192.168.15.1/24 (for virtualbox bridging mode with my VMs)
- I have a DHCP server and a bind server listing on in0 and eth1
Code: Select all
# /etc/conf.d/net
modules="dhcpcd"
config_eth0="dhcp"
dhcpcd_eth0="-t 40 -4" # Timeout after 10 seconds
tuntap_in0="tap"
config_in0="192.168.15.1/24"
config_eth1="192.168.100.1/24"
# /etc/local.d/baselayout1.start
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
iptables --append FORWARD --in-interface in0 -j ACCEPT
I found this https://www.netfilter.org/documentation ... -HOWTO.txt and tried the following command
Code: Select all
iptables -t nat -A PREROUTING -p tcp --dport 502 -j DNAT --to 127.0.0.1:1502
iptables -t nat -L -v shows this:
Code: Select all
Chain PREROUTING (policy ACCEPT 89 packets, 10859 bytes)
pkts bytes target prot opt in out source destination
6 360 DNAT tcp -- any any anywhere anywhere tcp dpt:502 to:127.0.0.1:1502
Code: Select all
echo 1 > /proc/sys/net/ipv4/conf/all/route_localnet
Code: Select all
telnet 127.0.0.1 502
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
Code: Select all
iptables -t nat -A PREROUTING -p tcp --dport 502 -j REDIRECT --to 1502
iptables -t nat -A OUTPUT -p tcp --dport 502 -j REDIRECT --to 1502
I ended up combining these 3 rules
Code: Select all
iptables -t nat -A PREROUTING -p tcp --dport 502 -j DNAT --to 127.0.0.1:1502
iptables -t nat -A PREROUTING -p tcp --dport 502 -j REDIRECT --to 1502
iptables -t nat -A OUTPUT -p tcp --dport 502 -j REDIRECT --to 1502
My question is: is this correct? This seems way more complicated than it should be. Am I just more complicated than it should be?
// edit:
after playing around a bit with the order, I realized that I don't need the REDIRECT rule in the PREROUTING chain, this seems to be more than enough:
Code: Select all
iptables -t nat -A PREROUTING -p tcp --dport 502 -j DNAT --to 127.0.0.1:1502
iptables -t nat -A OUTPUT -p tcp --dport 502 -j REDIRECT --to 1502


