StrongSwan VPN tunnel

So you can't establish child SA, what's the error log?

My own vpn setup is based on swanctl and xfrm, but I tried ipsec.conf and vti on virtual machine with conf below, it just worked.

conn test
	left=myLocal
	leftid=myLocalID
	leftsubnet=myLocalSubnet
	right=myRemote
	rightid=myRemoteID
	rightsubnet=0.0.0.0/0
	type=tunnel
	auto=add
	keyexchange=ikev2
	authby=secret
	ike=aes256-sha256-modp2048
	esp=aes256-sha256
	mark_in=32
	mark_out=42

I actually can. Its established and workng.

swanvpn    | 14[NET] received packet: from 92.255.**.**[500] to 172.18.0.3[500] (320 bytes)
swanvpn    | 14[ENC] parsed IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(REDIR_SUP) ]
swanvpn    | 14[IKE] 92.255..**.** is initiating an IKE_SA
swanvpn    | 14[CFG] selected proposal: IKE:AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
swanvpn    | 14[IKE] local host is behind NAT, sending keep alives
swanvpn    | 14[IKE] remote host is behind NAT
swanvpn    | 14[ENC] generating IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(CHDLESS_SUP) N(MULT_AUTH) V ]
swanvpn    | 14[NET] sending packet: from 172.18.0.3[500] to 92.255.**.**[500] (348 bytes)
swanvpn    | 15[NET] received packet: from 172.18.0.1[54786] to 172.18.0.3[4500] (300 bytes)
swanvpn    | 15[ENC] parsed IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(ADD_4_ADDR) N(ADD_4_ADDR) N(ADD_6_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
swanvpn    | 15[CFG] looking for peer configs matching 172.18.0.3[3.8..**.**]...172.18.0.1[192.168.0.137]
swanvpn    | 15[CFG] selected peer config 'wrt-psk'
swanvpn    | 15[IKE] authentication of '192.168.0.137' with pre-shared key successful
swanvpn    | 15[IKE] peer supports MOBIKE
swanvpn    | 15[IKE] authentication of '3.8.**.**' (myself) with pre-shared key
swanvpn    | 15[IKE] IKE_SA wrt-psk[1] established between 172.18.0.3[3.8.**.**]...172.18.0.1[192.168.0.137]
swanvpn    | 15[IKE] scheduling reauthentication in 28106s
swanvpn    | 15[IKE] maximum IKE_SA lifetime 28646s
swanvpn    | 15[CFG] selected proposal: ESP:AES_CBC_256/HMAC_SHA1_96/NO_EXT_SEQ
swanvpn    | 15[IKE] CHILD_SA wrt-psk{1} established with SPIs cea7f207_i c09b07bc_o and TS 0.0.0.0/0 === 10.10.10.10/32
swanvpn    | 15[ENC] generating IKE_AUTH response 1 [ IDr AUTH CPRP(DNS DNS) SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) ]
swanvpn    | 15[NET] sending packet: from 172.18.0.3[4500] to 172.18.0.1[54786] (236 bytes)
swanvpn    | 09[IKE] sending keep alive to 172.18.0.1[54786]

Regarding kmod crypto gcm, I was installing it this whole time. Without it authentication was failing.

I can even reach other websites using ping command thru vti.

--- yandex.ru ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 119.517/123.245/129.634 ms
root@OpenWrt:~# ^C
root@OpenWrt:~# test
root@OpenWrt:~# ping -I vti1 yandex.ru
PING yandex.ru (5.255.255.55): 56 data bytes
64 bytes from 5.255.255.55: seq=0 ttl=41 time=118.496 ms
64 bytes from 5.255.255.55: seq=1 ttl=41 time=118.665 ms
64 bytes from 5.255.255.55: seq=2 ttl=41 time=118.245 ms
64 bytes from 5.255.255.55: seq=3 ttl=41 time=118.429 ms
^C
--- yandex.ru ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 118.245/118.458/118.665 ms
root@OpenWrt:~# ping -I vti1 google.com
PING google.com (74.125.131.113): 56 data bytes
64 bytes from 74.125.131.113: seq=0 ttl=46 time=111.565 ms
64 bytes from 74.125.131.113: seq=1 ttl=46 time=104.723 ms
64 bytes from 74.125.131.113: seq=2 ttl=46 time=104.720 ms
64 bytes from 74.125.131.113: seq=3 ttl=46 time=104.767 ms
^C
--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 104.720/106.443/111.565 ms
root@OpenWrt:~# ping -I vti1 youtube.com
PING youtube.com (64.233.164.190): 56 data bytes
64 bytes from 64.233.164.190: seq=0 ttl=46 time=103.915 ms
64 bytes from 64.233.164.190: seq=1 ttl=46 time=103.726 ms
64 bytes from 64.233.164.190: seq=2 ttl=46 time=103.717 ms
64 bytes from 64.233.164.190: seq=3 ttl=46 time=103.654 ms
^C
--- youtube.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 103.654/103.753/103.915 ms

I'am sure that strongswan tunnel is configured correctly.
I think i keep messing up either routing or interface.

VPN interface in LuCi is set to 10.10.10.10 netmask 255.255.255.255 == leftsubnet in ipsec.conf(10.10.10.10/32), attached to VPN_ZONE firewall zone.

As soon as I add static route to 0.0.0.0 netmask 0.0.0.0 thru VPN interface my connection is dead.
ip a gives me no route on packets...
I am afraid that I'am missing the most basic, stupidest thing. Everything works by itself but fails when put together.

Holy cow. I tried to route specific websites...and it worked...
I routed https://portchecker.co/ thru vpn, and it gives me my server's ip, which is exactly what i needed:
ip and domain bases split-tunnel on router.

I have only one question:
If split-tunneling does work, why all traffic failed?

Do you have static route to server ip before adding default route? OpenWrt need to know how to reach server, otherwise it would get in a loop. Also you can add 0.0.0.0/1 and 128.0.0.0/1 route to vpn interface in order to avoid conflict with existing default route.

what does /1 in this context imply? I don't get it.

I think i did not. And now when you mention that it does make sense.
That explains "no route" packet errors.

cwbsw, thank you very much for your knowlege and help!
I couldn't do all this by myself.

I don't really need to forward all traffic, it would cost thousands of dollars in traffic fees on AWS.
I actually need to route specific IP's. Automating it with script would be a trivial task, now that i know that i can forward specific IP adresses.

All that is left is to make vti device persist between reboots. There should be either a flag or i can use script. And find a way to use FQDN as 'remote' part of vti instead of IP.

It just means first bit of binary ip address, I learned about this from:

@cwbsw
Hello again!
Sorry for necropostiong.

I've read a lot of articles and figured out how routing works! I've even managed to setup eltex commutator.
Thank you for all the articles and help.

I just have one last question.

Everything we've discussed above works, I've automated everything with scripts, its working fine.
Except i accidentaly broke site-to-site tunnel, and i can't understand where.

I have two vti tunnels with 10.10.10.N (for accessing restricted sites. Will call it 'VPN') and 10.11.10.N (For site-to-site tunnel to another server. Will call it 'WinTunnel'), where N - is specific to OpenWrt device on different locations. N = 1 for my dev environment at office.

VPN is connected to AWS loadbalancer with fleet of servers behind.
WinTunnel is connected to specific server, which acts as Firewall\AccessPoint to my dev WinServer with ActiveDirectory(hence, WinTunnel).

Schema is as follows:

OpenWrt_1 has subnet 192.168.10.0/24
OpenWrt_2 has subnet 192.168.1.0/24

I have route on OpenWrt_2 to 192.168.10.0/24 subnet and can reach every machine behind OpenWrt_1 from it.
My VPN-Services are installed on OpenWrt_1.

Both tunnels are up and established, no error logs on router\servers.

I can ping my WinServer from OpenWrt_1, but cant reach it from my PC.( 192.168.10.1 node unavailable )
I don't have to setup specific routes on my PC, beacuse route to 172.31.0.0/20 is set on OpenWrt_1, which is my default gateway anyways.

OpenWrt_1
ipsec.conf

config setup
    strictcrlpolicy=no
    uniqueids=never
    cachecrls=no

conn swanvpn
  type=tunnel
  auto=start
  keyexchange=ikev2
  authby=secret
  leftsubnet=10.10.10.1/32
  leftid=OfficeVPN
  left=192.168.1.230
  right=****
  rightid=vpn.***.com
  rightsubnet=0.0.0.0/0
  ike=aes256-sha1-modp1024!
  esp=aes256-sha1!
  aggressive=no
  keyingtries=%forever
  ikelifetime=28800s
  lifetime=86400s
  dpddelay=10s
  dpdtimeout=30s
  dpdaction=restart
  mark_in=32
  mark_out=42
  forceencaps=yes
  mobike=yes

conn wintunnel
  type=tunnel
  auto=start
  keyexchange=ikev2
  authby=secret
  leftsubnet=10.11.10.1/32
  left=192.168.1.230
  leftid=OfficeVPN
  right=****
  rightsubnet=172.31.0.0/20
  ike=aes256-sha1-modp1024!
  esp=aes256-sha1!
  aggressive=no
  keyingtries=%forever
  ikelifetime=28800s
  lifetime=86400s
  dpddelay=10s
  dpdtimeout=30s
  dpdaction=restart
  mark_in=33
  mark_out=43
  forceencaps=yes
  mobike=yes

ip r show

default via 192.168.1.1 dev eth0.2 proto static src 192.168.1.230
172.31.0.0/20 dev vti2 scope link
192.168.1.0/24 dev eth0.2 proto kernel scope link src 192.168.1.230
192.168.10.0/24 dev br-lan proto kernel scope link src 192.168.10.1

ipsec statusall

Status of IKE charon daemon (strongSwan 5.9.2, Linux 5.4.188, mips):
  uptime: 4 minutes, since Aug 16 09:27:31 2022
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 10
  loaded plugins: charon aes sha1 random nonce x509 pubkey gmp xcbc hmac kernel-netlink socket-default stroke updown
Listening IP addresses:
  10.11.10.1
  192.168.10.1
  fd12:b857:5201:4::1
  fd24:28f8:e06c::1
  192.168.1.230
  fd12:b857:5201:0:da07:b6ff:fed3:9e50
  fd12:b857:5201::230
Connections:
     swanvpn:  192.168.1.230...16.170.**.** IKEv2, dpddelay=10s
     swanvpn:   local:  [OfficeVPN] uses pre-shared key authentication
     swanvpn:   remote: [vpn.cloudcrmweb.com] uses pre-shared key authentication
     swanvpn:   child:  10.10.10.1/32 === 0.0.0.0/0 TUNNEL, dpdaction=restart
   wintunnel:  192.168.1.230...3.8.**.**  IKEv2, dpddelay=10s
   wintunnel:   local:  [OfficeVPN] uses pre-shared key authentication
   wintunnel:   remote: [3.8.**.**] uses pre-shared key authentication
   wintunnel:   child:  10.11.10.1/32 === 172.31.0.0/20 TUNNEL, dpdaction=restart
Security Associations (2 up, 0 connecting):
   wintunnel[2]: ESTABLISHED 4 minutes ago, 192.168.1.230[OfficeVPN]...3.8.**.**[3.8.**.**]
   wintunnel[2]: IKEv2 SPIs: 7b2a9c03564034da_i* 180f927c6d1dd22e_r, pre-shared key reauthentication in 7 hours
   wintunnel[2]: IKE proposal: AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
   wintunnel{2}:  INSTALLED, TUNNEL, reqid 2, ESP in UDP SPIs: c012c6a3_i c825b56e_o
   wintunnel{2}:  AES_CBC_256/HMAC_SHA1_96, 168 bytes_i (2 pkts, 228s ago), 320 bytes_o (6 pkts, 109s ago), rekeying in 23 hours
   wintunnel{2}:   10.11.10.1/32 === 172.31.0.0/20
     swanvpn[1]: ESTABLISHED 4 minutes ago, 192.168.1.230[OfficeVPN]...16.170.**.**[vpn.***.com]
     swanvpn[1]: IKEv2 SPIs: 82e34ce0545eed81_i* b733c622c29ebe8a_r, pre-shared key reauthentication in 7 hours
     swanvpn[1]: IKE proposal: AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_1024
     swanvpn{1}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: c793299e_i c47eb650_o
     swanvpn{1}:  AES_CBC_256/HMAC_SHA1_96, 61667 bytes_i (398 pkts, 96s ago), 45705 bytes_o (480 pkts, 96s ago), rekeying in 23 hours
     swanvpn{1}:   10.10.10.1/32 === 0.0.0.0/0

uci show firewall

firewall.@defaults[0]=defaults
firewall.@defaults[0].input='ACCEPT'
firewall.@defaults[0].output='ACCEPT'
firewall.@defaults[0].synflood_protect='1'
firewall.@defaults[0].forward='ACCEPT'
firewall.@zone[0]=zone
firewall.@zone[0].name='lan'
firewall.@zone[0].network='lan'
firewall.@zone[0].input='ACCEPT'
firewall.@zone[0].output='ACCEPT'
firewall.@zone[0].forward='ACCEPT'
firewall.@zone[1]=zone
firewall.@zone[1].name='wan'
firewall.@zone[1].network='wan' 'wan6'
firewall.@zone[1].output='ACCEPT'
firewall.@zone[1].masq='1'
firewall.@zone[1].mtu_fix='1'
firewall.@zone[1].forward='ACCEPT'
firewall.@zone[1].input='ACCEPT'
firewall.@forwarding[0]=forwarding
firewall.@forwarding[0].src='lan'
firewall.@forwarding[0].dest='wan'
firewall.@rule[0]=rule
firewall.@rule[0].name='Allow-DHCP-Renew'
firewall.@rule[0].src='wan'
firewall.@rule[0].proto='udp'
firewall.@rule[0].dest_port='68'
firewall.@rule[0].target='ACCEPT'
firewall.@rule[0].family='ipv4'
firewall.@rule[1]=rule
firewall.@rule[1].name='Allow-Ping'
firewall.@rule[1].src='wan'
firewall.@rule[1].proto='icmp'
firewall.@rule[1].icmp_type='echo-request'
firewall.@rule[1].family='ipv4'
firewall.@rule[1].target='ACCEPT'
firewall.@rule[2]=rule
firewall.@rule[2].name='Allow-IGMP'
firewall.@rule[2].src='wan'
firewall.@rule[2].proto='igmp'
firewall.@rule[2].family='ipv4'
firewall.@rule[2].target='ACCEPT'
firewall.@rule[3]=rule
firewall.@rule[3].name='Allow-DHCPv6'
firewall.@rule[3].src='wan'
firewall.@rule[3].proto='udp'
firewall.@rule[3].src_ip='fc00::/6'
firewall.@rule[3].dest_ip='fc00::/6'
firewall.@rule[3].dest_port='546'
firewall.@rule[3].family='ipv6'
firewall.@rule[3].target='ACCEPT'
firewall.@rule[4]=rule
firewall.@rule[4].name='Allow-MLD'
firewall.@rule[4].src='wan'
firewall.@rule[4].proto='icmp'
firewall.@rule[4].src_ip='fe80::/10'
firewall.@rule[4].icmp_type='130/0' '131/0' '132/0' '143/0'
firewall.@rule[4].family='ipv6'
firewall.@rule[4].target='ACCEPT'
firewall.@rule[5]=rule
firewall.@rule[5].name='Allow-ICMPv6-Input'
firewall.@rule[5].src='wan'
firewall.@rule[5].proto='icmp'
firewall.@rule[5].icmp_type='echo-request' 'echo-reply' 'destination-unreachable' 'packet-too-big' 'time-exceeded' 'bad-header' 'unknown-header-type' 'router-solicitation' 'neighbour-solicitation' 'router-advertisement' 'neighbour-advertisement'
firewall.@rule[5].limit='1000/sec'
firewall.@rule[5].family='ipv6'
firewall.@rule[5].target='ACCEPT'
firewall.@rule[6]=rule
firewall.@rule[6].name='Allow-ICMPv6-Forward'
firewall.@rule[6].src='wan'
firewall.@rule[6].dest='*'
firewall.@rule[6].proto='icmp'
firewall.@rule[6].icmp_type='echo-request' 'echo-reply' 'destination-unreachable' 'packet-too-big' 'time-exceeded' 'bad-header' 'unknown-header-type'
firewall.@rule[6].limit='1000/sec'
firewall.@rule[6].family='ipv6'
firewall.@rule[6].target='ACCEPT'
firewall.@rule[7]=rule
firewall.@rule[7].name='Allow-IPSec-ESP'
firewall.@rule[7].src='wan'
firewall.@rule[7].dest='lan'
firewall.@rule[7].proto='esp'
firewall.@rule[7].target='ACCEPT'
firewall.@rule[8]=rule
firewall.@rule[8].name='Allow-ISAKMP'
firewall.@rule[8].src='wan'
firewall.@rule[8].dest='lan'
firewall.@rule[8].dest_port='500'
firewall.@rule[8].proto='udp'
firewall.@rule[8].target='ACCEPT'
firewall.@rule[9]=rule
firewall.@rule[9].name='Support-UDP-Traceroute'
firewall.@rule[9].src='wan'
firewall.@rule[9].dest_port='33434:33689'
firewall.@rule[9].proto='udp'
firewall.@rule[9].family='ipv4'
firewall.@rule[9].target='REJECT'
firewall.@rule[9].enabled='false'
firewall.@include[0]=include
firewall.@include[0].path='/etc/firewall.user'
firewall.@zone[2]=zone
firewall.@zone[2].name='VPN_ZONE'
firewall.@zone[2].forward='ACCEPT'
firewall.@zone[2].input='ACCEPT'
firewall.@zone[2].output='ACCEPT'
firewall.@zone[2].network='VPN'
firewall.@zone[2].masq='1'
firewall.@zone[3]=zone
firewall.@zone[3].name='VPNTUNNEL_ZONE'
firewall.@zone[3].forward='ACCEPT'
firewall.@zone[3].input='ACCEPT'
firewall.@zone[3].output='ACCEPT'
firewall.@zone[3].network='WINTUNNEL'
firewall.@zone[3].masq='1'
firewall.@forwarding[1]=forwarding
firewall.@forwarding[1].src='lan'
firewall.@forwarding[1].dest='VPN_ZONE'
firewall.@forwarding[2]=forwarding
firewall.@forwarding[2].src='VPN_ZONE'
firewall.@forwarding[2].dest='lan'
firewall.@forwarding[3]=forwarding
firewall.@forwarding[3].src='lan'
firewall.@forwarding[3].dest='VPNTUNNEL_ZONE'
firewall.@forwarding[4]=forwarding
firewall.@forwarding[4].src='VPNTUNNEL_ZONE'
firewall.@forwarding[4].dest='lan'
firewall.@forwarding[5]=forwarding
firewall.@forwarding[5].src='wan'
firewall.@forwarding[5].dest='lan'

Ubuntu_Server ipsec.conf

config setup
    charondebug="ike 1, knl 1, cfg 0"
    uniqueids=no

conn win-psk-base
  type=tunnel
  auto=add
  keyexchange=ikev2
  authby=secret
  left=%any
  leftsubnet=172.31.0.0/20
  right=%any
  rightdns=8.8.8.8,8.8.4.4
  ike=aes256-sha1-modp1024!
  esp=aes256-sha1!
  aggressive=no
  keyingtries=%forever
  ikelifetime=28800s
  lifetime=3600s
  dpddelay=30s
  dpdtimeout=120s
  dpdaction=restart
  leftupdown=/etc/ipsec.d/firewall.updown

conn WIN-Office
  also=win-psk-base
  rightsubnet=10.11.10.1/32
  rightid=OfficeVPN

conn WIN-Zinina
  also=win-psk-base
  rightsubnet=10.11.10.2/32
  rightid=ZininaVPN

I know for sure, that i've had both tunnels working at the same time.
I think i've messed things up when i was "standartizing" configs and installation with bash scripts.

I've tried to make route to 172.31.0.0/20 from OpenWrt_2 for testing with

ip r add 172.31.0.0/20 via 192.168.1.230

No success.

I am a little bit stumped.

I've been fighting Strongswan as well the past few days. I don't know how much would apply to what you're doing since I'm using swanctl and an xfrm device.

No matter what scheme, the key to setting up a client to properly redirect the whole Internet seems to be adding a hole punch route so the encrypted packets can reach the server via the real ISP--
<SERVER_IP>/32 via <DEFAULT_GATEWAY> dev <WAN_DEVICE>
Other VPNs such as WIreguard and OpenVPN do this automatically when needed (and even sometimes when not) but I haven't found any feature in Strongswan to automate this. Have you written any scripts to add routes?

1 Like

Thank you for you reply!

I've managed to forward all internet thru vti device successfuly beforehand.
I am currently using OpenWrt strongswan vpn to access this site.
I now have trouble with site-to-site tunnel.

Regarding xfrm and swanctl, they're heavy.
I only have ~1.5mb of free space on our C6 routers.

but I haven't found any feature in Strongswan to automate this. Have you written any scripts to add routes?

I didn't find any way either. Yes, i've automated everyting with scripts. From installation and downloading config files to applying firewall settings, handling disconnects and reboots, split-tunneling routing.

DomainsList.txt - has site names you wish to forward thru vpn.
IPList.txt - has ips you wish to forward thru vpn.

RouteParser.sh

#!/bin/sh

WinSubnet=$(cat /usr/Settings | awk '/WinServSubnet/ {print $2}')

echo " Скачиваем файлы"

rm /usr/tempips.txt
touch /usr/tempips.txt

ip r add 8.8.8.8 dev vti1
ip r add 8.8.4.4 dev vti1

echo "Статика до WinServer"
ip route add $WinSubnet dev vti2

echo "Записываем статичные IP"

filename='/usr/IPList.txt'
n=1
while read line; 
do
  if [[ ${line::1} == "#" ]]
  then
    echo "Not an IP: $line";
  else
    echo "Parsing IP: $line";
    echo $line >> /usr/tempips.txt
  fi
  n=$((n+1))
done < $filename


echo "Парсим домены в IP в 2 прохода"

for i in $(seq 2)
do

  filename='/usr/DomainsList.txt'
  n=1
  while read line; 
  do
    if [[ ${line::1} == "#" || ${line} == "" || ${line} == "8.8.8.8" ]]
    then
      echo "Not a domain: $line";
    else
      echo "Parsing domain: $line";
      nslookup $line 8.8.8.8 |  awk '/^Address / {print $3}' >> /usr/tempips.txt
    fi
    n=$((n+1))
  done < $filename
done

echo "Роутим"

filename='/usr/tempips.txt'
n=1
while read line;
do
  if [[ ${line} == "127.0.0.1" || ${line} == "" || ${line} == "8.8.8.8" ]]
  then
    echo "Wrong IP: $line";
  else
    ip route add $line dev vti1;
    echo "Routing IP: $line";
  fi
  n=$((n+1))
done < $filename

Here is my dumb script, which first routes DNS-server queries (8.8.8.8 and 8.8.4.4) thru vpn(because my ISP redirects "unwanted" dns querries to nowhere,
and then nslookups site IPs, and then routes everything thru vti1. I use vti2 for tunneling to winserver.

I plan on making an article in the future to help others.
For now, bear with untranslated Russian comments.

If you wish to forward all traffic use

FullTunnel.sh

#!/bin/sh
ServerIP=$(cat /usr/Settings | awk '/ServerIP/ {print $2}')
ip route add $ServerIP via 192.168.0.1
ip route add $ServerIP dev eth0.2
ip r add 0.0.0.0/1 dev vti1
ip r add 128.0.0.0/1 dev vti1

where 192.168.0.1 is your gateway, as you've said in your comment.

If you want to automate this script on startup, use services.

Install.sh

touch /etc/init.d/VPN
chmod +x /etc/init.d/VPN

echo "#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org
 
START=99
STOP=99
 
start() {        
echo start
/bin/sh \"/usr/OnReboot.sh\"
}                 
 
stop() {          
echo stop
}

boot() {
/bin/sh \"/usr/OnReboot.sh\"
}
" > /etc/init.d/VPN

/etc/init.d/VPN enable

Hope it helps you!

Thanks for posting those. What I really wanted is to set the gateway on the hole punch route automatically, since this box will be connected to a source of Internet that I don't control, having the gateway hard-coded will break if anything changes upstream.

Here is what I came up with:

# Simplified updown script for StrongSwan which installs routes to direct
# all IPv4 into the VPN tunnel.
# For xfrm interfaces, swanctl only knows the ID number, not the ifname.
#  Therefore the ifname is passed in on the command line.
#  (PLUTO_IF_ID_OUT is the number, there would be some way to look it up.)
OUT_INTERFACE=$1

VPN_LOGGING=1
TAG=vpn-$PLUTO_INTERFACE
FAC_PRIO=local0.notice

# Get the ISP default gateway from existing routing table
DEFAULT_GATEWAY=$(route -n | awk '$1=="0.0.0.0" && $3=="0.0.0.0" {print $2}')
if [ $VPN_LOGGING ]
        then
        logger -t $TAG -p $FAC_PRIO "default gateway is $DEFAULT_GATEWAY"
fi

case $PLUTO_VERB in
        up-client)
                if [ $VPN_LOGGING ]
                then
                        logger -t $TAG -p $FAC_PRIO "installing IP4 forward all to $OUT_INTERFACE IPSec to $PLUTO_PEER"
                fi
                ip route add $PLUTO_PEER via $DEFAULT_GATEWAY
                ip route add 0.0.0.0/1 dev $OUT_INTERFACE
                ip route add 128.0.0.0/1 dev $OUT_INTERFACE
                ;;
        down-client)
                if [ $VPN_LOGGING ]
                then
                        logger -t $TAG -p $FAC_PRIO "removing IP4 forward all to $OUT_INTERFACE IPSec to $PLUTO_PEER"
                fi
                ip route del $PLUTO_PEER via $DEFAULT_GATEWAY
                ip route del 0.0.0.0/1 dev $OUT_INTERFACE
                ip route del 128.0.0.0/1 dev $OUT_INTERFACE
                ;;
esac

It works with xfrm but as noted it is necessary to pass in the name of the xfrm interface with the script call. I think this will mostly work in a starter / vti scenario as well. (I'm running on x86 so I didn't look at memory use at all).

Oh, I'am sorry.
This script is a little bit advanced for me.
Routers with VPN are always installed second in chain, so gateway stays the same.

It works with xfrm but as noted it is necessary to pass in the name of the xfrm interface with the script call.

Huh, I've had same challenge with my windows client on C#. Had to parse interface ID each time VPN-interface is rebuilt.

If i understand correctly, you need an int number before interface name in "ip a"?

Would something like that work for you?

ip a | awk '/vti2/ {print $1}' | head -1

Since an xfrm interface is directly created in /etc/config/network, it has the constant name xfrm0 that I configured for it. swanctl references the interface by its ID number, also a constant, which is configured in swanctl and in the network UCI.

config interface 'xfrm0'
        option ifid '301'
        option tunlink 'wan'
        option mtu '1438'
        option proto 'xfrm'

301 is an arbitrary 32 bit integer, it means nothing other than it has to match the number that swanctl is told to load into the kernel. Thus the matching config in /etc/config/ipsec (which in my install drives swanctl/vici, not the old ipsec/starter system)

        option if_id '301'
        option updown '/etc/swanctl/setroutes.sh xfrm0'

(setroutes.sh being my script above, which I placed in that directory so it will be kept during an upgrade) A big part of the learning curve for strongswan is to realize that the most of the names of things still refer to deprecated parts of the program, so it makes little sense.