[Solved] How to create VTI interface for IPsec Site-To-Site in OpenWrt?

Thanks for the video. Then I apologize.

However, your VTI guide does not work with my VPN provider.

I only get RX packets.

Please don't apologise just share my youtube video.

Install these packages for vti
opkg update && opkg install strongswan-full ip-full kmod-ip-vti vtiv4
Please share your configs so that we can try to solve your issue.
Is your pure IPsec established ? if yes then send snap of ipsec statusall.
Please make a document and send the following.

  1. /etc/strongswan.conf
  2. /etc/ipsec.conf
  3. /etc/ipsec.secret
  4. VTI config commands
  5. /etc/config/network
  6. /etc/config/firewall

opkg update && opkg install strongswan-full ip-full kmod-ip-vti vtiv4 are installed.

  1. /etc/strongswan.conf
# strongswan.conf - strongSwan configuration file
#
# Refer to the strongswan.conf(5) manpage for details
#
# Configuration changes should be made in the included files

charon {
	install_routes=no
	install_virtual_ip=no

	load_modular = yes
	plugins {
		include strongswan.d/charon/*.conf
	}
}

include strongswan.d/*.conf
  1. /etc/ipsec.conf
config setup
	charondebug="all"
	uniqueids=never

conn lan-passthrough
        leftsubnet=192.168.1.0/24 # Replace with your LAN subnet
        rightsubnet=192.168.1.0/24 # Replace with your LAN subnet
        authby=never # No authentication necessary
        type=pass # passthrough
        auto=route # no need to ipsec up lan-passthrough

conn PP
	eap_identity="username"
	type=tunnel
	mobike=no
	keyexchange=ikev2
	keyingtries=%forever
	dpdaction=restart
	closeaction=restart
	dpddelay=300s
	inactivity=36000s
	rekey=no
	forceencaps=yes
	authby=secret
	ike=aes256-sha256-modp2048
	esp=aes256-sha256
	leftfirewall=yes
	left=192.168.1.1
	leftid=192.168.1.1
	leftsubnet=10.0.0.0/8
	leftsourceip=%config4
	leftsendcert=never
	leftauth=eap-mschapv2
	rightfirewall=yes
	rightauth=pubkey
	right=37.48.94.1
	rightid=%any
	rightsubnet=0.0.0.0/0
	rightsendcert=always
	leftikeport=4500
	rightikeport=4500
	mark_in=42
	mark_out=42
	auto=add
  1. /etc/ipsec.secret
# /etc/ipsec.secrets - strongSwan IPsec secrets file

username : EAP "password"
  1. /etc/config/network
config interface 'ipsec'
	option ifname 'vti0'
	option proto 'static'
	option ipaddr '10.0.0.0'
	option netmask '255.0.0.0'

config route
	option target '10.0.0.0'
	option netmask '255.0.0.0'
	option interface 'ipsec'
  1. /etc/config/firewall
config rule
        option src 'wan'
        option name 'IPSec ESP'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option src 'wan'
        option name 'IPSec IKE'
        option proto 'udp'
        option dest_port '500'
        option target 'ACCEPT'

config rule
        option src 'wan'
        option name 'IPSec NAT-T'
        option proto 'udp'
        option dest_port '4500'
        option target 'ACCEPT'

config rule
        option src 'wan'
        option name 'Auth Header'
        option proto 'ah'
        option target 'ACCEPT'

config include
	option path '/etc/firewall.user'

config zone
	option network 'ipsec'
	option name 'PP_FW'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option masq '1'

config forwarding
	option dest 'PP_FW'
	option src 'lan'
  1. /etc/firewall.user
# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

# Internal uci firewall chains are flushed and recreated on reload, so
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.

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
  1. /etc/ipsec.d/cacerts/ppcrt.crt

  2. /etc/ipsec.user

# This file is interpreted as shell script.
# Put your custom ip rules here, they will
# be executed with each call to the script
# /usr/lib/ipsec/_updown which by default
# strongswan executes.

# Force it to use vti0
VTI_IF="vti0"

# Private subnet
PRIVATE_SUBNET="192.168.1.0/24"

LOCAL_IF="${PLUTO_INTERFACE}"

# GCP's MTU is 1460, so it's hardcoded
GCP_MTU="1460"

# ipsec overhead is 73 bytes, we need to compute new mtu.
VTI_MTU=$((GCP_MTU-73))

case "${PLUTO_VERB}" in
up-client)
	iptables -t nat -A postrouting_wan_rule -s "${PRIVATE_SUBNET}" -m policy --dir out --pol none -j SNAT --to-source "${PLUTO_MY_SOURCEIP4_1}"
	ip tunnel add "${VTI_IF}" local "${PLUTO_ME}" remote "${PLUTO_PEER}" mode vti okey "${PLUTO_MARK_OUT%%/*}" ikey "${PLUTO_MARK_IN%%/*}"
	ip link set "${VTI_IF}" up mtu "${VTI_MTU}"
	ip route add "${PRIVATE_SUBNET}" dev "${VTI_IF}"
	# Disable policy checks for this interface, otherwise the Kernel will drop the traffic after decryption.
	sysctl -w "net.ipv4.conf.${VTI_IF}.disable_policy=1"
	# Disable RP filter for the tunnel interface
	sysctl -w "net.ipv4.conf.${VTI_IF}.rp_filter=0"
	;;
down-client)
	iptables -t nat -F postrouting_wan_rule
	ip tunnel del "${VTI_IF}"
	;;
esac

# Disable IPSEC Encryption on local net
sysctl -w "net.ipv4.conf.${LOCAL_IF}.disable_policy=1"
  1. after "ipsec up PP", command "ipsec statusall":
root@OpenWrt:~# ipsec statusall
Status of IKE charon daemon (strongSwan 5.8.2, Linux 4.14.180, armv7l):
  uptime: 12 minutes, since Jul 25 12:35:36 2020
  worker threads: 10 of 16 idle, 6/0/0/0 working, job queue: 0/0/0/0, scheduled: 3
  loaded plugins: charon test-vectors ldap pkcs11 aes des blowfish rc2 sha2 sha1 md4 md5 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl gcrypt af-alg fips-prf gmp curve25519 agent xcbc cmac hmac ctr ccm gcm curl mysql sqlite attr kernel-netlink resolve socket-default connmark forecast farp stroke vici smp updown eap-identity eap-md5 eap-mschapv2 eap-radius eap-tls xauth-generic xauth-eap dhcp whitelist led duplicheck addrblock unity
Listening IP addresses:
  192.168.1.1
  2a02:908:3033:d220::1
  fd32:998d:b371::1
  62.143.72.48
  2a02:908:3000:3:3081:5087:204:43e7
  10.0.0.0
Connections:
lan-passthrough:  %any...%any  IKEv1/2
lan-passthrough:   local:  uses public key authentication
lan-passthrough:   remote: uses public key authentication
lan-passthrough:   child:  192.168.1.0/24 === 192.168.1.0/24 PASS
          PP:  192.168.1.1...37.48.94.1  IKEv2, dpddelay=300s
          PP:   local:  [192.168.1.1] uses EAP_MSCHAPV2 authentication with EAP identity 'username'
          PP:   remote: uses public key authentication
          PP:   child:  10.0.0.0/8 === 0.0.0.0/0 TUNNEL, dpdaction=restart
Shunted Connections:
lan-passthrough:  192.168.1.0/24 === 192.168.1.0/24 PASS
Security Associations (1 up, 0 connecting):
          PP[1]: ESTABLISHED 12 minutes ago, 192.168.1.1[192.168.1.1]...37.48.94.1[amsterdam.perfect-privacy.com]
          PP[1]: IKEv2 SPIs: 44698868eee6e94d_i* 461eaae120cfef15_r, rekeying disabled
          PP[1]: IKE proposal: AES_GCM_16_256/PRF_HMAC_SHA2_512/CURVE_25519
          PP{1}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: cfadb489_i c88e3c68_o
          PP{1}:  AES_CBC_256/HMAC_SHA2_256_128, 200292 bytes_i, 121833 bytes_o (329 pkts, 102s ago), rekeying disabled
          PP{1}:   10.4.75.35/32 === 0.0.0.0/0

In /etc/strongswan.conf give spaces like this
install_routes = no
install_virtual_ip = no
after saving this file reboot you router and do ipsec restart

I have removed the spaces.
Then saved, rebooted and ipsec restarted.

Same problem.

I told you to give spaces between install_virtual_ip=no like this install_virtual_ip = no in both lines. why you removed the same ?

Oh sorry.

I misunderstood.

I changed it.

# strongswan.conf - strongSwan configuration file
#
# Refer to the strongswan.conf(5) manpage for details
#
# Configuration changes should be made in the included files

charon {
	install_routes = no
	install_virtual_ip = no
	load_modular = yes
	plugins {
		include strongswan.d/charon/*.conf
	}
}

include strongswan.d/*.conf

same problem.

Why are you using '''lan pass through''' ?

I don't know why, but it works without "lan pass through".

I copied it from this thread, because I had difficulties to create a successful connection at that time.

root@OpenWrt:~# ipsec statusall
Status of IKE charon daemon (strongSwan 5.8.2, Linux 4.14.180, armv7l):
  uptime: 22 seconds, since Jul 26 11:57:12 2020
  worker threads: 10 of 16 idle, 6/0/0/0 working, job queue: 0/0/0/0, scheduled: 3
  loaded plugins: charon test-vectors ldap pkcs11 aes des blowfish rc2 sha2 sha1 md4 md5 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl gcrypt af-alg fips-prf gmp curve25519 agent xcbc cmac hmac ctr ccm gcm curl mysql sqlite attr kernel-netlink resolve socket-default connmark forecast farp stroke vici smp updown eap-identity eap-md5 eap-mschapv2 eap-radius eap-tls xauth-generic xauth-eap dhcp whitelist led duplicheck addrblock unity
Listening IP addresses:
  192.168.1.1
  2a02:908:3033:d220::1
  fd32:998d:b371::1
  62.143.72.48
  2a02:908:3000:3:3081:5087:204:43e7
  10.0.0.0
Connections:
          PP:  192.168.1.1...37.48.94.1  IKEv2, dpddelay=300s
          PP:   local:  [192.168.1.1] uses EAP_MSCHAPV2 authentication with EAP identity 'username'
          PP:   remote: uses public key authentication
          PP:   child:  10.0.0.0/8 === 0.0.0.0/0 TUNNEL, dpdaction=restart
Security Associations (1 up, 0 connecting):
          PP[1]: ESTABLISHED 18 seconds ago, 192.168.1.1[192.168.1.1]...37.48.94.1[amsterdam.perfect-privacy.com]
          PP[1]: IKEv2 SPIs: f6d5a356849f7fc0_i* 21e48da76044258e_r, rekeying disabled
          PP[1]: IKE proposal: AES_GCM_16_256/PRF_HMAC_SHA2_512/CURVE_25519
          PP{1}:  INSTALLED, TUNNEL, reqid 1, ESP in UDP SPIs: c96c3203_i cd0e82dd_o
          PP{1}:  AES_CBC_256/HMAC_SHA2_256_128, 0 bytes_i, 0 bytes_o, rekeying disabled
          PP{1}:   10.4.74.154/32 === 0.0.0.0/0

still no TX packts.

You got any routes with table 220? Like with:

ip route show table 220

If I set routes manually, it won't work.

Example:

root@OpenWrt:~# ip route add 192.168.1.0/24 dev vti0
RTNETLINK answers: File exists

root@OpenWrt:~# ip route add 192.168.1.0/24 via 192.168.1.1 dev vti0 table 220
Error: Nexthop has invalid gateway.

After "ipsec up PP":

root@OpenWrt:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         62.143.72.1     0.0.0.0         UG    0      0        0 eth0.2
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 vti0
62.143.72.0     0.0.0.0         255.255.248.0   U     0      0        0 eth0.2
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br-lan

@VincentR Do you have links or documentation on how to create Pseudowire from OpenWRT? If yes please share the same

@Bernd , this is the routing that works for me in ipsec.user (lan to vti0).
It's almost straight from: https://lists.strongswan.org/pipermail/users/2016-July/009829.html

case "${PLUTO_VERB}" in
    up-client)
        ip tunnel add vti0 mode vti local "${PLUTO_ME}" remote "${PLUTO_PEER}" key "${PLUTO_MARK_OUT%%/*}"
        ip link set vti0 up
        ip addr add "${PLUTO_MY_SOURCEIP}" dev vti0
        ip route add 127.0.0.0/8 dev lo table 220
        ip route add default via ${PLUTO_MY_SOURCEIP} dev vti0 table 220
        ip rule add from 10.10.10.0/24 table 220
        sysctl -w "net.ipv4.conf.vti0.disable_policy=1"
        sysctl -w "net.ipv4.conf.vti0.rp_filter=0"
...

I also always keep a route (from /etc/config/network) in that table to send local traffic back:

config route 'local_traffic'
	option interface 'lan'
	option target '10.10.10.0'
	option netmask '255.255.255.0'
	option gateway '0.0.0.0'
	option table '220'

and once connected, it shows up as:

root@OpenWrt:~# ip route show table 220
default via <pluto_source_ip> dev vti0 
10.10.10.0/24 dev br-lan proto static scope link 
127.0.0.0/8 dev lo scope link

root@OpenWrt:~# ip rule
...
219:   from 10.10.10.0/24 lookup 220
...

nope, I've not done anything like that before.

I have changed ipsec.user:

# This file is interpreted as shell script.
# Put your custom ip rules here, they will
# be executed with each call to the script
# /usr/lib/ipsec/_updown which by default
# strongswan executes.

VTI_IF="vti0"
PRIVATE_SUBNET="192.168.1.0/24"

case "${PLUTO_VERB}" in
up-client)
	iptables -t nat -A postrouting_wan_rule -s "${PRIVATE_SUBNET}" -m policy --dir out --pol none -j SNAT --to-source "${PLUTO_MY_SOURCEIP}"
	ip tunnel add "${VTI_IF}" local "${PLUTO_ME}" remote "${PLUTO_PEER}" mode vti key "${PLUTO_MARK_OUT%%/*}"
	ip link set "${VTI_IF}" up
	ip addr add "${PLUTO_MY_SOURCEIP}" dev "${VTI_IF}"
	ip route add 127.0.0.0/8 dev lo table 220
	ip route add default via "${PLUTO_MY_SOURCEIP}" dev "${VTI_IF}" table 220
	ip rule add from "${PRIVATE_SUBNET}" table 220
	sysctl -w "net.ipv4.conf.${VTI_IF}.disable_policy=1"
	sysctl -w "net.ipv4.conf.${VTI_IF}.rp_filter=0"
	;;
down-client)
	iptables -t nat -F postrouting_wan_rule
	ip tunnel del "${VTI_IF}"
	;;
esac

Then I have set static route:

config route 'local_traffic'
	option interface 'lan'
	option target '192.168.1.0'
	option netmask '255.255.255.0'
	option gateway '0.0.0.0'
	option table '220'
root@OpenWrt:~# ip route list table 220
default via 10.4.138.147 dev vti0
127.0.0.0/8 dev lo scope link
192.168.1.0/24 dev br-lan proto static scope link
root@OpenWrt:~# ip rule
0:      from all lookup local
219:    from 192.168.1.0/24 lookup 220
220:    from all lookup 220
32766:  from all lookup main
32767:  from all lookup default

But I did not have an internet connection afterwards.
VTI Interface had no RX and TX packets.

I'd say at this stage, it's likely to be down to your firewall as your interface is up and your routing looks good. I don't really use fw3 so I don't have a config handy but it's similar to an openvpn tunnel at that stage. On the top of my head, I do something like:

  • allow output on all
  • allow input on lan
  • allow forward between lan and vti
  • masquerade and mtu-fix on vti and wan

By temporarily removing your firewall (only do if safe), you can check and see if the routing is correct, maybe see the packets on the interfaces using tcpdump. Something similar to what the video shows i.e. with no firewall. Start from lan to vti to wan. And then narrow down the differences between packets flowing or not as you correct your firewall/iptables.

Also one thing, make sure you have the correct MTU on the VTI interface. A wrong MTU will look like some sites work and some don't.

Hope that helps

Yes, it helped a little.

Have I activated.

I have also temporarily removed my firewall by setting forward to accept in "General Settings".

Yes, that is the case with my configuration.

I have tested different mtu values for the vti interface according to your instructions. I have tested the values between 1200-1500, without success.

Do I also have to set mtu values for wan and lan interface? Like here? If so, how?

I've started from scratch.

@sagar_jain has rightsubnet 172.31.0.0/22.
I have rightsubnet 0.0.0.0/0.

I have specified this above:

config route
	option target '10.0.0.0
	option netmask '255.0.0.0'
	option interface 'ipsec

which I guess was wrong.

If I enter static route 0.0.0.0 and netmask 0.0.0.0, then it does not work.

I have now these settings:

etc/config/network

config route
	option interface 'lan'
	option target '192.168.1.0'
	option netmask '255.255.255.0'
	option gateway '0.0.0.0'
	option table '220'
	option source '192.168.1.1'

82.199.134.161 is the gateway VPN IP.
82.199.134.162 is remote VPN IP or VPN IP on WAN.

When I enter:

ip addr add 82.199.134.161 dev vti0
ip addr add 82.199.134.162 dev vti0
ip route add default via 82.199.134.161 dev vti0 proto static src 82.199.134.162 table 220

then I have:

root@OpenWrt:~# ip route list table 220
default via 82.199.134.161 dev vti0 proto static src 82.199.134.162
192.168.1.0/24 dev br-lan proto static scope link src 192.168.1.1

and some TX errors:

vti0      Link encap:UNSPEC  HWaddr C0-A8-01-01-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.0.0.0  P-t-P:10.0.0.0  Mask:255.0.0.0
          inet6 addr: fe80::5efe:c0a8:101/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP  MTU:1416  Metric:1
          RX packets:251 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:157 dropped:0 overruns:0 carrier:157
          collisions:0 txqueuelen:1000
          RX bytes:56640 (55.3 KiB)  TX bytes:0 (0.0 B)

Is routing table 220 even ok?
Anyone else have any idea what I can do?

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.