I am trying to apply SNAT to a PPTP client. The TCP/1723 packets are being SNATed properly but not the GRE ones. Can anyone spot what's wrong?
I have the following iptables configuration:
$ sudo iptables -t nat -L POSTROUTING -v -n
Chain POSTROUTING (policy ACCEPT 616 packets, 37030 bytes)
pkts bytes target prot opt in out source destination
0 0 SNAT 47 -- * * $internal_ip 0.0.0.0/0 to:$external_ip
When inspecting outgoing traffic on the egress interface using tcpdump, I see the following:
<timestamp> IP $internal_ip > $target_ip: GREv1, call 31607, seq 1, length 36: LCP, Conf-Request (0x01), id 1, length 22
… instead of the expected $external_ip >
so clearly the SNAT
translation isn't working (as is clear from the 0 pkts 0 bytes
).
I have the following modules loaded (among others):
nf_nat_proto_gre
nf_conntrack_proto_gre
nf_conntrack_pptp
nf_nat_pptp
A few notes in case this is relevant:
- The routing is happening upstream using a 3rd party firewall (so the outgoing packets are already on the correct egress interface).
- The firewall is actually running in a VM (the above
iptables
listing is from its hypervisor), bridged to the egress interface. - The TCP/1723 packets are being SNATed by the firewall (but not the GRE ones); I'm effectively trying to use IPTables as a workaround to the firewall shortcoming. Presumably IPTables doesn't care about how the packets got there?
- The egress interface/bridge has a static IP which is different from
$external_ip
(albeit on the same subnet)
This is a Ubuntu 14.04 server running 3.13.0-123-generic
Best Answer
First of all your iptables command missing
-t nat
part. But this should generate an error as no POSTROUTING table exists in filter table by default. Make sure you are adding this to a correct table. This is very similar to this question: NAT GRE (IP protocol 47) over Linux routerNext, make sure your are specified correct $internal_ip and that one matches the one you see on your tcpdump. Sometimes a simple typo slides out of sight and makes things look complicated.
Also check your iptables rules doesn't have any preceding rule which triggers before your SNAT rule. Netfilter will trigger only first match on that occasion. Your note that TCP/1723 are natted actually means that you have other rules there.
If this doesn't helps, make sure to check & post your detailed configuration with
iptables -t nat -L -v -n
and things likeip rule ls && ip route ls
. With-v
switch with iptables you can actually see how much packets was triggered with each of your rules.You are running inside VM. Check your host node iptables rules also! Your rule might worked but host node firewall has overwritten packed source IP coming from your VM back to your internal ip. As seems like you are inspecting packets somewhere else, i.e. not directly on your VM.