0

How can I configure iptables on a DMZ machine to forward port 12345 to another computer attached to the same router? Is iptables the wrong tool for this job?

I have a home server in my router's DMZ, which hosted a service on port 12345. I have moved that service to port 12345 of a more powerful machine in my home network, and have been running ssh -fNR 12345:localhost:12345 <home-server> on every bootup. Service is running a custom protocol - ie, I cannot use an HTTP proxy.

Solutions I've found tend to assume the computer running iptables is the router (two interfaces, etc). (eg: https://serverfault.com/a/140626/15756, https://www.digitalocean.com/community/tutorials/how-to-forward-ports-through-a-linux-gateway-with-iptables, etc)

Commands tried from various tutorials:

  • iptables -A FORWARD -p tcp -d 192.168.1.5 --dport 12345 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
  • iptables -t nat -A PREROUTING -p tcp --dport 12345 -j DNAT --to 192.168.1.5:12345
  • the above also w/iptables -t nat -A POSTROUTING -j MASQUERADE
  • the above above w/iptables -A FORWARD -p tcp -d 192.168.1.5 --dport 12345 -j ACCEPT
1
  • Can you clarify whether the "DMZ machine" is still behind a NAT with a private IP address, or whether its own interface directly has a public IP address? Commented Sep 27, 2018 at 5:21

1 Answer 1

1

In your situation, the "DMZ" setting is actually nothing more than a very broad port-forwarding (DNAT) rule on the router. If you want a single port to be forwarded elsewhere, usually you can simply add a port-forwarding rule to the router as you normally would – and it will take priority over the DMZ rule.

If your router allows this, you should do it on the router. Not only will it reduce load on the current DMZ-machine by simply bypassing it, but you will also avoid the hairpinning problem described below.


What you're trying to achieve on your DMZ-machine is still the same as your router's port-forwarding does (that is, simple DNAT).

But because you only have one interface, the main problem you're having is the same "NAT hairpinning" issue as with accessing port-forwarded services from inside; only it's the other way around. (Your router sends packets to the DMZ machine but receives packets from the other machine and nothing matches up.)

The workaround to this usually requires a SNAT (masquerade) rule in addition, and will result in the destination machine thinking that all connections come from your DMZ-machine (the original source IPs being lost).


The second problem is that it is currently unknown 1) whether your DMZ-machine actually has IP routing (forwarding) even enabled (you should check that), and 2) what firewall rules it already has (you should check that too – you mention adding rules, but you don't mention checking or deleting the old ones).

No matter if it's one interface or two, you're still asking the DMZ-machine to route IP packets, and therefore it should have the net.ipv4.conf.all.forwarding sysctl set to 1.

iptables rules are kept in a list (chain), checked from top to bottom. Using -A adds a rule to the bottom of the specified table/chain. You should always look at your current ruleset (as shown by iptables-save or at least iptables [-t nat] -S) to make sure the rules are in the correct order and so on.

The network is not a black box. You can use packet-capture tools such as Wireshark or tcpdump to see what packets come in and what packets come out. Maybe your DMZ-machine is already correctly forwarding all those packets to the other system – but the replies aren't coming through? That's a different problem with a different solution.

1
  • Per various tutorials, ip forwarding is enabled, it does not currently have any other firewall rules (and I flushed the ones I added after discovering they were ineffective to present a clean slate). I did try a tutorial w/MASQUERADE with the same lack of effects. I'll look more into these, see if I missed anything.
    – Iiridayn
    Commented Sep 27, 2018 at 19:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .