[strongSwan] NAT over VPN

Will Wykeham will at wykeham.net
Mon Nov 25 17:24:45 CET 2013


On 23 November 2013 13:29, Mirko Parthey <
mirko.parthey at informatik.tu-chemnitz.de> wrote:

> On Fri, Nov 22, 2013 at 05:52:21PM +0000, Will Wykeham wrote:
> > I've got a local subnet with statically assigned address -
> 10.65.112.0/22. One
> > of the devices is a linux box acting as a gateway with a PPP connection,
> it has
> > a normal ethernet controller with address 10.65.112.69, and when the PPP
> > connection is up it has an assigned address of 10.1.20.19.
> >
> > Also on the local subnet is another machine (Windows as it happens),
> > 10.65.112.174, with gateway set to the .69 machine.
> >
> > Prior to integrating the VPN, I had some normal NAT going on so that the
> > Windows box could communicate with the outside world, but using the
> "public" IP
> > of 10.1.20.19. A fairly standard sort of rule:
> > iptables --table nat --append POSTROUTING --out-interface ppp0 -j
> MASQUERADE
> >
> > This worked fine - I could ping other devices on the public net directly
> from
> > the Windows box.
> >
> > I've now got an IPSEC based VPN, with the following connection setup:
> >
> > conn MYCONN
> > left=%defaultroute
> > leftsourceip=%config
> > right=10.1.40.1
> > rightsubnet=10.31.21.0/24
> > auto=add
> >
> > This VPN works fine and from the Linux gateway I can ping remote devices
> > (10.31.21.XXX) without any problem. If I add in my NAT rule again though,
> > everything breaks - I can't ping from the local machine or the Windows
> box. The
> > packets go out on the PPP interface but without being encapsulated,
> whether
> > they've been locally or remotely generated.
> >
> > My understanding of the iptables NAT table is that it takes place before
> it
> > gets to the xfrm lookup (
> http://upload.wikimedia.org/wikipedia/commons/3/37/
> > Netfilter-packet-flow.svg), and so once the source has been rewritten to
> > 10.1.20.19, it should get picked up by the vpn and encapsulated, but
> that is
> > clearly not what's happening.
>
> Your IPsec connection is set up as host-to-net, but behind that host
> (the gateway) you have multiple machines which want to use the IPsec
> tunnel. I see this as the reason why you are trying to set up NAT for
> both unprotected and IPsec-protected traffic.
>
> A cleaner solution in my opinion would be to use NAT only for non-IPsec
> traffic, and set up IPsec with a net-to-net connection. This requires
> that you are able to change the configuration of both gateways, and
> that IP addresses from the 10.65.112.0/22 range are routable inside
> the remote subnet.
> On the local gateway, replace leftsourceip=%config with
> leftsubnet=10.65.112.0/22, and on the remote gateway, do the same for
> rightsourceip and rightsubnet.
> Then, set up your NAT rule such that it applies only to non-IPsec traffic:
>   iptables -t nat -A POSTROUTING -o ppp0 -m policy --dir out --pol none -j
> MASQUERADE
> and you should be done.
>
> If you cannot meet these requirements, we are back to your original
> question how to set up NAT in conjunction with IPsec.
> You have to make sure that outgoing packets match the IPsec policy after
> NAT processing. In particular, the packet's sender IP address after NAT
> must
> match the IPsec tunnel's internal source IP assigned by the %config
> mechanism.
> If no policy matches, the packet is sent out in plain text.
>
> > My understanding of the iptables NAT table is that it takes place before
> it
> > gets to the xfrm lookup (
> http://upload.wikimedia.org/wikipedia/commons/3/37/
> > Netfilter-packet-flow.svg), and so once the source has been rewritten to
> > 10.1.20.19, it should get picked up by the vpn and encapsulated, but
> that is
> > clearly not what's happening.
>
> I would suggest to change your NAT rule as follows:
>   iptables -t nat -A POSTROUTING -o ppp0 -j SNAT --to-source $ip_addr
> where $ip_addr is the local internal source IP assigned by the remote
> gateway. If that IP address comes from an address pool and changes
> dynamically on connection establishment, the NAT rule needs to be
> updated as well, for example inside an updown script.
> Using "-j SNAT --to-source" instead of "-j MASQUERADE" gives you
> control over the sender IP address after NAT, which may be needed to
> match the IPsec policy.  I haven't used such a setup myself, but I am sure
> others can correct any possible errors in my description.
>
> By the way, you didn't say how you checked if outgoing packets are
> encrypted.
> Using a packet sniffer on the gateway itself can give misleading results.
> I'd recommend to either use a box separate from the gateway to monitor
> the traffic, or read xfrm packet counters on the gateway with "ipsec
> statusall".
>
> Regards,
> Mirko
>

Mirko,

Thanks for the responses.

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.

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.
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).
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":

Destination     Gateway         Genmask         Flags Metric Ref    Use
Iface
10.1.40.0       *               255.255.255.0   U     0      0        0 ppp0
10.31.21.0      10.1.40.1       255.255.255.0   UG    0      0        0 ppp0

The destination is then 10.1.40.1, and the source is 10.1.20.19, so they
match the xfrm policy.

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.
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).

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?

Regards,
Will
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.strongswan.org/pipermail/users/attachments/20131125/309f539d/attachment.html>


More information about the Users mailing list