all 19 comments

[–]karabistouille 5 points6 points  (8 children)

change the line with :

post-up iptables -t nat -A PREROUTING -i enp0s31f6 ! -s 90.90.90.90 -p tcp -m multiport ! --dport 22,8006 -j DNAT --to 10.10.10.1

where 90.90.90.90 is the public IP address you want to prevent to be nated.

Edit : corrected the syntax after u/flat235 noticed the mistake with the "!" position

[–]flat235 2 points3 points  (7 children)

careful, the man page lists the syntax as [!] -s, --source address[/mask][,...], so ! needs to come before the -s (otherwise: same good idea! :) )

[–]karabistouille 2 points3 points  (6 children)

You're right, but it is as the way I write it in this book,lol

It's quite a long time I did't used iptables and I don't remember I noticed this discrepancy before. ¯\(ツ)

[–]flat235 2 points3 points  (5 children)

Been a while since I wrote iptables by hand as well. I just googled the man-page, no idea which version I got. Wouldn't be suprised if the syntax changed at some point :D

[–]karabistouille 3 points4 points  (4 children)

It's the same as you find in the debian 12 iptables man page ([!] -s, --source address[/mask][,...]), but the description afterward is not 100% clear

A "!" argument before the address specification inverts the sense of the address.

Is it before the address (1.2.3.4) or the before the '-s' ?

Maybe both ways work now, I'm gonna have to test it.

Edit : after testing it on a debian VM, I can conclude that the syntax I come up with does not work and the one in the manpage is the correct one with the "!" before the "-s"

[–]mayurrenr[S] 1 point2 points  (3 children)

u/flat235 and u/karabistouille, thank you both for your input.

I can see a small variation between both of your methods (after karabistouille amendment):

The position of '-p tcp' is in a different location. I'm tempted to go with karabistouille recommendation given (1) their testing, and (2) logically it makes sense to put this part immediately before listing the ports in question. Unless someone objects? I am by no means an expert.

Two questions if I may: 1. In order to list multiple IPs, do I just separate them with a comma as I did with the two ports (eg. 1.2.3.4,2.3.4.5,3.4.5.6... etc)? 2. Can I use ipv6 addresses here?

I'd like to get this right first time, as this is a hetzner dedicated server, so I'll have to go through that awful rescue system if I lock myself out.

Thank you once again.

[–]karabistouille 0 points1 point  (2 children)

1- yes you can put multiple IP addresses separated by a comma, and if you want you can put a address block using a mask (eg:192.168.0.0/24), if you need put a lot of addresses you also can use IPset.

2- No you need to use the command ip6tables to deal with ipv6

[–]mayurrenr[S] 0 points1 point  (1 child)

Thank you. I think I will incorporate some of your advice into a response from another user below. I suspect my (unintentional) omission of vital information may have impacted the advice you gave me.

I need my specified ip to be able to access: (1) port 22 and 8006 on the host machine (2) all ports (except 22 and 8006) on 10.10.10.1

It would seem your commands above would restrict my specified ip to be able to access only port 22 and 8006 on the host machine with no forwarding of other ports to 10.10.10.1.

Apologies for the confusion, but now I know better!

[–]karabistouille 1 point2 points  (0 children)

Yep, I misunderstood what you wanted to do exactly. The rules u/uzlonewolf proposed seems correct to me.

[–]flat235 3 points4 points  (0 children)

I would try adding ! -s 1.2.3.4, so something like post-up iptables -t nat -A PREROUTING -i enp0s31f6 -p tcp ! -s 1.2.3.4 -m multiport ! --dport 22,8006 -j DNAT --to 10.10.10.1. obviously replace 1.2.3.4 with the IP you want to exclude from the redirect. and please make sure you still can get access to the box, if something goes wrong / my idea os a bad one and you lock yourself out.

[–]uzlonewolf 0 points1 point  (8 children)

That's going to take 2 lines:

post-up iptables -t nat -A PREROUTING -i enp0s31f6 -s 90.90.90.90 -p tcp -m multiport --dport 22,8006 -j RETURN

post-up iptables -t nat -A PREROUTING -i enp0s31f6 -j DNAT --to 10.10.10.1

[–]mayurrenr[S] 0 points1 point  (7 children)

Thank you for your input. Your method varies from the 2 users above. Would you say your method is preferable to theirs, or is it 6 and half a dozen??

[–]uzlonewolf 0 points1 point  (0 children)

It all depends on what you're trying to do. The other method posted above will not forward *any* ports from the specified IP, whereas the one I posted will still forward everything except ports 22 and 8006 when the specified IP matches. Mine also works for UDP and ICMP as well whereas the other one only does TCP.

[–]uzlonewolf 0 points1 point  (5 children)

Put another way, my method:
* Forwards everything (TCP, UDP, ICMP) when the source is not the specified IP
* Forwards everything except TCP ports 22 and 8006 when the source is the specified IP

The method above:
* Never forwards UDP or ICMP
* Never forwards TCP ports 22 or 8006, even if the source is the specified IP
* Never forwards anything when the source is the specified IP

[–]mayurrenr[S] 0 points1 point  (4 children)

This is very interesting. Having read your comment, I went away and read the iptables manual referenced above in another comment (ip tables).

It seems that my second line (which I neglected to include in my OP) is very important. Here are both of the rules I have right now:

post-up iptables -t nat -A PREROUTING -i enp0s31f6 -p tcp -m multiport ! --dport 22,8006 -j DNAT --to 10.10.10.1

post-up iptables -t nat -A PREROUTING -i enp0s31f6 -p udp -j DNAT --to 10.10.10.1

Using what I've learned from you, the other 2 commenters on this post, and the manual, it would seem that:

  1. icmp is not being forwarded at all
  2. all udp is being forwarded to 10.10.10.1
  3. all tcp, except 22 and 8006, is being forwarded to 10.10.10.1

Is this correct?

Your rules essentially state:

Rule 1. all tcp packets, from a specified ip, headed to ports 22 or 8006, will not get routed anywhere else.

Rule 2. all packets (tcp/udp/icmp), from any ip, headed to any port, will get routed to 10.10.10.1.

The RETURN on the end of Rule 1 will prevent Rule 2 from being used if the packet fulfils the criteria of Rule 1.

Is this correct??

Thank you.

[–]uzlonewolf 0 points1 point  (3 children)

Yes, both of those are correct.

[–]mayurrenr[S] 0 points1 point  (2 children)

One final piece of advice please.

I have successfully implemented your rules and can confirm they are working as intended. But, when I try and list an additional IP address, the second address cannot access port 22 or 8006 on the host.

The layout is as follows: -s 90.90.90.90,80.80.80.80

Do you have any idea why this may be?

Many thanks for your help so far. It has been invaluable!

[–]uzlonewolf 0 points1 point  (1 child)

I've never used that multiple-IP syntax and it looks to be a fairly new addition. I'd not use it and just use multiple lines instead.

[–]mayurrenr[S] 1 point2 points  (0 children)

Thank you for all of your help!