Example: XFRM interfaces with VRF-based multitenant IPsec
This example configures a multitenant IPsec setup:
- use strongSwan for IPsec setup
- use VLAN subinterfaces for inside VRF access
- XFRM interfaces to connect IPsec tunnels with the VRFs (requires Linux kernel 4.19+)
ifstate
interfaces:
# external interface for IPsec termination
- name: outside
addresses:
- 198.51.100.2/31
link:
state: up
kind: physical
address: 00:50:56:ad:db:ac
# inside base interface
- name: trunk
link:
kind: physical
address: 8c:16:45:dc:b1:ad
state: up
# first tenant VRF
- name: vrf-tenant1
addresses: []
link:
state: up
kind: vrf
vrf_table: 101
- name: ipsec-tenant1
addresses: []
link:
state: up
kind: xfrm
xfrm_link: outside
xfrm_if_id: 1
master: vrf-tenant1
- name: inside-tenant1
addresses:
- 192.0.2.1/24
link:
state: up
kind: vlan
link: trunk
vlan_id: 41
master: vrf-tenant1
# second tenant VRF
- name: vrf-tenant2
addresses: []
link:
state: up
kind: vrf
vrf_table: 102
- name: ipsec-tenant2
addresses: []
link:
state: up
kind: xfrm
xfrm_link: outside
xfrm_if_id: 2
master: vrf-tenant2
- name: inside-tenant2
addresses:
- 192.0.2.1/24
link:
state: up
kind: vlan
link: trunk
vlan_id: 42
master: vrf-tenant2
routing:
routes:
# outside default route
- to: 0.0.0.0/0
via: 198.51.100.1
# first tenant VRF: add default route into vpn
- to: 0.0.0.0/0
dev: ipsec-tenant1
table: 101
# second tenant VRF: add default route into vpn
- to: 0.0.0.0/0
dev: ipsec-tenant2
table: 102
strongSwan
To make strongSwan VRF aware you must use swanctl.
It is not possible to use the classic ipsec.conf
with XFRM interfaces. A swanctl configuration might look like:
#
# IPsec tunnel for tenant1
#
connections {
# Section for an IKE connection named <conn>.
tentant1 {
# IKE major version to use for connection.
version = 2
# Local address(es) to use for IKE communication, comma separated.
local_addrs = 198.51.100.2
# Remote address(es) to use for IKE communication, comma separated.
remote_addrs = 203.0.113.1
# Default inbound XFRM interface ID for children.
if_id_in = 1
# Default outbound XFRM interface ID for children.
if_id_out = 1
# Section for a local authentication round.
local {
auth = psk
}
# Section for a remote authentication round.
remote {
auth = psk
}
children {
# CHILD_SA configuration sub-section.
tenant1 {
# Local traffic selectors to include in CHILD_SA.
local_ts = 192.0.2.0/24
# Remote selectors to include in CHILD_SA.
remote_ts = 0.0.0.0/0
}
}
}
}
#
# IPsec tunnel for tenant2
#
connections {
# Section for an IKE connection named <conn>.
tentant2 {
# IKE major version to use for connection.
version = 2
# Local address(es) to use for IKE communication, comma separated.
local_addrs = 198.51.100.2
# Remote address(es) to use for IKE communication, comma separated.
remote_addrs = 203.0.113.1
# Default inbound XFRM interface ID for children.
if_id_in = 2
# Default outbound XFRM interface ID for children.
if_id_out = 2
# Section for a local authentication round.
local {
auth = psk
}
# Section for a remote authentication round.
remote {
auth = psk
}
children {
# CHILD_SA configuration sub-section.
tenant1 {
# Local traffic selectors to include in CHILD_SA.
local_ts = 192.0.2.0/24
# Remote selectors to include in CHILD_SA.
remote_ts = 0.0.0.0/0
}
}
}
}