<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On 23 November 2013 13:29, Mirko Parthey <span dir="ltr"><<a href="mailto:mirko.parthey@informatik.tu-chemnitz.de" target="_blank">mirko.parthey@informatik.tu-chemnitz.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">On Fri, Nov 22, 2013 at 05:52:21PM +0000, Will Wykeham wrote:<br>

</div><div><div class="h5">> I've got a local subnet with statically assigned address - <a href="http://10.65.112.0/22" target="_blank">10.65.112.0/22</a>. One<br>
> of the devices is a linux box acting as a gateway with a PPP connection, it has<br>
> a normal ethernet controller with address 10.65.112.69, and when the PPP<br>
> connection is up it has an assigned address of 10.1.20.19.<br>
><br>
> Also on the local subnet is another machine (Windows as it happens),<br>
> 10.65.112.174, with gateway set to the .69 machine.<br>
><br>
> Prior to integrating the VPN, I had some normal NAT going on so that the<br>
> Windows box could communicate with the outside world, but using the "public" IP<br>
> of 10.1.20.19. A fairly standard sort of rule:<br>
> iptables --table nat --append POSTROUTING --out-interface ppp0 -j MASQUERADE<br>
><br>
> This worked fine - I could ping other devices on the public net directly from<br>
> the Windows box.<br>
><br>
> I've now got an IPSEC based VPN, with the following connection setup:<br>
><br>
> conn MYCONN<br>
> left=%defaultroute<br>
> leftsourceip=%config<br>
> right=10.1.40.1<br>
> rightsubnet=<a href="http://10.31.21.0/24" target="_blank">10.31.21.0/24</a><br>
> auto=add<br>
><br>
> This VPN works fine and from the Linux gateway I can ping remote devices<br>
> (10.31.21.XXX) without any problem. If I add in my NAT rule again though,<br>
> everything breaks - I can't ping from the local machine or the Windows box. The<br>
> packets go out on the PPP interface but without being encapsulated, whether<br>
> they've been locally or remotely generated.<br>
><br>
> My understanding of the iptables NAT table is that it takes place before it<br>
> gets to the xfrm lookup (<a href="http://upload.wikimedia.org/wikipedia/commons/3/37/" target="_blank">http://upload.wikimedia.org/wikipedia/commons/3/37/</a><br>
> Netfilter-packet-flow.svg), and so once the source has been rewritten to<br>
> 10.1.20.19, it should get picked up by the vpn and encapsulated, but that is<br>
> clearly not what's happening.<br>
<br>
</div></div>Your IPsec connection is set up as host-to-net, but behind that host<br>
(the gateway) you have multiple machines which want to use the IPsec<br>
tunnel. I see this as the reason why you are trying to set up NAT for<br>
both unprotected and IPsec-protected traffic.<br>
<br>
A cleaner solution in my opinion would be to use NAT only for non-IPsec<br>
traffic, and set up IPsec with a net-to-net connection. This requires<br>
that you are able to change the configuration of both gateways, and<br>
that IP addresses from the <a href="http://10.65.112.0/22" target="_blank">10.65.112.0/22</a> range are routable inside<br>
the remote subnet.<br>
On the local gateway, replace leftsourceip=%config with<br>
leftsubnet=<a href="http://10.65.112.0/22" target="_blank">10.65.112.0/22</a>, and on the remote gateway, do the same for<br>
rightsourceip and rightsubnet.<br>
Then, set up your NAT rule such that it applies only to non-IPsec traffic:<br>
<div class="im">  iptables -t nat -A POSTROUTING -o ppp0 -m policy --dir out --pol none -j MASQUERADE<br>
</div>and you should be done.<br>
<br>
If you cannot meet these requirements, we are back to your original<br>
question how to set up NAT in conjunction with IPsec.<br>
You have to make sure that outgoing packets match the IPsec policy after<br>
NAT processing. In particular, the packet's sender IP address after NAT must<br>
match the IPsec tunnel's internal source IP assigned by the %config mechanism.<br>
If no policy matches, the packet is sent out in plain text.<br>
<div class="im"><br>
> My understanding of the iptables NAT table is that it takes place before it<br>
> gets to the xfrm lookup (<a href="http://upload.wikimedia.org/wikipedia/commons/3/37/" target="_blank">http://upload.wikimedia.org/wikipedia/commons/3/37/</a><br>
> Netfilter-packet-flow.svg), and so once the source has been rewritten to<br>
> 10.1.20.19, it should get picked up by the vpn and encapsulated, but that is<br>
> clearly not what's happening.<br>
<br>
</div>I would suggest to change your NAT rule as follows:<br>
  iptables -t nat -A POSTROUTING -o ppp0 -j SNAT --to-source $ip_addr<br>
where $ip_addr is the local internal source IP assigned by the remote<br>
gateway. If that IP address comes from an address pool and changes<br>
dynamically on connection establishment, the NAT rule needs to be<br>
updated as well, for example inside an updown script.<br>
Using "-j SNAT --to-source" instead of "-j MASQUERADE" gives you<br>
control over the sender IP address after NAT, which may be needed to<br>
match the IPsec policy.  I haven't used such a setup myself, but I am sure<br>
others can correct any possible errors in my description.<br>
<br>
By the way, you didn't say how you checked if outgoing packets are encrypted.<br>
Using a packet sniffer on the gateway itself can give misleading results.<br>
I'd recommend to either use a box separate from the gateway to monitor<br>
the traffic, or read xfrm packet counters on the gateway with "ipsec<br>
statusall".<br>
<br>
Regards,<br>
Mirko<br></blockquote><div><br></div><div>Mirko,</div><div><br></div><div>Thanks for the responses. <br></div><div><br></div><div>I do have control over the gateway configuration if necessary, but setting up a net to net connection won't work in this case. This is a piece of embedded hardware using ethernet internally, and using a 3G modem to communicate with the outside world. There will be several of them, all using the same static IP set up internally, so I can't do a net-net connection or I'd have conflicts.</div>
<div><br></div><div>Packets matching the XFRM policy does seem to be key here, I don't think the source address is the issue though - I'm currently thinking it's the destination address.</div><div>The xfrm policy (from "ip xfrm state" - an invaluable discovery!), relates to src 10.1.20.19, and destination 10.1.40.1 (and obviously the reverse for the other direction).</div>
<div>Clearly the routing rules I've got in place cause locally generated packets to the 10.31.21.0 net to get routed to 10.1.40.1 as the gateway. This is (some of) the output from "route":</div><div><br></div>
<div><div><div>Destination     Gateway         Genmask         Flags Metric Ref    Use Iface</div><div>10.1.40.0       *               255.255.255.0   U     0      0        0 ppp0</div><div>10.31.21.0      10.1.40.1       255.255.255.0   UG    0      0        0 ppp0</div>
</div></div><div><br></div><div>The destination is then 10.1.40.1, and the source is 10.1.20.19, so they match the xfrm policy.</div><div><br></div><div>Looking at tcpdump on the ppp interface though, when the basic NAT rule is in place, the source has been appropriately re-written from 10.65.112.174 to 10.1.20.19, but the destination is 10.31.21.10, not 10.1.40.1, as you might expect. This then means it doesn't match the xfrm policy, and goes straight out on the wire.</div>
<div>Packets originating externally aren't going through quite the same routing process as those internally, and so they're ending up coming out on the PPP interface with their destination still as 10.31.21.0, even though I don't have a routing rule for that. Slightly strange, and where I'm looking now. This is a separate problem to the NAT rule - it happens even if the rule isn't in use (although obviously I see the source addess as 10.65.112.174 in the dump then).</div>
<div><br></div><div>I'm interested you say that packet sniffing on the device isn't completely reliable - it's been ok so far, but definitely worth bearing in mind. Are there any particular circumstances under which I should be wary of it?</div>
<div><br></div><div>Regards,</div><div>Will</div></div></div></div>