Virtual IP » History » Version 18

Version 17 (Noel Kuntze, 22.02.2016 14:39) → Version 18/24 (Tobias Brunner, 08.04.2016 19:43)

h1. Virtual IP


IKEv1 and IKEv2 both know the concept of _virtual IPs_. This means that the initiator requests an additional IP address from the responder peer to use as inner IPsec tunnel address.

In IKEv1, virtual IPs are exchanged using the _mode config_ extension. IKEv2 has full support for virtual IPs in the core standard using _configuration payloads_.

strongSwan currently implements one scenario with IKEv2 configuration payloads, where an IP address is assigned to the initiator (since version:5.0.1 [[5.0.1]] multiple addresses can be assigned from multiple pools). The opposite is possible by the protocol, but is an uncommon setup and therefore not supported. It is supported for IKEv1, though, with mode config in _push mode_.

h2. Initiator Configuration

To The client needs an additional parameter called _leftsourceip_.


_%config_ means to
request an *arbitrary* virtual IP address from the responder and is an alias for the client configures the following:

|_<.Configuration File |_<.IPv4|_<.IPv6|
|(level2). [[swanctl.conf]]|_connections.<conn>.vips =|_connections.<conn>.vips = ::_|
|(level2). [[ipsec.conf]] |_leftsourceip=%config_|_leftsourceip=%config6_|

It is possible to request a
IKEv1 specific _%modecfg_. But you may specify an address explicitly by setting:

|_<.Configuration File |_<.IPv4|_<.IPv6|

|(level2). [[swanctl.conf]]|_connections.<conn>.vips =|_connections.<conn>.vips = 2001:db8::1_| <pre>

|(level2). [[ipsec.conf]] |_leftsourceip=|_leftsourceip=2001:db8::1_| </pre>

This will include _10.3.0.5_ into the configuration payload request. However, the responder may return a *different address*, different address, or may *not return* 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_ in [[swanctl.conf]] or _leftsubnet_ in [[ipsec.conf]]). Configuring such an IP as in the example above will not have the intended effect because the IP won't get [[VirtualIp#Implementation|installed on the system]] unless the server actually assigns that IP to the client with a configuration payload.

The *traffic selectors* in [[swanctl.conf]] and [[ipsec.conf]] (_local|remote_ts_ and _left|rightsubnet_, respectively) default @leftsubnet@ option defaults to the value _%dynamic_. @%dynamic@. If virtual IPs are @leftsourceip@ respectively @rightsourceip@ is used, this value gets dynamically replaced by the received or assigned virtual IP.
Therefore, no local traffic selector *must be* configured on the client and no remote traffic selector on the server

The @leftsubnet@ option should not be included
when using requesting a virtual IPs. This ensures IP, as the client's traffic selector subnet may not match the received address. Without the _leftsubnet_ option, the subnet is correctly narrowed to the assigned virtual IP. IP automatically.

To use a static virtual IP (i.e. without exchanging configuration payloads) it may simply be added to any local interface (even _lo_) and referenced in _leftsubnet_.

Since version:5.0.1 [[5.0.1]] a client may request *multiple* multiple IP addresses by listing a comma-separated combination of _%config4_, _%config6_ or fixed IP addresses in _leftsourceip_, respectively multiple IP addresses in _connections.<conn>.vips_. _leftsourceip_. Configuring _%config_ in _leftsourceip_ (or one of its aliases) will request an address of the traffic selectors' tunnel address family.
The main use case is for dual-stack dualstack hosts to request a virtual IP of each address family:

|_<.Configuration File |_<.IPv4 & IPv6| <pre>

|(level2). [[swanctl.conf]]|_connections.<conn>.vips =, ::_|
|(level2). [[ipsec.conf]] |_leftsourceip=%config4,%config6_|

</pre> This is also illustrated in the {{tc(ikev2/ip-two-pools-v4v6)}} test scenario.

h3. DNS servers

Before version:5.0.1 [[5.0.1]] the client couldn't explicitly request other attributes, but it may still have requested and processed the DNS attribute (depending on the loaded plugins). attribute. With current releases DNS servers may explicitly be requested with the _leftdns_ option in [[ipsec.conf]] (there is nothing similar in [[swanctl.conf]]). option. Received DNS servers are handled, for instance, by the [[resolveplugin|resolve plugin]], plugin]] which uses the @resolvconf@ utility to install them or writes them to _/etc/resolv.conf_ (or another _/etc/resolv.conf_, or an other file specified with the _--with-resolve-conf_ configure directive). directive.

h3. Implementation

On Linux, the virtual IP addresses will be installed on the outbound interface by default (may be changed, since version:5.0.1, [[5.0.1]], with the _charon.install_virtual_ip_on_ option) and source routes will be installed in the routing table configured with _charon.routing_table_ in [[strongswan.conf]] (or [[Autoconf|./configured]] with _--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 was used the IPsec policies wouldn't match and the packets wouldn't get tunneled). in _rightsubnet_.

h2. Responder Configuration

To The responder configuration uses the _rightsourceip_ option:

This will
serve a specific the IP address (even _10.3.0.6_ to the client, even if the initiator requests a different address) to a single client requested another address. Additionally, the following responder may be configured:

|_<.Configuration File |_<.IPv4|_<.IPv6|
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = <name>_ <pre>

_pools.<name>.addrs =|_connections.<conn>.pools = <name>_
_pools.<name>.addrs = 2001:db8::1_|
|(level2). [[ipsec.conf]] |_rightsourceip=|_rightsourceip=2001:db8::1_|

Alternatively, the responder may define the following to let the client choose an address. This is *not recommended* not recommended if you do not trust the client is not completely trusted. completely.

|_<.Configuration File |_<.IPv4 & IPv6|
|(level2). [[ipsec.conf]] |_rightsourceip=%config_|

To serve *multiple clients*
You may define an address pool in CIDR notation or notation, e.g.
</pre> to serve addresses from that pool.

Alternatively, you can define the pool
as an address range:

|_<.Configuration File |_<.IPv4|_<.IPv6|

|/2(level2). [[swanctl.conf]]|_connections.<conn>.pools = <name>_ <pre>

_pools.<name>.addrs =|_connections.<conn>.pools = <name>_ </pre>
_pools.<name>.addrs = 2001:db8::3:0/24_| You may also use an external pool implemented as a plugin where you can specify a pool name to select addresses from. The definition
|_connections.<conn>.pools = <name>_ <pre>

_pools.<name>.addrs =|_connections.<conn>.pools = <name>_
_pools.<name>.addrs = 2001:db8::3:1-2001:db8::3:100_|
|/2(level2). [[ipsec.conf]] |_rightsourceip=|_rightsourceip=2001:db8::3:0/24_|


queries registered plugins for an IP from a pool named _poolname_. This can also be the name of another connection in [[IpsecConf|ipsec.conf]] which defines a pool in CIDR notation with _rightsourceip_, as a pool with that connection's name is created implicitly.
Since version:5.0.1 [[5.0.1]] multiple connections in [[ipsec.conf]] (i.e. [[ConnSection|conn sections]]) can share the same pool implicitly if they use the same definition in _rightsourceip_ (previously each connection would use it's own copy and the same virtual IP may have been handed out to different clients).
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:

|_<.Configuration File |_<.IPv4 & IPv6|
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = poolname_|
|(level2). [[ipsec.conf]] |_rightsourceip=%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 can be listed in _rightsourceip_ since version:5.0.1:

|_<.Configuration File |_<.IPv4 & IPv6|
[[5.0.1]], e.g.
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = v4pool, v6pool_ <pre>

_pools.v4pool.addrs =
_pools.v6pool.addrs = 2001:db8::3:0/24_|
|(level2). [[ipsec.conf]] |_rightsourceip=,2001:db8::3:0/24_|

As used in the {{tc(ikev2/ip-two-pools-v4v6)}} test scenario.

h3. DNS servers

DNS servers and other attributes can be assigned by plugins (e.g. the [[AttrPlugin|attr plugin]]) or since version:5.0.1 [[5.0.1]] directly in [[ipsec.conf]] by use of the _rightdns_ option. In [[swanctl.conf]] each pool in the _pools_ section may define a list of attributes to assign to clients.

h3. Database backend

The [[IpsecPool|ipsec pool]] utility allows to easily manage IP address pools and other attributes, like DNS servers, stored in an SQL database using the [[attrsql|attr-sql plugin]].

h3. DHCP backend

With the [[DHCPPlugin|dhcp plugin]] the responder can request virtual IP addresses for clients from a DHCP server using broadcasts, or a designated server.

DNS/WINS server information is additionally served to clients if the DHCP server provides such information.

The plugin is used in [[ipsec.conf]] configurations by setting

|_<.Configuration File |_<.IPv4|

|(level2). [[swanctl.conf]]|_connections.<conn>.pools = dhcp_| <pre>

|(level2). [[ipsec.conf]] |_rightsourceip=%dhcp_| </pre>

The [[FARPPlugin|farp plugin]] might also be of use when using the [[DHCPPlugin|dhcp plugin]]. It allows the responder to fake ARP responses for virtual IP addresses handed out to clients. This lets a road-warrior act as a client on the local LAN of the responder.

h3. RADIUS backend

Since version:5.0.3 [[5.0.3]] the [[EAPRAdius|RADIUS plugin]] can provide virtual IP addresses assigned to RADIUS clients via the Framed-IP-Address attribute. [[EAPRAdius#RADIUS-attribute-forwarding|Forwarding of other RADIUS attributes]] has been added in later releases.

The plugin is used in [[ipsec.conf]] configurations by setting

|_<.Configuration File |_<.IPv4 & IPv6|

|(level2). [[swanctl.conf]]|_connections.<conn>.pools = radius_| <pre>

|(level2). [[ipsec.conf]] |_rightsourceip=%radius_| </pre>

h3. Multiple pools, different backends

If multiple pools are defined from *different* different backends, for instance

|_<.Configuration File |_<.IPv4| <pre>

|(level2). [[swanctl.conf]]|_connections.<conn>.pools = radius, v4pool_
_pools.v4pool.addrs =|
|(level2). [[ipsec.conf]] |_rightsourceip=%radius,|

the order in which they are queried for virtual IPs depends on the [[PluginLoad|plugin load order]] (in-memory pools are provided by the _stroke_ and _vici_ plugins, respectively). plugin). The order in _rightsourceip_ or _pools_ is irrelevant unless irrelevant, unless, multiple in-memory pools from the same backend are defined.

h2. Versions before 5.0.0

The description above covers the features of the charon daemon, which handled only IKEv2 connections in earlier releases. The pluto daemon that handled IKEv1 connections provided a similar feature set but not everything was supported (for instance, the _dhcp_ dhcp and _farp_ farp plugins).

The pluto daemon did not request virtual IP addresses from the responder if they were explicitly configured with _leftsourceip_ (but it still installed it on the system, which charon does not do). _leftsourceip_. In that case, that is, if the virtual IP was not assigned by the responder with _rightsourceip_ one may had to use the _rightsubnetwithin_ directive (refer to "this example": That's not required in charon due to narrowing.

The IKEv2 daemon charon supports address pools since version version:4.2.1, [[4.2.1]], the IKEv1 daemon pluto gained support for this in version:4.4.0. [[4.4.0]].