Virtual IP Addresses
IKEv1 and IKEv2 both know the concept of virtual IP addresses. This means that the initiator requests an additional IP address from the responder to use as the inner IPsec tunnel address.
In IKEv1, virtual IPs are exchanged using the ModeConfig
extension. IKEv2 has
full support for virtual IPs in the core standard using CP
Configuration Payloads.
strongSwan currently implements one scenario with IKEv2 configuration payloads, where a virtual IP address is requested by the initiator and one or several IPv4 and/or IPv6 addresses are assigned from multiple pools by the responder.
An alternative approach is possible by the IKEv2 protocol where the responder
would propose virtual IP addresses to the initiator but this is an uncommon
setup and therefore not supported. It is supported for IKEv1, though, with
ModeConfig
in push
mode.
Initiator Configuration
To request an arbitrary virtual IP from the responder the client configures the
following in swanctl.conf
:
IPv4 | IPv6 |
---|---|
|
|
It is possible to request a specific address by setting:
IPv4 | IPv6 |
---|---|
|
|
However the responder may return a different address, or may not return one at all.
To use a specific and static virtual IP (i.e. without exchanging any
configuration payloads) it may simply be added to any local interface (even lo
)
and referenced in the client’s local traffic selector (local_ts
).
Configuring such an IP as in the example above will not have the intended effect
because the IP won’t get installed on the system unless
the server actually assigns that IP to the client with a configuration payload.
The traffic selectors in local_ts
and remote_ts
default to the value
dynamic
. If virtual IPs are used this value gets dynamically replaced by the
received or assigned virtual IP, respectively. Therefore, no local traffic selector
must be configured on the client and no remote traffic selector on the server
when using virtual IPs. This ensures the client’s traffic selector is correctly
narrowed to the assigned virtual IP.
A client may request multiple IP addresses by listing multiple IP addresses in
connections.<conn>.vips
. The main use case is for dual-stack hosts to request
a virtual IP of each address family:
connections.<conn>.vips = 0.0.0.0, ::
Example
DNS servers
VPN clients cannot explicitly request DNS servers via a special DNS option in
swanctl.conf
. But DNS server information received
from the VPN gateway through the IKEv2
CP
or IKEv1
ModeConfig
payloads
are handled for instance by the resolve
plugin
which in turn uses either the resolvconf(8)
utility to add the DNS server
information on the host or write it directly to /etc/resolv.conf
or to an
alternative file specified with the --with-resolve-conf
./configure
directive.
Implementation
On Linux the virtual IP addresses will be installed on the outbound interface by
default. The interface may be changed with the charon.install_virtual_ip_on
option. Source routes will be installed in the routing table configured with
charon.routing_table
in
strongswan.conf
or via the
./configure
option
--with-routing-table
. The source routes force the use of the virtual IP when
sending packets to the subnets defined as remote traffic selector (if the physical
IP were used, the IPsec policies wouldn’t match and the packets wouldn’t get
tunneled).
Responder Configuration
As already documented above, the remote traffic selector remote_ts
defaults
to the value dynamic
. This placeholder gets dynamically replaced by the
virtual IP assigned to a client. Therefore no remote traffic selector must be
configured on the server when using virtual IPs. This ensures the client’s
traffic selector is correctly narrowed to the assigned virtual IP (otherwise,
every client would get the same traffic selector assigned, resulting in conflicting
policies).
To serve a specific IP address (even if the initiator requests a different address) to a single client, the following may be configured:
IPv4 | IPv6 |
---|---|
|
|
|
|
To serve multiple clients, define an address pool in CIDR notation
IPv4 | IPv6 |
---|---|
|
|
|
|
or as an IP address range
IPv4 | IPv6 |
---|---|
|
|
|
|
As address pools are explicitly assigned to connections defined in
swanctl.conf
, multiple connections can easily
share the same pool.
It’s also possible to use an external pool provided by a plugin by specifying a pool name to request addresses from (see further below for details on these backends):
connections.<conn>.pools = poolname
This queries registered plugins for an IP address from a pool named poolname
(below are two examples that use the
dhcp
and eap-radius
plugins, respectively).
Multiple pools may be defined. Note that the order in which they are queried
primarily depends on the plugin order. Only if pools are provided by the same
backend, does the order defined in swanctl.conf
matter:
connections.<conn>.pools = v4pool, v6pool pools.v4pool.addrs = 10.3.0.0/24 pools.v6pool.addrs = 2001:db8::3:0/24
DNS servers
DNS servers and other attributes can be assigned by plugins (e.g. by the
attr
plugin. In
swanctl.conf
each pool in the pools
section may define a list of attributes to assign to clients.
In-memory backend
A non-persistent memory-based backend is the default as described for
swanctl.conf
. Such a backend is suitable for
environments where pools are not shared across multiple gateways, server restarts
are rare and direct administration of the pools is not needed (though there are
some provisions for non-destructively reloading pool configurations in a running
server when using swanctl.conf
). To preserve
IP address affinity, the remote IKE identity (as defined for the connection in
question) is used. This maintains the same IP for a client (most of the time)
even across brief teardowns of connections, approximating the behavior of a DHCP
server without the stricture of lease expiry timers but prevents clients from
intentionally attempting to get a different IP address as there is no
corresponding release mechanism.
DHCP backend
With the dhcp
plugin the responder can request
virtual IP addresses for clients from a DHCP server using broadcasts or from a
designated server.
DNS/WINS server information is additionally served to clients if the DHCP server provides such information.
The plugin is used by setting
connections.<conn>.pools = dhcp
RADIUS backend
The eap-radius
plugin can provide virtual IP
addresses assigned to RADIUS clients via the Framed-IP-Address
attribute.
Forwarding of other RADIUS attributes
is also supported. The plugin is used by setting
connections.<conn>.pools = radius
Multiple pools, Different Backends
If multiple pools are defined from different backends, for instance
connections.<conn>.pools = radius, v4pool pools.v4pool.addrs = 10.3.0.0/24
the order in which they are queried for virtual IPs depends on the
plugin load order. In-memory pools are provided by
the vici
plugins. The order pools
is irrelevant
unless multiple in-memory pools from the same backend are defined.