OpenVPN to IPsec source NAT
-
I'm having trouble getting openVPN clients to communicate with hosts on the other end of an IPsec tunnel and would really appreciate any input.
Current situation:
- Pfsense machine: 10.0.1.254 (aliased in firewall as INT_IP)
- type: netgate XG-7100
- software: 2.4.4-release-p3
- LAN network: 10.0.1.0/24
- testing client: 10.0.1.253
- IPsec:
- local network: LAN subnet
- remote network: 172.17.0.0/16
- resulting P2 entry 10.0.1.0/24 <->172.17.0.0/16
- example testing host: 172.17.20.130
- OpenVPN:
- OpenVPN subnet: 192.168.248.0/24
- OpenVPN server/interface has IP IP 192.168.248.1
- testing client: 192.168.248.2
- Clients receive push-routes, including the IPsec remote network.
The party on the remote network requires us to do source NAT, to translate requests from our end to 10.0.1.254. To this end, the following outbound NAT rule was added to Firewall/NAT/Outbound:
interface: IPsec address family: ipv4 protocol: any source: 10.0.1.0/24 destination: 172.17.0.0/16 NAT address: INT_IP (host alias for 10.0.1.254) Pool options: default
This rule works, for hosts in the LAN network. I have a machine (raspi) connected to the machine gateway as 10.0.1.253. This Pi can succesfully ping a host in 172.17.0.0/16 when this rule is enabled.
However, when cloning this rule for OpenVPN:
interface: IPsec address family: ipv4 protocol: any source: 192.168.248.0/24 destination: 172.17.0.0/16 NAT address: INT_IP (10.0.1.254) Pool options: default
The OpenVPN client cannot ping said host in 172.17.0.0/16.
Our previous setup consisted of a linux machine (10.0.1.1) with iptables, which achieved this through the following rule:
iptables -t nat -I POSTROUTING -s 192.168.248.0/24 -d 172.17.0.0/16 -j SNAT --to-source 10.0.1.1
I'm trying to mimic said rule with the outbound NAT rule mentioned above.Steps I've taken to troubleshoot this:
- firewall:
- under Firewall/Rules/LAN:
- added rule allowing any traffic from any network to 172.17.0.0/16 to pass
- ping attempts from 10.0.1.253 to 172.17.0.0/16 show up in the states table and return traffic is registered
- packets + bytes: 48 / 47 4 KiB / 4 KiB
- under Firewall/Rules/OpenVPN:
- added rule allowing any traffic destined for 172.17.0.0/16 to pass.
- Ping attempts from 192.168.248.2 to hosts in 172.17.0.0/16 do show up in the states table
- no packets or bytes are returned: 31.71 K / 0 2.54 MiB / 0 B
- under Firewall/Rules/LAN:
- NAT:
- under Firewall/NAT/outbound:
- Altered the above-mentioned rule's translation address from "host alias: INT_IP ()" to "Interface address", with no success.
- under Firewall/NAT/outbound:
Now I did some traceroutes:
- from the Raspberry pi in the LAN network to a host in the IPsec remote network:
traceroute to 172.17.20.130 (172.17.20.130), 30 hops max, 60 byte packets 1 10.0.1.254 (10.0.1.254) 0.561 ms 0.617 ms 0.428 ms 2 ipsec-p1.example.com (ipsec P1 remote gateway IP) 25.029 ms 25.814 ms 25.472 ms 3 ip.in.remote.network (IP in the remote network) 26.037 ms 25.697 ms 25.358 ms 4 172.17.20.130 (172.17.20.130) 25.231 ms * *
- from the OpenVPN client to the raspi in the LAN network:
traceroute to 10.0.1.253 (10.0.1.253), 30 hops max, 60 byte packets 1 192.168.248.1 (192.168.248.1) 29.568 ms 30.109 ms 30.111 ms 2 10.0.1.253 (10.0.1.253) 30.118 ms 31.242 ms 31.257 ms
- from the OpenVPN client to a host in the IPsec remote network:
traceroute to 172.17.20.130 (172.17.20.130), 30 hops max, 60 byte packets 1 192.168.248.1 (192.168.248.1) 16.583 ms 17.312 ms 17.853 ms 2 * * * 3 * * * ...
It's as if traffic from the OpenVPN interface is not even being routed to the IPsec-tunnel. Has anybody ever jousted with openvpn to ipsec communication and am I perhaps just looking in the completely wrong locations?
- Pfsense machine: 10.0.1.254 (aliased in firewall as INT_IP)
-
A brief update on the issue:
I did a several tcpdumps to see how traffic traveled through the machine.
pings from the Raspberry Pi 10.0.1.253 to 172.17.20.130 are sent to the ipsec interface and receive replies:
tcpdump -i lagg0.100 icmp
14:22:27.875175 IP 10.0.1.253 > 172.17.20.130: ICMP echo request, id 8761, seq 14, length 64 14:22:27.899031 IP 172.17.20.130 > 10.0.1.253: ICMP echo reply, id 8761, seq 14, length 64
These in turn are encapsulated:
tcpdump -i enc0 icmp
14:23:23.969153 (authentic,confidential): SPI 0x82bee771: IP 10.0.1.253 > 172.17.20.130: ICMP echo request, id 8761, seq 70, length 64 14:23:23.992999 (authentic,confidential): SPI 0xc030c198: IP 172.17.20.130 > 10.0.1.254: ICMP echo reply, id 21640, seq 70, length 64
We see the requests going out as 10.0.1.253 and replies coming in for 10.0.1.254, which are then translated back to finally be delivered to the Pi.
Now, when repeating this check with an OpenVPN client, we see different behavior:
tcpdump -i ovpns7 icmp
14:27:13.375762 IP 192.168.248.2 > 172.17.20.130: ICMP echo request, id 13598, seq 1, length 64 14:27:14.383797 IP 192.168.248.2 > 172.17.20.130: ICMP echo request, id 13598, seq 2, length 64
Requests go out, but nothing returns. Let's see where the requests go:
tcpdump -i enc0 icmp
yields nothing, so let's try WAN:
tcpdump -i lagg0.4090 icmp
14:30:10.318176 IP 192.168.248.2 > 172.17.20.130: ICMP echo request, id 30820, seq 3, length 64 14:30:11.326380 IP 192.168.248.2 > 172.17.20.130: ICMP echo request, id 30820, seq 4, length 64
Now it's getting interesting: the pings from OpenVPN clients are sent to the default route (WAN). If I change the NAT rule's interface from IPsec to WAN, the translation also shows up in the tcpdump output:
interface: WAN address family: ipv4 protocol: any source: 192.168.248.0/24 destination: 172.17.0.0/16 NAT address: INT_IP (10.0.1.254) Pool options: default
Let's try the tcpdump again:
tcpdump -i lagg0.4090 icmp
14:33:12.248168 IP 10.0.1.254 > 172.17.20.130: ICMP echo request, id 15552, seq 1, length 64 14:33:13.251668 IP 10.0.1.254 > 172.17.20.130: ICMP echo request, id 15552, seq 2, length 64
So the firewall is correctly performing outbound NAT translation for 192.168.248.0/24->172.17.0.0/16 as 10.0.1.254, but the traffic is routed from the OpenVPN interface to the default gateway (WAN interface / lagg0.4090) rather than to the IPsec tunnel for encapsulation.
The whole point of wanting to use outbound NAT for traffic to 172.17.0.0/16 is so either side only needs to define one P2 entry, but we can set up multiple OpenVPN tunnels (with each a different subnet) that can all reach that remote network.
Would anybody know a trick / way to force traffic from 192.168.248.0 to 172.17.0.0/16 to go via the IPsec interface (enc0) rather than the default gateway (WAN/lagg0.4090)? I've tried creating a bogus gateway under System/Routing/Gateways and creating a static route under System/Routing/Static Routes for 172.17.0.0/16 via this bogus gateway, but this only resulted in all traffic from ovpns7 meant for this subnet to get put through a loop until the TTL expired.
-
This post is deleted! -
Hi JohnnyricoMC, I have the same requirement on our network and ran into the same issues as you did. Have you found a solution besides creating another P2 on your IPsec (even though it would be much easier to accomplish)?
Cheers,
Paul -
@paul-heidenreich-0 Unfortunately no, not really, at least not on the pfsense box. We circumvented the problem by running an OpenVPN server on a separate VM in the LAN subnet and employing masquerading on that host.
-
@JohnnyricoMC
You can do this with BINAT in IPSec. It can translates source IPs to whatever you want.Additionally in the OpenVPN server settings you have to add the remote network to the "Local Networks".
-
Thanks a lot for you quick replies!
@viragomann said in OpenVPN to IPsec source NAT:
You can do this with BINAT in IPSec. It can translates source IPs to whatever you want.
I already tried the BINAT in IPsec before. Unfortunately you have to create another P2 which of course has to be created on the other site as well.
In my case I was able to use the BINAT option anyway, since I could use an existing P2 which wasn't in use (and needed) anymore.
The outbound NAT method would have still been the nicer/slicker way. But it always routed my traffic to the default gateway (WAN) instead of the IPsec interface. I'm not sure wether it's a mistake in pfsense or if I don't understand the way it's supposed to work.
@viragomann said in OpenVPN to IPsec source NAT:
Additionally in the OpenVPN server settings you have to add the remote network to the "Local Networks".
You have always have to add the remote networdk to the "local networks", no matter if you use BINAT or outbound NAT.
I found a solution, that's all that counts - at least for the moment.
-
@paul-heidenreich-0
Outbound NAT doesn't work with policy-based IPSec tunnels. You have to do the NAT inside IPSec.
It should work with VTI IPSec, however.If you have already a phase 2 to for the NAT-IP or subnet at the remote side, an additional is not needed in most cases.
You have always have to add the remote networdk to the "local networks", no matter if you use BINAT or outbound NAT.
That's correct. But you didn't mention, that you have already done this.