Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Assistance Networking & Security
  • Search

Port forwarding when localhost is involved

Having problems getting connected to the internet or running a server? Wondering about securing your box? Ask here.
Post Reply
Advanced search
6 posts • Page 1 of 1
Author
Message
pablo_supertux
Advocate
Advocate
User avatar
Posts: 2974
Joined: Sun Jan 25, 2004 1:58 pm
Location: Somewhere between reality and Middle-Earth and in Freiburg (Germany)

Port forwarding when localhost is involved

  • Quote

Post by pablo_supertux » Wed Jul 31, 2024 10:01 am

Hi

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
So these are my problems:

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
If I do telnet ip 502 (from a VM I used 192.168.15.1 and from a notebook bound to eth1 I used 192.168.100.1), then telnet show "Trying ip ...." and then it hangs.
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
Looks good, but something does not work correctly. I found this https://serverfault.com/a/1104711/237453 and after executing

Code: Select all

echo 1 > /proc/sys/net/ipv4/conf/all/route_localnet
then my VM and my notebook can connect to port 502. However my localhost cannot connect to itself on port 502:

Code: Select all

telnet 127.0.0.1 502
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
I also found this https://stackoverflow.com/a/28170005/1480131. I removed the PREROUTING rule and tried

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
Now telnet 127.0.0.1 502 works but the VM and the notebook cannot connect to port 502, now they show me "Unable to connect to remote host: Connection refused"

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
and the DNAT rule in the PREROUTING chain must come before the REDIRECT rule, otherwise the VM and my notebook cannot connect.

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
Why do I need the REDIRECT rule in the OUTPUT chain if I want to connect on the localhost on port 502?
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
Top
pietinger
Moderator
Moderator
Posts: 6609
Joined: Tue Oct 17, 2006 5:11 pm
Location: Bavaria

  • Quote

Post by pietinger » Wed Jul 31, 2024 10:17 pm

pablo_supertux wrote:
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
Why do I need the REDIRECT rule in the OUTPUT chain if I want to connect on the localhost on port 502?
Because your modbus tcp "server" is listening on 1502 ... and your first packet coming from telnet saying it wants to connect to port 502; this packet must be "rewritten", so in this packet is the new destination port 1502.

You need two rules because you have two types of incoming packets traversing different parts of the kernel/netfilter:
- From Network
- From localhost

Please see this great picture: https://stuffphilwrites.com/fw-ids-ipta ... 024-05-22/

(here you find more explanations: https://lewestech.com/mirrors/www.iptab ... ables.html )

What happens if you do (without having the redirect rule in OUTPUT) a "telnet 127.0.0.1 1502" ?
https://wiki.gentoo.org/wiki/User:Pietinger --> https://wiki.gentoo.org/wiki/User:Pieti ... _at_Gentoo
Top
pablo_supertux
Advocate
Advocate
User avatar
Posts: 2974
Joined: Sun Jan 25, 2004 1:58 pm
Location: Somewhere between reality and Middle-Earth and in Freiburg (Germany)

  • Quote

Post by pablo_supertux » Fri Aug 02, 2024 9:43 pm

pietinger wrote:
Please see this great picture: https://stuffphilwrites.com/fw-ids-ipta ... 024-05-22/
thanks, I'll take a closer look later


pietinger wrote:
What happens if you do (without having the redirect rule in OUTPUT) a "telnet 127.0.0.1 1502" ?
Without the OUTPUT rule, telnet can connect:

Code: Select all

telnet localhost 1502
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
^]
telnet> Connection closed.

With the 3 rules, telnet connects to either localhost:502 or localhost:1502

// edit: in the graph there are two input sources: "Incoming packet" and "locally generated package". What is the difference?
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
Top
pietinger
Moderator
Moderator
Posts: 6609
Joined: Tue Oct 17, 2006 5:11 pm
Location: Bavaria

  • Quote

Post by pietinger » Fri Aug 02, 2024 10:22 pm

pablo_supertux wrote:// edit: in the graph there are two input sources: "Incoming packet" and "locally generated package". What is the difference?
If you create a packet from a local application it starts at: "locally generated package" (that is obvious) ... then ... THIS is important ... if it arrives at "Outgoing packet" ... this does not mean the kernel is finished here and gives it to the network device ... it means: Now we check WHO is the destination ... AND if the destination is 127.0.0.1 ... THEN ... THIS packet goes INTO "Incoming packet" ... and the show goes on :lol:

So, you have two types of "Incoming packet":

1. Really from network (network adapter/device), OR
2. From the own station

Therefore you have also the two questions: "localhost source?" and "localhost dest?"

The picture would be perfect if there would be a ---------- line from "Outgoing packet" to "Incoming packet" IF FROM localhost TO localhost

And now you see why you must do DNAT in both sections (OUTPUT and PREROUTING; because a local packet will never arrive at DNAT PREROUTING).


(Sorry for my poor english - ask next time in german section :lol: :P )
https://wiki.gentoo.org/wiki/User:Pietinger --> https://wiki.gentoo.org/wiki/User:Pieti ... _at_Gentoo
Top
Hu
Administrator
Administrator
Posts: 24380
Joined: Tue Mar 06, 2007 5:38 am

  • Quote

Post by Hu » Sat Aug 03, 2024 12:30 am

Rather than go through these elaborate games, why not reconfigure the client to expect a port other than 502, so that the Python script can bind to an unprivileged port and the client can connect directly to that unprivileged port?
Top
pablo_supertux
Advocate
Advocate
User avatar
Posts: 2974
Joined: Sun Jan 25, 2004 1:58 pm
Location: Somewhere between reality and Middle-Earth and in Freiburg (Germany)

  • Quote

Post by pablo_supertux » Sun Aug 04, 2024 8:11 pm

@pietinger thaks for the explanation

@hu I have no access to them modbus master and I cannot change/configure it, it expects the slave to listen on port 502 and I didn't want to run my python stack as root (like I've done in the past with other customers).
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
Top
Post Reply

6 posts • Page 1 of 1

Return to “Networking & Security”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy