Linux: Configure MPLSoDMVPN Part 2: Setup Strongswan ipsec profile
How-To: Linux FRR MPLSoDMVPN Part 2
Thursday 29th May 2025
In Part 1 I configured the GRE tunnel interface and installed the latest version of FRR. Now we need a complementary application for configuring IPSec profiles to be used inside the GRE tunnel interface.
Install Strongswan
At first I thought I could just copy the configuration from VyOS shell, but the confusion started when I couldn’t find any IPSec configuration inside the FRR configuration. It turns out that a separate application is used to configure IPSec profiles.
Not only that, but the application itself, called Strongswan, needs to have a patch applied. How to apply it? Niether the FRR documentation, Strongswan documentation or the patch documentation tells you that. You have to download the patch and the sourcecode with git, patch it with “git apply” and then compile it.
Note: Why isn’t this patch just applied in the main branch? It Seems like the maintainers don’t want to do that for whatever reason.
Step 1: Download Strongswan sourcecode from Github
I’m inside my home directory and logging in as root:
~$ sudo su
~#
I choose the 6.0.1rc1 version:
git clone --branch 6.0.1rc1 https://github.com/strongswan/strongswan.git
Step 2: Download Strongswan patch from Gitlab
git clone https://gitlab.alpinelinux.org/alpine/aports.git
Step 3: Apply the patch
Navigate to the source directory of the Strongswan sourcecode:
~# cd strongswan
Then perform these git apply commands:
~/strongswan# git apply --stat --apply ../aports/main/strongswan/0002-vici-send-certificates-for-ike-sa-events.patch
~/strongswan# git apply --stat --apply ../aports/main/strongswan/0003-vici-add-support-for-individual-sa-state-changes.patch
Note: The other included patches are not relevant and can’t be applied.
Before we can compile the source code, we need to install a bunch of dependencies.
Step 4: Install Dependencies
The dependencies are listed in the file called HACKING located inside the strongswan sourcode directory. All dependencies can thankfully be installed with APT.
~# apt update
~# apt install git gcc pkg-config automake autoconf libtool gettext perl python flex yacc bison gperf
Step 5: Compile the code
Now we can start with the compiling process. To generate the makefile however, you first need to run following script inside the sourcecode directory:
~/strongswan# ./autogen.sh
Then run the configure script with following options:
~/strongswan# ./configure --sysconfdir=/etc --enable-curve25519 --enable-systemd --enable-swanctl --with-systemdsystemunitdir=/lib/systemd/system
Source: https://unix.stackexchange.com/questions/592372/building-strongswan-from-source
Now you should have a makefile so you can go ahead with the compilation:
~/strongswan# make
~/strongswan# make install
Step 6: Verify Installation
Now there should be a service called strongswan.service installed. It may not be active and needs to be manually enabled for the first time.
~# systemctl start strongswan
~# systemctl enable strongswan
~# systemctl status strongswan
Step 7: Configure IPSec profile

The ipsec profile is configured under /etc/swanctl/swanctl.conf
~# nano /etc/swanctl/swanctl.conf
Add this to the bottom of the file. Edit IP addresses and ID’s to reflect your environment:
connections {
dmvpn {
proposals = aes256-sha256-modp2048
version = 2
rekey_time = 28800s
keyingtries = 0
local {
auth = psk
id = @sauna-vm1.bastuklubben.online
}
remote {
auth = psk
}
children {
dmvpn {
esp_proposals = aes256-sha256-modp2048
rekey_time = 3600s
rand_time = 540s
local_ts = dynamic[gre]
remote_ts = dynamic[gre]
mode = transport
dpd_action = clear
close_action = none
start_action = none
}
}
}
}
secrets {
ike-1 {
secret = my-pre-shared-secret
}
}
# Include config snippets
include conf.d/*.conf
Explanations:
The FRR documentation on how to configure Strongswan IPSec profile is obsolete.
This configuration is reverse engineered by inspecting the configuration on VyOS. I only added the FQDN identifier.
The pre-shared key can be used by any remote client.
Step 8: Configure the DMVPN Tunnel endpoints
Hub Configuration
The FRR enabled linux server is the hub router. Only GRE tunnel configuration is included:
~# vtysh
# conf t
interface gre1
description DMVPN Tunnel Interface
ip nhrp authentication password123
ip nhrp holdtime 60
ip nhrp map multicast dynamic
ip nhrp network-id 1
ip nhrp redirect
ip nhrp registration no-unique
ip nhrp shortcut
multicast enable
tunnel protection vici profile dmvpn
tunnel source ens22
Note: Physical interface configuration was covered in part 1.
Spoke Router Configuration
The Spoke router is a Cisco IOS-XE router:
! Physical interface
interface GigabitEthernet0/0/1.3014
description FW-GLOBAL
encapsulation dot1Q 3014
ip address 10.14.255.1 255.255.255.254
ipv6 address FE80::E:2 link-local
ipv6 address 2001:db8:1234:E::2/64
ipv6 nd ra suppress all
!
!
! IPSec Configuration
crypto ikev2 proposal IKEV2-PROPOSAL
encryption aes-cbc-256
integrity sha256
group 14
!
crypto ikev2 policy IKEV2-POLICY
proposal IKEV2-PROPOSAL
!
crypto ikev2 keyring DMVPN-KEYRING
peer DMVPN-PEER
address 0.0.0.0 0.0.0.0
pre-shared-key my-pre-shared-secret
!
crypto ikev2 profile DMVPN-IKE
match identity remote fqdn sauna-vm1.bastuklubben.online
identity local fqdn sauna-ro1.bastuklubben.online
authentication remote pre-share
authentication local pre-share
keyring local DMVPN-KEYRING
dpd 30 5 on-demand
!
crypto ipsec transform-set DMVPN-ESP esp-aes 256 esp-sha256-hmac
mode transport
!
crypto ipsec profile DMVPN
set transform-set DMVPN-ESP
set ikev2-profile DMVPN-IKE
!
!
! GRE Tunnel configuration:
interface Tunnel1
ip address 192.168.1.3 255.255.255.0
no ip redirects
ip mtu 1400
ip nhrp authentication password123
ip nhrp network-id 1
ip nhrp holdtime 60
ip nhrp nhs 192.168.1.1 nbma 10.4.254.41 multicast
ip nhrp redirect
ip tcp adjust-mss 1360
ipv6 mtu 1400
ipv6 tcp adjust-mss 1340
mpls ip
tunnel source GigabitEthernet0/0/1.3014
tunnel mode gre multipoint
tunnel key 1
tunnel path-mtu-discovery
tunnel protection ipsec profile DMVPN
Note: NHRP NBMA address can be configured to be a IPv6 address. Configuration for that will be included in the appendix. I would actually prefer that above IPv4, but FRRs version of NHRP does not support IPv6 as NBMA address yet, even if GREv6 is supported.
Verification
Verification from the Cisco Spoke Router
NHRP status:
SAUNA-RO1#show dmvpn
Legend: Attrb --> S - Static, D - Dynamic, I - Incomplete
N - NATed, L - Local, X - No Socket
T1 - Route Installed, T2 - Nexthop-override, B - BGP
C - CTS Capable, I2 - Temporary
# Ent --> Number of NHRP entries with same NBMA peer
NHS Status: E --> Expecting Replies, R --> Responding, W --> Waiting
UpDn Time --> Up or Down Time for a Tunnel
==========================================================================
Interface: Tunnel1, IPv4 NHRP Details
Type:Spoke, NHRP Peers:2,
# Ent Peer NBMA Addr Peer Tunnel Add State UpDn Tm Attrb
----- --------------- --------------- ----- -------- -----
1 10.4.254.41 192.168.1.1 UP 00:35:16 S
IPSec Status:
SAUNA-RO1#show crypto ikev2 sa
IPv4 Crypto IKEv2 SA
Tunnel-id Local Remote fvrf/ivrf Status
1 10.14.255.1/500 10.4.254.41/500 none/none READY
Encr: AES-CBC, keysize: 256, PRF: SHA256, Hash: SHA256, DH Grp:14,
Auth sign: PSK, Auth verify: PSK
Life/Active Time: 86400/2138 sec
Verification from the Hub FRR Linux Server
IPSec SAs:
~# swanctl --list-sas
dmvpn: #14, ESTABLISHED, IKEv2, a2aa544f97fca79d_i 2ed62710cd0a5ad3_r*
local 'sauna-vm1.bastuklubben.online' @ 10.4.254.41[500]
remote 'sauna-ro1.bastuklubben.online' @ 10.14.255.1[500]
AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
established 106s ago, rekeying in 3312s
dmvpn: #209, reqid 1, INSTALLED, TUNNEL, ESP:AES_CBC-256/HMAC_SHA2_256_128
installed 106s ago, rekeying in 3162s, expires in 3854s
in c58f33c8, 3202 bytes, 32 packets, 0s ago
out 0564f9fd, 1092 bytes, 7 packets, 2s ago
local 10.4.254.41/32[gre]
remote 10.14.255.1/32[gre]
NHRP:
~# vtysh -c "show dmvpn"
Src Dst Flags SAs Identity
10.4.254.41 10.14.255.1 n 1 10.14.255.1
~# vtysh -c "show ip nhrp cache"
Iface Type Protocol NBMA Claimed NBMA Flags Identity
gre1 dynamic 192.168.1.3 10.14.255.1 10.14.255.1 T 10.14.255.1
gre1 local 192.168.1.1 10.4.254.41 10.4.254.41 -
To be continued…
Now we have the DMVPN tunnel setup. Next we need a underlay routing protocol and ldp configuration for the tunnel interface.
Appendix
Configure NHRPv4 with IPv6 NBMA
This is only supported on the Cisco side for the moment.
Cisco Spoke Router:
interface Tunnel1
ip nhrp nhs 192.168.1.1 nbma 2001:DB8:1234:E000::4:1 multicast
ip nhrp nhs 192.168.1.2 nbma 2001:DB8:1234:E000::4:2 multicast
tunnel mode gre multipoint ipv6
FRR Hub Router (not supported)
This is not supported but I will describe where the problem is:
GRE tunnel interface configuration in /etc/network/interfaces works fine:
auto gre1
iface gre1 inet manual
pre-up ip tunnel add $IFACE mode gre6 local 2001:DB8:1234:E000::4:1 remote :: key 1 ttl 64
up ip link set $IFACE up
up ip link set $IFACE mtu 1400
up ip addr add 192.168.1.1/32 dev $IFACE
up ip -6 addr add fc01::e:1/128 dev $IFACE
down ip link set $IFACE down
down ip link set $IFACE down
post-down ip link del $IFACE
Notice that the mode is set to gre6.
The problem is that NHRP neighbors won’t form after that. When trying to configure static NHS to NBMA binding in FRR, you will notice that IPv6 address is not available:
sauna-vm2(config-if)# ip nhrp nhs 192.168.0.1 nbma ?
A.B.C.D IPv4 NBMA address
FQDN Fully qualified domain name for NBMA address(es)
I wonder, how hard can it be to get this supported, when the IPSec profile and GRE tunnel both can be configured to support IPv6 already?