Discussion:
Source NAT in POSTROUTING chain for locally generated packets
Michael Schwartzkopff
2014-08-26 06:38:32 UTC
Permalink
Hi,

For some special reasons I want to alter the IP address of outgoing packets
that are generated locally to a secondary IP address on my machine. For a test
I use the udp/echo service. Without any rules a tcpdump looks like this:

192.168.56.101 is the primary address of the echo server and 192.168.56.16 is
the secondary address of the interface.

08:24:04.063987 IP 192.168.56.1.48462 > 192.168.56.16.echo: UDP, length 6
08:24:04.064522 IP 192.168.56.101.echo > 192.168.56.1.48462: UDP, length 6

So I add the iptables rule:

iptables -t nat -I POSTROUTING -p udp -s 192.168.56.101 --sport 7 \
-j SNAT --to-source 192.168.56.16

now tcpdump shows that no answer packet is sent out any more:

08:24:16.851095 IP 192.168.56.1.55362 > 192.168.56.16.echo: UDP, length 6


With iptables -t nat -L POSTROUTING I can see that the rule is hit since the
counter increases. Also a iptables TRACE shows me that the rule is hit. No
filter appears in the TRACE log.

Any ideas where the packet vanished?


Mit freundlichen Grüßen,

Michael Schwartzkopff
--
[*] sys4 AG

http://sys4.de, +49 (89) 30 90 46 64, +49 (162) 165 0044
Franziskanerstraße 15, 81669 München

Sitz der Gesellschaft: München, Amtsgericht München: HRB 199263
Vorstand: Patrick Ben Koetter, Marc Schiffbauer
Aufsichtsratsvorsitzender: Florian Kirstein
Pascal Hambourg
2014-08-28 22:08:38 UTC
Permalink
Hello,
=20
For some special reasons I want to alter the IP address of outgoing p=
ackets=20
that are generated locally to a secondary IP address on my machine. F=
or a test=20
I use the udp/echo service. Without any rules a tcpdump looks like th=
=20
192.168.56.101 is the primary address of the echo server and 192.168.=
56.16 is=20
the secondary address of the interface.
=20
08:24:04.063987 IP 192.168.56.1.48462 > 192.168.56.16.echo: UDP, leng=
th 6
08:24:04.064522 IP 192.168.56.101.echo > 192.168.56.1.48462: UDP, len=
gth 6
=20
=20
iptables -t nat -I POSTROUTING -p udp -s 192.168.56.101 --sport 7 \
-j SNAT --to-source 192.168.56.16
=20
=20
08:24:16.851095 IP 192.168.56.1.55362 > 192.168.56.16.echo: UDP, leng=
th 6
=20
=20
With iptables -t nat -L POSTROUTING I can see that the rule is hit si=
nce the=20
counter increases. Also a iptables TRACE shows me that the rule is hi=
t. No=20
filter appears in the TRACE log.
=20
Any ideas where the packet vanished?
Clash with an existing connection entry (the one created by the incomin=
g
packet) -> source port changed or packet dropped.
What was the full tcpdump command used ? Any filters ?

--
To unsubscribe from this list: send the line "unsubscribe netfilter" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Michael Schwartzkopff
2014-08-31 12:05:29 UTC
Permalink
Post by Pascal Hambourg
Hello,
Post by Michael Schwartzkopff
For some special reasons I want to alter the IP address of outgoing packets
that are generated locally to a secondary IP address on my machine. For a
test I use the udp/echo service. Without any rules a tcpdump looks like
192.168.56.101 is the primary address of the echo server and 192.168.56.16
is the secondary address of the interface.
08:24:04.063987 IP 192.168.56.1.48462 > 192.168.56.16.echo: UDP, length 6
08:24:04.064522 IP 192.168.56.101.echo > 192.168.56.1.48462: UDP, length 6
iptables -t nat -I POSTROUTING -p udp -s 192.168.56.101 --sport 7 \
-j SNAT --to-source 192.168.56.16
08:24:16.851095 IP 192.168.56.1.55362 > 192.168.56.16.echo: UDP, length 6
With iptables -t nat -L POSTROUTING I can see that the rule is hit since
the counter increases. Also a iptables TRACE shows me that the rule is
hit. No filter appears in the TRACE log.
Any ideas where the packet vanished?
Clash with an existing connection entry (the one created by the incoming
packet) -> source port changed or packet dropped.
Since I so not filter on existing state, the packet should not be dropped
anyway.
Post by Pascal Hambourg
What was the full tcpdump command used ?
Yes. tcpdump should have captured the package.
Post by Pascal Hambourg
Any filters ?
No filters at all.

Mit freundlichen Grüßen,

Michael Schwartzkopff
--
[*] sys4 AG

http://sys4.de, +49 (89) 30 90 46 64, +49 (162) 165 0044
Franziskanerstraße 15, 81669 München

Sitz der Gesellschaft: München, Amtsgericht München: HRB 199263
Vorstand: Patrick Ben Koetter, Marc Schiffbauer
Aufsichtsratsvorsitzender: Florian Kirstein
Michael Schwartzkopff
2014-08-31 14:19:31 UTC
Permalink
Post by Pascal Hambourg
Hello,
Post by Michael Schwartzkopff
For some special reasons I want to alter the IP address of outgoing packets
that are generated locally to a secondary IP address on my machine. For a
test I use the udp/echo service. Without any rules a tcpdump looks like
192.168.56.101 is the primary address of the echo server and 192.168.56.16
is the secondary address of the interface.
08:24:04.063987 IP 192.168.56.1.48462 > 192.168.56.16.echo: UDP, length 6
08:24:04.064522 IP 192.168.56.101.echo > 192.168.56.1.48462: UDP, length 6
iptables -t nat -I POSTROUTING -p udp -s 192.168.56.101 --sport 7 \
-j SNAT --to-source 192.168.56.16
08:24:16.851095 IP 192.168.56.1.55362 > 192.168.56.16.echo: UDP, length 6
With iptables -t nat -L POSTROUTING I can see that the rule is hit since
the counter increases. Also a iptables TRACE shows me that the rule is
hit. No filter appears in the TRACE log.
Any ideas where the packet vanished?
Clash with an existing connection entry (the one created by the incoming
packet) -> source port changed or packet dropped.
SNAT indeed alters the source port that is why the client does not recognizes
the packet now. But I did not find any way not to alter the source port.

Mit freundlichen Grüßen,

Michael Schwartzkopff
--
[*] sys4 AG

http://sys4.de, +49 (89) 30 90 46 64, +49 (162) 165 0044
Franziskanerstraße 15, 81669 München

Sitz der Gesellschaft: München, Amtsgericht München: HRB 199263
Vorstand: Patrick Ben Koetter, Marc Schiffbauer
Aufsichtsratsvorsitzender: Florian Kirstein
Pascal Hambourg
2014-08-31 15:33:11 UTC
Permalink
Post by Michael Schwartzkopff
For some special reasons I want to alter the IP address of outgoing packets
that are generated locally to a secondary IP address on my machine.=
For a
Post by Michael Schwartzkopff
test I use the udp/echo service. Without any rules a tcpdump looks =
like
Post by Michael Schwartzkopff
192.168.56.101 is the primary address of the echo server and 192.16=
8.56.16
Post by Michael Schwartzkopff
is the secondary address of the interface.
08:24:04.063987 IP 192.168.56.1.48462 > 192.168.56.16.echo: UDP, le=
ngth 6
Post by Michael Schwartzkopff
08:24:04.064522 IP 192.168.56.101.echo > 192.168.56.1.48462: UDP, l=
ength 6
Post by Michael Schwartzkopff
iptables -t nat -I POSTROUTING -p udp -s 192.168.56.101 --sport 7 \
-j SNAT --to-source 192.168.56.16
08:24:16.851095 IP 192.168.56.1.55362 > 192.168.56.16.echo: UDP, le=
ngth 6
Post by Michael Schwartzkopff
With iptables -t nat -L POSTROUTING I can see that the rule is hit =
since
Post by Michael Schwartzkopff
the counter increases. Also a iptables TRACE shows me that the rule=
is
Post by Michael Schwartzkopff
hit. No filter appears in the TRACE log.
Any ideas where the packet vanished?
Clash with an existing connection entry (the one created by the inco=
ming
packet) -> source port changed or packet dropped.
=20
SNAT indeed alters the source port that is why the client does not re=
cognizes=20
the packet now. But I did not find any way not to alter the source po=
rt.
=20
Since I so not filter on existing state, the packet should not be dro=
pped=20
anyway.
The NAT table can drop the packet by itself when the clash with an
existing connection cannot be avoided (usually by changing the source
port automatically). Here, the existing connection is the one created b=
y
the incoming packet. However, the SNAT rule does not force the source
port, this should not happen.
What was the full tcpdump command used ?
=20
Yes. tcpdump should have captured the package.
=20
Any filters ?
=20
No filters at all.
If you did not set any filters in tcpdump, it should indeed have
captured the outgoing packet. What have you changed ?

What is your real goal ?
My guess is that you want to SNAT the outgoing packet so that it looks
like the expected reply for the client. IMO this is the wrong way of
doing things. Instead you should consider using DNAT (or maybe REDIRECT=
)
on the original request packet to redirect it to the primary address o=
f
the server, 192.168.56.101, so that the reply packet from that same
address is considered as part of the same connection and is
automatically de-NATed with the original address.

A better fix would be that the server sends the reply from the same
address as the one it received the request on. If the echo service is
part of inetd, that can be done in inetd.conf by specifying the local
address to use.

192.168.56.16:echo dgram udp wait root internal
--
To unsubscribe from this list: send the line "unsubscribe netfilter" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Michael Schwartzkopff
2014-08-31 15:42:58 UTC
Permalink
Post by Pascal Hambourg
Post by Michael Schwartzkopff
Post by Pascal Hambourg
Post by Michael Schwartzkopff
For some special reasons I want to alter the IP address of outgoing packets
that are generated locally to a secondary IP address on my machine. For a
test I use the udp/echo service. Without any rules a tcpdump looks like
192.168.56.101 is the primary address of the echo server and 192.168.56.16
is the secondary address of the interface.
08:24:04.063987 IP 192.168.56.1.48462 > 192.168.56.16.echo: UDP, length 6
08:24:04.064522 IP 192.168.56.101.echo > 192.168.56.1.48462: UDP, length 6
iptables -t nat -I POSTROUTING -p udp -s 192.168.56.101 --sport 7 \
-j SNAT --to-source 192.168.56.16
08:24:16.851095 IP 192.168.56.1.55362 > 192.168.56.16.echo: UDP, length 6
With iptables -t nat -L POSTROUTING I can see that the rule is hit since
the counter increases. Also a iptables TRACE shows me that the rule is
hit. No filter appears in the TRACE log.
Any ideas where the packet vanished?
Clash with an existing connection entry (the one created by the incoming
packet) -> source port changed or packet dropped.
SNAT indeed alters the source port that is why the client does not
recognizes the packet now. But I did not find any way not to alter the
source port.
Since I so not filter on existing state, the packet should not be dropped
anyway.
The NAT table can drop the packet by itself when the clash with an
existing connection cannot be avoided (usually by changing the source
port automatically). Here, the existing connection is the one created by
the incoming packet. However, the SNAT rule does not force the source
port, this should not happen.
Post by Michael Schwartzkopff
Post by Pascal Hambourg
What was the full tcpdump command used ?
Yes. tcpdump should have captured the package.
Post by Pascal Hambourg
Any filters ?
No filters at all.
If you did not set any filters in tcpdump, it should indeed have
captured the outgoing packet. What have you changed ?
What is your real goal ?
My guess is that you want to SNAT the outgoing packet so that it looks
like the expected reply for the client. IMO this is the wrong way of
doing things. Instead you should consider using DNAT (or maybe REDIRECT)
on the original request packet to redirect it to the primary address of
the server, 192.168.56.101, so that the reply packet from that same
address is considered as part of the same connection and is
automatically de-NATed with the original address.
Yeah. DNAT works. Thanks.
Post by Pascal Hambourg
A better fix would be that the server sends the reply from the same
address as the one it received the request on. If the echo service is
part of inetd, that can be done in inetd.conf by specifying the local
address to use.
192.168.56.16:echo dgram udp wait root internal
echo only was an example. The real service does not offer that possibilility
to bind to a single IP address. That also was max first idea.

Mit freundlichen Grüßen,

Michael Schwartzkopff
--
[*] sys4 AG

http://sys4.de, +49 (89) 30 90 46 64, +49 (162) 165 0044
Franziskanerstraße 15, 81669 München

Sitz der Gesellschaft: München, Amtsgericht München: HRB 199263
Vorstand: Patrick Ben Koetter, Marc Schiffbauer
Aufsichtsratsvorsitzender: Florian Kirstein
Loading...