Virtual IP » History » Version 24

Tobias Brunner, 03.07.2020 15:21
Note about pool order

1 6 Martin Willi
h1. Virtual IP
2 1 Martin Willi
3 11 Tobias Brunner
4 1 Martin Willi
5 18 Tobias Brunner
IKEv1 and IKEv2 both know the concept of _virtual IPs_. This means that the initiator requests an additional IP address from the responder to use as inner IPsec tunnel address.
6 1 Martin Willi
7 6 Martin Willi
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_.
8 6 Martin Willi
9 18 Tobias Brunner
strongSwan currently implements one scenario with IKEv2 configuration payloads, where an IP address is assigned to the initiator (since version: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_.
10 1 Martin Willi
11 7 Tobias Brunner
12 11 Tobias Brunner
h2. Initiator Configuration
13 1 Martin Willi
14 18 Tobias Brunner
To request an *arbitrary* virtual IP from the responder the client configures the following:
15 1 Martin Willi
16 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4|_<.IPv6|
17 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.vips =|_connections.<conn>.vips = ::_|
18 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_leftsourceip=%config_|_leftsourceip=%config6_|
19 11 Tobias Brunner
20 18 Tobias Brunner
It is possible to request a specific address by setting:
21 1 Martin Willi
22 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4|_<.IPv6|
23 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.vips =|_connections.<conn>.vips = 2001:db8::1_|
24 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_leftsourceip=|_leftsourceip=2001:db8::1_|
25 1 Martin Willi
26 18 Tobias Brunner
However, the responder may return a *different address*, or may *not return* one at all.
27 1 Martin Willi
28 18 Tobias Brunner
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.
29 15 Noel Kuntze
30 23 Tobias Brunner
The *traffic selectors* in [[swanctl.conf]] and [[ipsec.conf]] (_local|remote_ts_ and _left|rightsubnet_, respectively) default to the value _dynamic_ or _%dynamic_, respectively. If virtual IPs are used, this value gets dynamically replaced by the received or assigned virtual IP.
31 18 Tobias Brunner
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.
32 14 Tobias Brunner
33 18 Tobias Brunner
Since version:5.0.1 a client may request *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_. Configuring _%config_ in _leftsourceip_ will request an address of the traffic selectors' address family.
34 18 Tobias Brunner
The main use case is for dual-stack hosts to request a virtual IP of each address family:
35 1 Martin Willi
36 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4 & IPv6|
37 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.vips =, ::_|
38 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_leftsourceip=%config4,%config6_|
39 1 Martin Willi
40 18 Tobias Brunner
This is also illustrated in the {{tc(ikev2/ip-two-pools-v4v6)}} test scenario.
41 18 Tobias Brunner
42 1 Martin Willi
h3. DNS servers
43 1 Martin Willi
44 18 Tobias Brunner
Before version: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). With current releases DNS servers may explicitly be requested with the _leftdns_ option in [[ipsec.conf]] (there is nothing similar in [[swanctl.conf]]). Received DNS servers are handled, for instance, by the [[resolveplugin|resolve plugin]], which uses the @resolvconf@ utility to install them or writes them to _/etc/resolv.conf_ (or another file specified with the _--with-resolve-conf_ configure directive).
45 1 Martin Willi
46 1 Martin Willi
h3. Implementation
47 1 Martin Willi
48 18 Tobias Brunner
On Linux, the virtual IP addresses will be installed on the outbound interface by default (may be changed, since version: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).
49 1 Martin Willi
50 1 Martin Willi
h2. Responder Configuration
51 12 Tobias Brunner
52 23 Tobias Brunner
As already documented above, the remote *traffic selector* in [[swanctl.conf]] and [[ipsec.conf]] (_remote_ts_ and _rightsubnet_, respectively) defaults to the value _dynamic_ or _%dynamic_, respectively. This value 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).
53 1 Martin Willi
54 24 Tobias Brunner
To serve a specific IP address (even if the initiator requests a different address) to a single client, the following may be configured:
55 12 Tobias Brunner
56 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4|_<.IPv6|
57 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = <name>_
58 18 Tobias Brunner
_pools.<name>.addrs =|_connections.<conn>.pools = <name>_
59 18 Tobias Brunner
_pools.<name>.addrs = 2001:db8::1_|
60 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_rightsourceip=|_rightsourceip=2001:db8::1_|
61 1 Martin Willi
62 18 Tobias Brunner
Alternatively, the responder may define the following to let the client choose an address. This is *not recommended* if the client is not completely trusted.
63 1 Martin Willi
64 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4 & IPv6|
65 1 Martin Willi
|(level2). [[ipsec.conf]]  |_rightsourceip=%config_|
66 1 Martin Willi
67 24 Tobias Brunner
To serve *multiple clients*, define an address pool in CIDR notation or as an address range:
68 6 Martin Willi
69 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4|_<.IPv6|
70 18 Tobias Brunner
|/2(level2). [[swanctl.conf]]|_connections.<conn>.pools = <name>_
71 18 Tobias Brunner
_pools.<name>.addrs =|_connections.<conn>.pools = <name>_
72 18 Tobias Brunner
_pools.<name>.addrs = 2001:db8::3:0/24_|
73 18 Tobias Brunner
|_connections.<conn>.pools = <name>_
74 18 Tobias Brunner
_pools.<name>.addrs =|_connections.<conn>.pools = <name>_
75 18 Tobias Brunner
_pools.<name>.addrs = 2001:db8::3:1-2001:db8::3:100_|
76 1 Martin Willi
|/2(level2). [[ipsec.conf]]  |_rightsourceip=|_rightsourceip=2001:db8::3:0/24_|
77 1 Martin Willi
78 1 Martin Willi
79 24 Tobias Brunner
Since version:5.0.1, multiple connections in [[ipsec.conf]] (i.e. [[ConnSection|conn sections]]) can share the same pool 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).
80 24 Tobias Brunner
As address pools are explicitly assigned to connections defined in [[swanctl.conf]], multiple connections can easily share the same pool.
81 17 Noel Kuntze
82 24 Tobias Brunner
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):
83 18 Tobias Brunner
84 1 Martin Willi
|_<.Configuration File     |_<.IPv4 & IPv6|
85 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = poolname_|
86 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_rightsourceip=%poolname_|
87 18 Tobias Brunner
88 18 Tobias Brunner
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).
89 18 Tobias Brunner
90 24 Tobias Brunner
Multiple pools may be listed since version:5.0.1. 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 here matter:
91 18 Tobias Brunner
92 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4 & IPv6|
93 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = v4pool, v6pool_
94 18 Tobias Brunner
_pools.v4pool.addrs =
95 18 Tobias Brunner
_pools.v6pool.addrs = 2001:db8::3:0/24_|
96 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_rightsourceip=,2001:db8::3:0/24_|
97 18 Tobias Brunner
98 1 Martin Willi
As used in the {{tc(ikev2/ip-two-pools-v4v6)}} test scenario.
99 11 Tobias Brunner
100 1 Martin Willi
h3. DNS servers
101 11 Tobias Brunner
102 18 Tobias Brunner
DNS servers and other attributes can be assigned by plugins (e.g. the [[AttrPlugin|attr plugin]]) or since version: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.
103 11 Tobias Brunner
104 20 Brian Julin
h3. In-memory backend
105 20 Brian Julin
106 22 Tobias Brunner
A non-persistent memory-based backend is the default (the configuration for [[swanctl.conf]] and  [[ipsec.conf]] is described above).  This 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.
107 20 Brian Julin
108 11 Tobias Brunner
h3. Database backend
109 11 Tobias Brunner
110 21 Brian Julin
The [[IpsecPool|ipsec pool]] utility allows easy management of IP address pools and other attributes, like DNS servers, stored in an SQL database using the [[attrsql|attr-sql plugin]].
111 11 Tobias Brunner
112 11 Tobias Brunner
h3. DHCP backend
113 11 Tobias Brunner
114 11 Tobias Brunner
With the [[DHCPPlugin|dhcp plugin]] the responder can request virtual IP addresses for clients from a DHCP server using broadcasts, or a designated server.
115 1 Martin Willi
116 1 Martin Willi
DNS/WINS server information is additionally served to clients if the DHCP server provides such information.
117 1 Martin Willi
118 18 Tobias Brunner
The plugin is used by setting
119 11 Tobias Brunner
120 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4|
121 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = dhcp_|
122 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_rightsourceip=%dhcp_|
123 18 Tobias Brunner
124 11 Tobias Brunner
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.
125 11 Tobias Brunner
126 13 Tobias Brunner
h3. RADIUS backend
127 13 Tobias Brunner
128 18 Tobias Brunner
Since version: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.
129 13 Tobias Brunner
130 18 Tobias Brunner
The plugin is used by setting
131 13 Tobias Brunner
132 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4 & IPv6|
133 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = radius_|
134 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_rightsourceip=%radius_|
135 18 Tobias Brunner
136 16 Tobias Brunner
h3. Multiple pools, different backends
137 16 Tobias Brunner
138 18 Tobias Brunner
If multiple pools are defined from *different* backends, for instance
139 16 Tobias Brunner
140 18 Tobias Brunner
|_<.Configuration File     |_<.IPv4|
141 18 Tobias Brunner
|(level2). [[swanctl.conf]]|_connections.<conn>.pools = radius, v4pool_
142 18 Tobias Brunner
_pools.v4pool.addrs =|
143 18 Tobias Brunner
|(level2). [[ipsec.conf]]  |_rightsourceip=%radius,|
144 16 Tobias Brunner
145 18 Tobias Brunner
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). The order in _rightsourceip_ or _pools_ is irrelevant unless multiple in-memory pools from the same backend are defined.
146 11 Tobias Brunner
147 11 Tobias Brunner
h2. Versions before 5.0.0
148 11 Tobias Brunner
149 18 Tobias Brunner
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_ and _farp_ plugins).
150 11 Tobias Brunner
151 18 Tobias Brunner
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). 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.
152 1 Martin Willi
153 18 Tobias Brunner
The IKEv2 daemon charon supports address pools since version version:4.2.1, the IKEv1 daemon pluto gained support for this in version:4.4.0.