0

I want all TCP and UDP packets destined for the host on port 3389 to be routed to a different address on the network. The host is the computer that hosts these iptables.

Starting with this, doesn't look so bad, although, it would be nice to combine TCP and UDP into one rule:

*nat
-A PREROUTING -i ens1 -d 10.58.0.1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i ens1 -d 10.58.0.1 -p udp -m udp --dport 3389 -j DNAT --to-destination 172.20.0.201
COMMIT

But, there are about 5 interfaces that need to be allowed to do this and several others that do not. Ok, so, lets get to work:

*nat
-A PREROUTING -i ens1 -d 10.58.0.1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i ens1 -d 10.58.0.1 -p udp -m udp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun0 -d 10.58.0.1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun0 -d 10.58.0.1 -p udp -m udp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun1 -d 10.58.0.1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun1 -d 10.58.0.1 -p udp -m udp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun2 -d 10.58.0.1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun2 -d 10.58.0.1 -p udp -m udp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun3 -d 10.58.0.1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -i tun3 -d 10.58.0.1 -p udp -m udp --dport 3389 -j DNAT --to-destination 172.20.0.201
COMMIT

Oh, but wait, the host has 6 different possible IP addresses, so now I have to repeat that block of rules 6 times with different destinations that all actually refer to the same host. That will take a total of 60 brittle entries. There must be a better way.

Question: How can I refer to the host universally? instead of saying:

-d <ip address>

... and repeating that line countless times, I would much rather say:

-d <catch-all for anything destined to this computer>

In my mind, it makes more sense to apply this DNAT rule to the INPUT chain but for reasons that are way beyond my comprehension, the INPUT chain seems to only accept SNAT rules. So, unless someone knows better, I am stuck in NAT PREROUTING.

Thanks and Regards

2 Answers2

0

If you don't need to restrict the traffic by incoming interface name, then you can use

-A PREROUTING -d 10.58.0.1 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 172.20.0.201
-A PREROUTING -d 10.58.0.1 -p udp -m udp --dport 3389 -j DNAT --to-destination 172.20.0.201

Then combining this with the ipset feature, you have only two lines. iptables multiple source IPs has information on the ipset feature.

Tero Kilkanen
  • 34,499
  • 3
  • 38
  • 58
  • This is the first time I have encountered ipset and this is certainly useful. However, the main point of this issue is the need to restrict by incoming interface. For this reason, it would be ideal to be able to do DNAT rules on the INPUT chain which is perfectly logical in my mind, but evidently the INPUT chain only allows you to do SNAT routing which (in my mind) makes no sense. Otherwise, it seems necessary to build complex PREROUTING rules with potentially a hundred entries to sort this out. Basically, anything destined to the INPUT chain for a certain port needs to be re-rerouted. – Vic Morrowshead Apr 05 '18 at 11:45
0

It looks like there is a way to refer to all things local that I did not know about until I accidentally came across it somewhere else.

-A PREROUTING -m addrtype --dst-type LOCAL -j DEST-LOCAL

The rule above will redirect everything that is apparently destined for the INPUT chain which is exactly what I was looking for. Those packets can now be redirected elsewhere based on the new chain they are being sent to. Essentially, in that DEST-LOCAL chain, only packets coming from interfaces that are permitted will be accepted.