LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Networking (https://www.linuxquestions.org/questions/linux-networking-3/)
-   -   iptables DNAT does not work? (https://www.linuxquestions.org/questions/linux-networking-3/iptables-dnat-does-not-work-4175580248/)

jip 05-20-2016 05:14 AM

iptables DNAT does not work?
 
Dear all,

I am trying to implement destination NAT on a Linux box using:

# iptables -t nat -A PREROUTING -d 217.118.168.80 -j DNAT \
--to-destination 62.138.116.25


I would expect all connections originated from the local box to the
217.118.168.80 redirected to 62.138.116.25, but it does not happen.

curl and tcpdump show that the connections still go to the 217.118.168.80, so it looks like the iptables rule does not have any effect... probably I missed some important point?

Your help/suggestions are highly appreciated.

/* --
uname -a
Linux NB0618-L 3.16.0-71-generic #91~14.04.1-Ubuntu SMP Mon Apr 18 19:43:36 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

iptables -t nat -A PREROUTING -d 217.118.168.80 -j DNAT --to-destination 62.138.116.25

iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL
DNAT all -- anywhere 217.118.168.80 to:62.138.116.25
...

*/

Best regards,
Yury Pakhomenko

sundialsvcs 05-20-2016 07:23 AM

Quote:

I am trying to implement destination NAT on a Linux box ...
[...]

I would expect all connections originated from the local box ...
Whups, that is "Source NAT," or SNAT!

Source-NAT is what maps the local-addresses at the source, in the outbound traffic, so that replies can be returned to the same source, "inside."

Destination-NAT is what allows incoming traffic to be delivered to a particular place on the internal network, so that replies can be returned to the same destination, "outside."

When I want everyone in my office to be able to use the Internet, that's SNAT. Traffic can be sent out, and replied-to. But, if I wanted to set up a publicly-accessible web server on one of the office machines, I'd have to set up DNAT rules to allow that external traffic to be properly routed: from the gateway, to my internal server, and back again.

vincix 05-20-2016 07:27 AM

Secondly, do you actually need nat or simply forwarding? If both networks have public IPs, why do you actually need nat?

Thirdly, you should never post your real public IPs. They might be targeted by bad people :)

jip 05-20-2016 08:11 AM

thanks a lot for your answer, I think my question was misleading, in fact I need:

|my src IP|some dst IP_1| --> (iptables) --> |my src IP|some dst IP_2|

so when some particular outside IP is contacted from inside,
I need the destination IP re-written, so that the packets go to a different address,
if I understood your point, it is not DNAT (other direction) ...
could you advice what do I actually need for the use case?

Quote:

Originally Posted by sundialsvcs (Post 5548169)
Whups, that is "Source NAT," or SNAT!

Destination-NAT is what allows incoming traffic to be delivered to a particular place on the internal network, so that replies can be returned to the same destination, "outside."


vincix 05-20-2016 09:18 AM

Quote:

Originally Posted by jip (Post 5548187)
thanks a lot for your answer, I think my question was misleading, in fact I need:

|my src IP|some dst IP_1| --> (iptables) --> |my src IP|some dst IP_2|

so when some particular outside IP is contacted from inside,
I need the destination IP re-written, so that the packets go to a different address,
if I understood your point, it is not DNAT (other direction) ...
could you advice what do I actually need for the use case?

I think you got it right from the beginning, after all. But you did append -j ACCEPT at the end, right? It doesn't look as if you did so :)

iptables has this weird behaviour... it doesn't give an error if you don't use jump or some other directive. It's like a dead rule. It happened to me before, I hope that's the problem and it's easier than expected :)

vincix 05-20-2016 09:35 AM

I didn't take into consideration one aspect though. The local box has a private network, right? So you still do need SNAT, don't you, in order for the translation of Private IPs to Public IPs to be made?

jip 05-20-2016 09:54 AM

Quote:

Originally Posted by vincix (Post 5548221)
I didn't take into consideration one aspect though. The local box has a private network, right? So you still do need SNAT, don't you, in order for the translation of Private IPs to Public IPs to be made?

It's ok, the overloaded snat is performed by the firewall...

jip 05-20-2016 09:57 AM

I am not sure if I've got your point -- multiple "-j" are not allowed, so
iptables -t nat -A PREROUTING -d 217.118.168.80 -j DNAT --to-destination 62.138.116.25 -j ACCEPT
would not be accepted, let me try that out:

iptables -t nat -A PREROUTING -d 217.118.168.80 -j DNAT --to-destination 62.138.116.25 -j ACCEPT
iptables v1.4.21: multiple -j flags not allowed
Try `iptables -h' or 'iptables --help' for more information.


Quote:

Originally Posted by vincix (Post 5548215)
I think you got it right from the beginning, after all. But you did append -j ACCEPT at the end, right? It doesn't look as if you did so :)

iptables has this weird behaviour... it doesn't give an error if you don't use jump or some other directive. It's like a dead rule. It happened to me before, I hope that's the problem and it's easier than expected :)


lazydog 05-20-2016 10:10 AM

Quote:

Originally Posted by jip (Post 5548187)
thanks a lot for your answer, I think my question was misleading, in fact I need:

|my src IP|some dst IP_1| --> (iptables) --> |my src IP|some dst IP_2|

so when some particular outside IP is contacted from inside,
I need the destination IP re-written, so that the packets go to a different address,
if I understood your point, it is not DNAT (other direction) ...
could you advice what do I actually need for the use case?

Outside network -> Your Network = DNAT
Your network -> Outside network = SNAT or MASQ

Example:
Code:

iptables -t nat -A PREROUTING -i <external interface> -d <outside ip address> -j DNAT --to-destination <inside ip address>

iptables -A FORWARD -i <external interface> -d <inside ip address> -j ACCEPT

iptables -t nat POSTROUTE -o <external interface> -j MASQURADE

I always place the interface in my rules so that the rule is only applied to the interface it needs to be.
When you do not supply an interface the rule is applied to all interfaces.

jip 05-20-2016 10:33 AM

Hi,

thanks for all replies, they gave me the idea where to look :-)
This worked as expected:


iptables -t nat -A OUTPUT -d 8.8.8.8 -j DNAT --to-destination 75.126.162.205 # :-)))

curl -D - 8.8.8.8
HTTP/1.1 302 Found
Server: nginx
Date: Fri, 20 May 2016 15:30:48 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Keep-Alive: timeout=45
Location: http://www.lqconsulting.com/

17:31:26.533310 IP 192.168.178.37.35933 > 75.126.162.205.80: Flags [S], seq 2802046731, win 29200, options [mss 1460,sackOK,TS val 7857540 ecr 0,nop,wscale 7], length 0
17:31:26.685893 IP 75.126.162.205.80 > 192.168.178.37.35933: Flags [S.], seq 1356990771, ack 2802046732, win 5840, options [mss 1452], length 0
17:31:26.685945 IP 192.168.178.37.35933 > 75.126.162.205.80: Flags [.], ack 1, win 29200, length 0
17:31:26.685984 IP 192.168.178.37.35933 > 75.126.162.205.80: Flags [P.], seq 1:72, ack 1, win 29200, length 71
17:31:26.838512 IP 75.126.162.205.80 > 192.168.178.37.35933: Flags [.], ack 72, win 5840, length 0
17:31:26.847081 IP 75.126.162.205.80 > 192.168.178.37.35933: Flags [P.], seq 1:207, ack 72, win 5840, length 206
17:31:26.847138 IP 192.168.178.37.35933 > 75.126.162.205.80: Flags [.], ack 207, win 30016, length 0
17:31:26.847445 IP 192.168.178.37.35933 > 75.126.162.205.80: Flags [F.], seq 72, ack 207, win 30016, length 0
17:31:26.998604 IP 75.126.162.205.80 > 192.168.178.37.35933: Flags [F.], seq 207, ack 73, win 5840, length 0
17:31:26.998661 IP 192.168.178.37.35933 > 75.126.162.205.80: Flags [.], ack 208, win 30016, length 0
.....

Quote:

Originally Posted by lazydog (Post 5548246)
Outside network -> Your Network = DNAT
Your network -> Outside network = SNAT or MASQ

Example:
Code:

iptables -t nat -A PREROUTING -i <external interface> -d <outside ip address> -j DNAT --to-destination <inside ip address>

iptables -A FORWARD -i <external interface> -d <inside ip address> -j ACCEPT

iptables -t nat POSTROUTE -o <external interface> -j MASQURADE

I always place the interface in my rules so that the rule is only applied to the interface it needs to be.
When you do not supply an interface the rule is applied to all interfaces.


vincix 05-20-2016 05:01 PM

Quote:

Originally Posted by jip (Post 5548241)
I am not sure if I've got your point -- multiple "-j" are not allowed, so
iptables -t nat -A PREROUTING -d 217.118.168.80 -j DNAT --to-destination 62.138.116.25 -j ACCEPT
would not be accepted, let me try that out:

iptables -t nat -A PREROUTING -d 217.118.168.80 -j DNAT --to-destination 62.138.116.25 -j ACCEPT
iptables v1.4.21: multiple -j flags not allowed
Try `iptables -h' or 'iptables --help' for more information.

Yes, it obviously doesn't work. I simply mixed things up altogether.

I was wondering what the nat OUTPUT chain was there for :)

I still don't see how it works if you do a SNAT in POSTROUTING, though. I mean, I don't understand the logic. POSTROUTING is the last chain, you wouldn't be able to change anything afterwards, so I don't understand how this actually works, given that OUTPUT precedes POSTROUTING, and SNAT means that you jump direct to POSTROUTING.

lazydog 05-20-2016 10:57 PM

Quote:

Originally Posted by vincix (Post 5548444)
Yes, it obviously doesn't work. I simply mixed things up altogether.

I was wondering what the nat OUTPUT chain was there for :)

I still don't see how it works if you do a SNAT in POSTROUTING, though. I mean, I don't understand the logic. POSTROUTING is the last chain, you wouldn't be able to change anything afterwards, so I don't understand how this actually works, given that OUTPUT precedes POSTROUTING, and SNAT means that you jump direct to POSTROUTING.

Not sure if this is directed towards myself or not.

In any part of that path you can change anything you want. The only thing you would not want to change in the POSTROUTE is the destination address as you have already past the part that makes the routing decisions.

As to SNAT, you can do that in either OUTPUT or POSTROUTE chain.

It is the same with the DNAT, you can do that in either PREROUTE or INPUT chain.

vincix 05-21-2016 03:31 AM

Quote:

Originally Posted by lazydog (Post 5548543)
Not sure if this is directed towards myself or not.

In any part of that path you can change anything you want. The only thing you would not want to change in the POSTROUTE is the destination address as you have already past the part that makes the routing decisions.

As to SNAT, you can do that in either OUTPUT or POSTROUTE chain.

It is the same with the DNAT, you can do that in either PREROUTE or INPUT chain.

Well, that's exactly what I was talking about when I said that in the POSTROUTING chain you cannot change anything. I was referring to this context, and obviously, to the destination address.

So you've got SNAT for the private-to-public translation, and then you've got DNAT, to redirect packets to a different destination.
But iff you use SNAT, you use the POSTROUTING chain, don't you? So then how do you then change the destination of the packets?

vincix 05-21-2016 02:20 PM

@jip
OUTPUT chain – NAT for locally generated packets on the firewall.

Are you sure this is what you're looking for?

vincix 05-21-2016 04:34 PM

Ok, only now did I understand what you were trying to do. So you were actually interested in redirecting all the IPs originating from the computer you're applying iptables to to a different destination, based on the initial packet destination. I thought you were actually trying to apply the rule to your private IPs on your lan. I thought you were using your linux machine as a router (or maybe you do, but that's irrelevant in this case).

So your discovery is exactly what you needed, indeed.

But what I thought you were trying to do (and also interested me) was routing your lan with SNAT and redirecting all packets with a specific destination to another specific destination. And in order to do that, you simply apply both DNAT and SNAT. SNAT for your LAN, and DNAT for changing the destination. For instance:

Quote:

iptables -t nat -A PREROUTING -s 192.168.0.0/24 -d 1.2.3.4 -i eth0 -j DNAT --to-destination 5.6.7.8
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j SNAT --to-source 1.1.1.1
So this works for me, indeed.

@lazydog
I don't think the INPUT chain in the nat table actually exists. So I don't think you can apply either SNAT or DNAT to the INPUT chain. Correct me if I'm wrong.


All times are GMT -5. The time now is 01:08 PM.