Help needed: IPSec IKEv2 passthrough


#1

Hi,

I've recently upgraded to OpenWRT and I really like the extra features it brings. However unfortunately I cannot get IKEv2 traffic to my IPsec server (raspberry pi) somehow, while it was working before on a Netgear router with stock firmware. I hope somebody here can help :slight_smile:

My setup is as follows:

(client @ WAN) ==> (OpenWRT @ 172.16.0.1) ==> (IPsec server @ 172.16.0.2)

I'm forwarding UDP traffics to ports 4500/500 to the server, as well as the ESP protocol using these 'port forwarding' rules (although ESP is a protocol and hence not a port forward):

config redirect
	option name 'VPN ESP'
	option dest_ip '172.16.0.2'
	option target 'DNAT'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'

config redirect
	option target 'DNAT'
	option src 'wan'
	option dest 'lan'
	option proto 'udp'
	option src_dport '500'
	option dest_ip '172.16.0.2'
	option dest_port '500'
	option name 'isakmp'

config redirect
	option target 'DNAT'
	option src 'wan'
	option dest 'lan'
	option proto 'udp'
	option src_dport '4500'
	option dest_ip '172.16.0.2'
	option dest_port '4500'
	option name 'ipsec-nat-t'

For my IPSec server, I've used these Digitalocean instructions, which worked on my previous router.

I can connect to the IPSec (on my iOS client), and even reach the webserver on the server (172.16.0.2). However, no other traffic gets through.

I've also tried adapting these instructions and other, but to no avail. Also I tried following this strongswan instruction:

iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j  ACCEPT

but I'm not sure if this refers to the IPSec firewall or the router firewall. In any case it doesn't work ;(

I think it has to do with ESP traffic not being handled properly, but I don't know how to fix this. Does anyone know how this should work?


#2

First off, for reference, let me refer you to the index for some of OpenWrt's various VPN options:

https://openwrt.org/docs/guide-user/services/vpn/overview

And as far as the iptables rules, it looks like you might need a few more, added to your firewall.user file on the OpenWrt router:

iptables -I INPUT  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir in --pol ipsec --proto esp -j ACCEPT
iptables -I FORWARD  -m policy --dir out --pol ipsec --proto esp -j ACCEPT
iptables -I OUTPUT   -m policy --dir out --pol ipsec --proto esp -j ACCEPT

#3

Thanks for the quick reply @dit_dah_dit, however unfortunately adding those rules does not help.

The instructions you refer to are for VPN servers running on top of OpenWRT, while I have a server behind it. I think this means I need to NAT or Masquerade the VPN traffic, right?


#4

Yes, but your WAN is already doing both, isn't it? It should by default. And since you are using Destination NAT for your redirect rules, that too means that you are using NAT for the VPN traffic.


#5

Yes, my WAN (or my router) is already NAT'ing traffic from inside to outside, however now I have traffic coming in from road warrior VPN clients connecting from WAN to the VPN server behind the router.

I don't see how the article you pointed to would help since in that case the VPN traffic stops at the router and doesn't need NAT'ing / masquerading to get to the VPN server behind the router.

Does this make sense? I hope I can still get it to work.


#6

The article was just to show you where I got those iptables rules from. The more useful link in my opinion would be the index of resources.

Since you are running a VPN server independent of the router, your real goal is to forward all packets related to VPN from the WAN interface to the VPN server.

Have you tried redirecting all traffic on ports 500 and 4500 to the server? Maybe also redirect all proto esp to the server?


#7

The rules using policy matching won't be useful for IPsec passthrough anyway. They only match if you are running IPsec on the OpenWrt router.

Have you checked the packet counters on the rules that you inserted using the redirect configuration? And have you tried running tcpdump on the router on the wan and lan interfaces to check if the traffic is forwarded?


#8

Hi dit_dah_dit & mikma, thanks for your ideas. When running tcpdump on the VPN server in promiscuous mode the VPN works, running tcpdump -p (=no promiscuous mode) breaks the VPN again.

I'm using forceencaps such that I don't need to worry about ESP traffic (protocol 50), this is encapsulated in UDP so I only need to forward ports 500 and 4500. See rules isakmp and ipsec-nat-t in my original post.

Below excerpts from tcpdump running in promiscuous mode and not. It seems the VPNServer is not receiving data targeted at the VPN client because the IP is 'wrong'. I'm a bit puzzled why this worked before with a different router. I have two ideas:

  1. The Router should also NAT the IP of the packets destined for VPN clients located 'behind' the VPN server. Is this correct?
  2. The VPN Server should accept packets from all its VPN client IPs. Why does strongswan not add this automatically?

Any ideas how I can fix my routing firewall to NAT the packets, or have my VPN server accept packets with other IPs? Thanks in advance!

tcpdump - not in promiscuous mode running on VPNServerIP

tim.lan = VPN road warrior client located in WAN

11:19:41.872106 IP WanIP.64739 > VPNServerIP.ipsec-nat-t: UDP-encap: ESP(spi=0xca6d6073,seq=0x20), length 104
11:19:41.872289 IP tim.lan.54871 > RouterIP.domain: 23559+ A? vid.nl. (24)
11:19:41.872359 IP tim.lan.54871 > RouterIP.domain: 23559+ A? vid.nl. (24)
11:19:42.031138 IP WanIP.64739 > VPNServerIP.ipsec-nat-t: UDP-encap: ESP(spi=0xca6d6073,seq=0x21), length 120
11:19:42.031314 IP tim.lan.56054 > RouterIP.domain: 21458+ A? gateway.icloud.com. (36)
11:19:42.031388 IP tim.lan.56054 > RouterIP.domain: 21458+ A? gateway.icloud.com. (36)
11:19:43.882271 IP WanIP.64739 > VPNServerIP.ipsec-nat-t: UDP-encap: ESP(spi=0xca6d6073,seq=0x22), length 104
11:19:43.882555 IP tim.lan.54871 > RouterIP.domain: 23559+ A? vid.nl. (24)
11:19:43.882640 IP tim.lan.54871 > RouterIP.domain: 23559+ A? vid.nl. (24)
...etc

tcpdump in promiscuous mode running on VPNServerIP

172.16.0.233 = VPN road warrior client located in WAN

11:26:21.487744 IP WanIP.64739 > VPNServerIP.ipsec-nat-t: UDP-encap: ESP(spi=0xcef8561d,seq=0x5), length 104
11:26:21.487929 IP 172.16.0.233.55526 > RouterIP.domain: 56277+ A? tweakers.net. (30)
11:26:21.487995 IP 172.16.0.233.55526 > RouterIP.domain: 56277+ A? tweakers.net. (30)
11:26:21.491147 IP RouterIP.domain > 172.16.0.233.55526: 56277 1/0/0 A 213.239.154.31 (46)
11:26:21.491234 IP VPNServerIP > RouterIP: ICMP redirect 172.16.0.233 to host RouterIP, length 82
11:26:21.491338 IP VPNServerIP.ipsec-nat-t > WanIP.64739: UDP-encap: ESP(spi=0x0bc256f0,seq=0x5), length 120
11:26:21.659224 IP WanIP.64739 > VPNServerIP.ipsec-nat-t: UDP-encap: ESP(spi=0xcef8561d,seq=0x6), length 120
11:26:21.659363 IP 172.16.0.233.51070 > tweakers.net.https: Flags [S], seq 4155390379, win 65535, options [mss 1360,nop,wscale 7,nop,nop,TS val 597880919 ecr 0,sackOK,eol], length 0
11:26:21.659438 IP 172.16.0.233.51070 > tweakers.net.https: Flags [S], seq 4155390379, win 65535, options [mss 1360,nop,wscale 7,nop,nop,TS val 597880919 ecr 0,sackOK,eol], length 0
11:26:21.659766 IP VPNServerIP.59088 > RouterIP.domain: 63783+ PTR? 31.154.239.213.in-addr.arpa. (45)
11:26:21.667005 IP RouterIP.domain > VPNServerIP.59088: 63783 1/0/0 PTR tweakers.net. (71)
11:26:21.672884 IP tweakers.net.https > 172.16.0.233.51070: Flags [S.], seq 978669927, ack 4155390380, win 28960, options [mss 1460,sackOK,TS val 2841061320 ecr 597880919,nop,wscale 7], length 0

#9

I wonder why there is an icmp redirect? Is it caused by using promiscuous mode or does it indicate an underlying problem with routing?

I'm not sure there us a good idea having the VPN clients in the same LAN subnet. Is Proxy ARP needed on the VPN server in this case, many it's used automatically by strongswan?


#10

I don't know. I've tested a bit further, and the working depend on the router IP and VPN leases. If the subnets don't overlap, it never works, else it only works in promiscuous mode. Shouldn't the VPN server masquerade the traffic and make it seem it's coming from the VPN server instead of the VPN client IP?

Depending on the Router IP and VPN client leases (rightsourceip in ipsec.conf) the VPN works or not:

Router IP 172.16.0.1/24

  1. Lease to 172.16.1.0/16: does not work (either promiscuous or not)
  2. Lease to 172.16.1.0/24: does not work (either promiscuous or not)
  3. Lease to 172.16.0.0/24: works ONLY in promiscuous mode

Router IP 172.16.0.1/16

  1. Lease to 172.16.1.0/24: works ONLY in promiscuous mode

I also came across this thread where I tried using route_via_internal = yes, but this also doesn't help...


#11

That's one solution, but I think it's better to avoid rewriting addresses when possible.

That combination should be avoided since the network overlaps and the VPN network use a longer
prefix.

This should work but requires that you configure a static route to 172.16.0.0/24 with the VPN server as gateway on your router.

This is the preferred solution in my opinion, if it's possible. (Not all routers allow you to configure static routes, and sometimes you want VPN clients to have addresses within the LAN network.)

This should probably also work if you avoid IP conflicts. But it requires the farp plugin in Strongswan, since your router and other devices will send ARP asking for who has a 172.16.0.x address since the address is within the LAN subnet.

https://wiki.strongswan.org/projects/strongswan/wiki/FARPPlugin

This should probably also work since the VPN network is a subnet of the LAN, but also requires the farp plugin as above.


#12

Thanks for the suggestions. I found my mistake, it turns out it was a user error after all: three iptables rules that masquerade the VPN traffic I had were attached to eth0, but when I changed the router I also changed the connection from wired (eth0) to wireless (wlan0). Apologies for the confusion... :grimacing:

The issue was never with the OpenWRT router, but with the server all along. I believe your (mikma's) solution should also work, where the traffic is not masqueraded but is part of the 'regular' LAN traffic with it's own IPs. This is more elegant, but outside my scope for today... The only thing I don't understand is why it was working in promiscuous mode when VPN and LAN subnets overlapped, but I've already wasted too much time on this to figure this out :stuck_out_tongue:.

The tcpdump now looks as follows:

22:53:02.685577 IP WanIP.64719 > VPNServerIP.ipsec-nat-t: UDP-encap: ESP(spi=0xc3a1173a,seq=0x5), length 104
22:53:02.685832 IP 172.16.1.1.51189 > RouterIP.domain: 26232+ A? tweakers.net. (30)
22:53:02.685938 IP VPNServerIP.51189 > RouterIP.domain: 26232+ A? tweakers.net. (30)
22:53:02.688932 IP RouterIP.domain > VPNServerIP.51189: 26232 1/0/0 A 213.239.154.31 (46)

where the second and third line show the masquerading at work.