Project

General

Profile

Route-based VPNs » History » Version 8

Martin Willi, 05.04.2019 16:44
Document policy match limitation with XFRM interfaces

1 1 Tobias Brunner
h1. Route-based VPNs
2 1 Tobias Brunner
3 1 Tobias Brunner
{{>toc}}
4 1 Tobias Brunner
5 6 Tobias Brunner
Generally IPsec processing is based on policies. After regular route lookups are done, the OS kernel consults its SPD(Security Policy Database) for a matching policy and if one is found that is associated with an IPsec SA(Security Association), the packet is processed (e.g. encrypted and sent as ESP packet). Refer to [[IPsecDocumentation]] for details.
6 1 Tobias Brunner
7 1 Tobias Brunner
Depending on the operating system it is also possible to configure route-based VPNs. Here IPsec processing does not (only) depend on negotiated policies but may e.g. be controlled by routing packets to a specific interface.
8 1 Tobias Brunner
9 1 Tobias Brunner
Most of these approaches also allow easy capture of plaintext traffic, which, depending on the operating system, might not be that straight-forward with policy-based VPNs (see [[CorrectTrafficDump]]). Another advantage this approach could have is that the MTU can be specified for the tunneling devices allowing to fragment packets before tunneling them in case PMTUD does not work properly.
10 1 Tobias Brunner
11 1 Tobias Brunner
h2. VTI Devices on Linux
12 1 Tobias Brunner
13 1 Tobias Brunner
_*Disclaimer:* VTI devices are supported since the Linux 3.6 kernel, but some important changes were added later (3.15+). The information below might not be accurate for older kernel versions._
14 1 Tobias Brunner
15 6 Tobias Brunner
_*Note:* On newer kernels (4.19+), XFRM interfaces provide a better solution than VTI devices, [[RouteBasedVPN#XFRM-Interfaces-on-Linux|see below]] for details._
16 6 Tobias Brunner
17 1 Tobias Brunner
VTI devices act like a wrapper around existing IPsec policies. This means you can't just route arbitrary packets to a VTI device to get them tunneled, the established IPsec policies have to match too. However, you can negotiate _0.0.0.0/0_ traffic selectors on both ends to allow tunneling anything that's routed via VTI device.
18 1 Tobias Brunner
19 6 Tobias Brunner
To make this work, that is, to prevent packets not routed via VTI device from matching the policies (if _0.0.0.0/0_ is used every packet would match) marks are used. Only packets that are marked accordingly will match the policies and get tunneled. For other packets the policies are ignored. Whenever a packet is routed to a VTI device it automatically gets the configured mark applied so it will match the policy and get tunneled.
20 1 Tobias Brunner
21 6 Tobias Brunner
It's important to note that VTI tunnel devices are a local feature, no additional encapsulation (like with GRE, [[RouteBasedVPN#GRE|see below]]) is added, so the other end does not have to be aware that VTI devices are used in addition to regular IPsec policies.
22 1 Tobias Brunner
23 1 Tobias Brunner
A VTI device may be created with the following command:
24 1 Tobias Brunner
25 1 Tobias Brunner
<pre>
26 1 Tobias Brunner
ip tunnel add <name> local <local IP> remote <remote IP> mode vti key <number equaling the mark>
27 1 Tobias Brunner
</pre>
28 1 Tobias Brunner
29 1 Tobias Brunner
_<name>_ can be any valid device name (e.g. _ipsec0_, _vti0_ etc.). But note that the @ip@ command treats names starting with _vti_ special in some instances (e.g. when retrieving device statistics). The IPs are the endpoints of the IPsec tunnel. The number at the end has to match the mark configured for the connection. It is also possible to configure different marks for in- and outbound traffic using _ikey/okey <mark>_, but that is usually not required.
30 1 Tobias Brunner
31 1 Tobias Brunner
After creating the device it has to be enabled (@ip link set <name> up@) and then routes may be installed (routing protocols may also be used).  To avoid duplicate policy lookups it is also recommended to set @sysctl -w net.ipv4.conf.<name>.disable_policy=1@. All of this also works for IPv6.
32 1 Tobias Brunner
33 1 Tobias Brunner
{{collapse(Examples)
34 1 Tobias Brunner
<pre>
35 1 Tobias Brunner
ip tunnel add vti0   local 192.168.0.1 remote 192.168.0.2 mode vti key 42
36 1 Tobias Brunner
ip tunnel add ipsec0 local 192.168.0.1 remote 192.168.0.2 mode vti key 0x01000201
37 1 Tobias Brunner
sysctl -w net.ipv4.conf.vti0.disable_policy=1
38 1 Tobias Brunner
ip link set vti0 up
39 1 Tobias Brunner
ip route add 10.1.0.0/16 dev vti0
40 1 Tobias Brunner
sysctl -w net.ipv4.conf.ipsec0.disable_policy=1
41 1 Tobias Brunner
ip link set ipsec0 up
42 1 Tobias Brunner
ip route add 10.2.0.0/16 dev ipsec0
43 1 Tobias Brunner
ip route add 10.3.0.0/16 dev ipsec0
44 1 Tobias Brunner
</pre>
45 1 Tobias Brunner
}}
46 1 Tobias Brunner
47 1 Tobias Brunner
Statistics on VTI devices may be displayed with @ip -s tunnel show [<name>]@. Note that specifying a name will not show any statistics if the device name starts with _vti_.
48 1 Tobias Brunner
49 1 Tobias Brunner
A VTI device may be removed again with @ip tunnel del <name>@.
50 1 Tobias Brunner
51 1 Tobias Brunner
h3. Configuration
52 4 Noel Kuntze
53 6 Tobias Brunner
*First, the route installation by the IKE daemon must be disabled. To do this, set _charon.install_routes=0_ in [[strongswan.conf]].*
54 1 Tobias Brunner
55 6 Tobias Brunner
Then configure a regular site-to-site connection, either with the traffic selectors set to _0.0.0.0/0_ on both ends (_local|remote_ts=0.0.0.0.0/0_ in [[swanctl.conf]] or _left|rightsubnet=0.0.0.0/0_ in [[ipsec.conf]]), or set to specific subnets. As mentioned above, only traffic that matches these traffic selectors will then actually be forwarded, other packets routed to the VTI device will be rejected with an ICMP error message (_destination unreachable/destination host unreachable_).
56 1 Tobias Brunner
57 6 Tobias Brunner
The most important configuration option is the mark (_mark_in|out_ in [[swanctl.conf]], _mark_ in [[ipsec.conf]]). After applying the optional mask (default is _0xffffffff_) to the mark that's set on the VTI device and it applied to the routed packets, the value has to match the configured mark.
58 6 Tobias Brunner
So referring to the example above, to match the mark on _vti0_ configure _mark_in_ = _mark_out_ = _42_ and to match the mark on _ipsec0_ set the value to _0x01000201_ (but something like _0x00000200/0x00000f00_ would also work).
59 1 Tobias Brunner
60 1 Tobias Brunner
h3. Sharing VTI Devices
61 1 Tobias Brunner
62 1 Tobias Brunner
VTI devices may be shared by multiple IPsec SAs (e.g. in roadwarrior scenarios, to capture traffic or lower the MTU) by setting the remote endpoint of the VTI device to 0.0.0.0. For instance:
63 1 Tobias Brunner
64 1 Tobias Brunner
<pre>
65 1 Tobias Brunner
ip tunnel add ipsec0 local 192.168.0.1 remote 0.0.0.0 mode vti key 42
66 1 Tobias Brunner
</pre>
67 1 Tobias Brunner
68 1 Tobias Brunner
Then assuming [[VirtualIP|virtual IPs]] for roadwarriors are assigned from the _10.0.1.0/24_ subnet a matching route may be installed with @ip route add 10.0.1.0/24 dev ipsec0@.
69 1 Tobias Brunner
70 6 Tobias Brunner
_*Note:* Only one such device with the same local IP may be created._
71 6 Tobias Brunner
72 1 Tobias Brunner
h3. Connection-specific VTI Devices
73 3 Noel Kuntze
74 3 Noel Kuntze
With a custom [[updown]] script it is also possible to setup connection-specific VTI devices.
75 3 Noel Kuntze
76 5 Noel Kuntze
For instance, to create a VTI device on a roadwarrrior client that receives a [[VirtualIP|dynamic virtual IP]] (courtesy of Endre Szab├│):
77 5 Noel Kuntze
78 6 Tobias Brunner
{{collapse(Example script for roadwarriors)
79 1 Tobias Brunner
<pre>
80 1 Tobias Brunner
#!/bin/bash
81 1 Tobias Brunner
82 1 Tobias Brunner
# set charon.install_virtual_ip = no to prevent the daemon from also installing the VIP
83 1 Tobias Brunner
84 1 Tobias Brunner
set -o nounset
85 1 Tobias Brunner
set -o errexit
86 1 Tobias Brunner
87 1 Tobias Brunner
VTI_IF="vti${PLUTO_UNIQUEID}"
88 1 Tobias Brunner
89 1 Tobias Brunner
case "${PLUTO_VERB}" in
90 1 Tobias Brunner
    up-client)
91 5 Noel Kuntze
        ip tunnel add "${VTI_IF}" local "${PLUTO_ME}" remote "${PLUTO_PEER}" mode vti \
92 1 Tobias Brunner
            key "${PLUTO_MARK_OUT%%/*}"
93 1 Tobias Brunner
        ip link set "${VTI_IF}" up
94 1 Tobias Brunner
        ip addr add "${PLUTO_MY_SOURCEIP}" dev "${VTI_IF}"
95 1 Tobias Brunner
        ip route add "${PLUTO_PEER_CLIENT}" dev "${VTI_IF}"
96 1 Tobias Brunner
        sysctl -w "net.ipv4.conf.${VTI_IF}.disable_policy=1"
97 1 Tobias Brunner
        ;;
98 1 Tobias Brunner
    down-client)
99 1 Tobias Brunner
        ip tunnel del "${VTI_IF}"
100 1 Tobias Brunner
        ;;
101 1 Tobias Brunner
esac
102 1 Tobias Brunner
</pre>
103 1 Tobias Brunner
}}
104 5 Noel Kuntze
105 6 Tobias Brunner
If there is more than one subnet in the remote traffic selector this might cause conflicts as the _updown_ script will be called for each combination of local and remote subnet.
106 5 Noel Kuntze
107 6 Tobias Brunner
Dynamically creating such devices on the server could be problematic if two roadwarriors are connected from the same IP. The kernel rejects the creation of a VTI device if the remote and local addresses are already in use by another VTI device.
108 6 Tobias Brunner
109 6 Tobias Brunner
In the following script, it is assumed that only the roadwarrior's assigned IPv4 VIP is supposed to be reachable over the assigned tunnel.
110 6 Tobias Brunner
111 6 Tobias Brunner
{{collapse(Example script for gateways)
112 5 Noel Kuntze
<pre>
113 5 Noel Kuntze
#!/bin/bash
114 5 Noel Kuntze
115 5 Noel Kuntze
# set charon.install_virtual_ip = no to prevent the daemon from also installing the VIP
116 5 Noel Kuntze
117 5 Noel Kuntze
set -o nounset
118 1 Tobias Brunner
set -o errexit
119 1 Tobias Brunner
120 5 Noel Kuntze
VTI_IF="vti${PLUTO_UNIQUEID}"
121 1 Tobias Brunner
122 1 Tobias Brunner
case "${PLUTO_VERB}" in
123 1 Tobias Brunner
    up-client)
124 1 Tobias Brunner
        ip tunnel add "${VTI_IF}" local "${PLUTO_ME}" remote "${PLUTO_PEER}" mode vti \
125 1 Tobias Brunner
            key "${PLUTO_MARK_OUT%%/*}" 
126 1 Tobias Brunner
        ip link set "${VTI_IF}" up
127 1 Tobias Brunner
        ip route add "${PLUTO_PEER_SOURCEIP}" dev "${VTI_IF}" 
128 1 Tobias Brunner
        sysctl -w "net.ipv4.conf.${VTI_IF}.disable_policy=1" 
129 1 Tobias Brunner
        ;;
130 1 Tobias Brunner
    down-client)
131 1 Tobias Brunner
        ip tunnel del "${VTI_IF}" 
132 1 Tobias Brunner
        ;;
133 1 Tobias Brunner
esac
134 6 Tobias Brunner
</pre>
135 6 Tobias Brunner
}}
136 1 Tobias Brunner
137 6 Tobias Brunner
**Note:** Using @PLUTO_UNIQUEID@ might not be a good idea if IKE_SAs may be rekeyed as the unique ID will change with each rekeying (i.e. the script won't be able to delete the device anymore). Using some other identifier (e.g. parts of the virtual IP, or the mark, if it is unique) might be better.
138 6 Tobias Brunner
139 6 Tobias Brunner
h2. XFRM Interfaces on Linux
140 6 Tobias Brunner
141 6 Tobias Brunner
_*Disclaimer:* strongSwan supports XFRM interfaces since version:5.8.0. They are supported by the Linux kernel since 4.19, however, @iproute2@ currently has no support to create such interfaces via @ip link@. So they have to be created directly via Netlink. strongSwan currently provides a small utility to create and list such interfaces (@iproute2@ can be used for other operations)._
142 6 Tobias Brunner
143 6 Tobias Brunner
XFRM interfaces are similar to VTI devices in their basic functionality ([[RouteBasedVPN#VTI-Devices-on-Linux|see above]] for details) but offer several advantages:
144 6 Tobias Brunner
145 6 Tobias Brunner
* No tunnel endpoint addresses have to be configured on the interfaces. Compared to VTIs, which are layer 3 tunnel devices with mandatory endpoints, this resolves issues with wildcard addresses (only one VTI with wildcard endpoints is supported), avoids a 1:1 mapping between SAs and interfaces, and easily allows SAs with multiple peers to share the same interface.
146 6 Tobias Brunner
147 6 Tobias Brunner
* Because there are no endpoint addresses, IPv4 and IPv6 SAs are supported on the same interface (VTI devices only support one address family).
148 6 Tobias Brunner
149 6 Tobias Brunner
* IPsec modes other than tunnel are supported (VTI devices only support tunnel mode).
150 6 Tobias Brunner
151 6 Tobias Brunner
* No awkward configuration via GRE keys and XFRM marks. Instead, a new identifier (XFRM interface ID) links policies and SAs with XFRM interfaces.
152 6 Tobias Brunner
153 6 Tobias Brunner
As mentioned above, the policies and SAs are linked to XFRM interface via a new identifier (interface ID). Like XFRM marks they are part of the policy selector. That is, policies will only match traffic if it was routed via an XFRM interface with a matching interface ID, and duplicate policies are allowed as long as the interface ID is different. So as with VTI devices it's possible to negotiate _0.0.0.0/0_ as traffic selector on both ends (to tunnel arbitrary traffic) for multiple CHILD_SAs as long as the interface IDs are different.
154 6 Tobias Brunner
155 6 Tobias Brunner
Traffic that's routed to an XFRM interface, while no policies and SAs with matching interface ID exist, will be dropped by the kernel. Likewise, as long as no interface with a matching interface ID exists, the policies and SAs will not be operational (i.e. outbound traffic bypasses the policies and inbound traffic is dropped). So it's possible to create interfaces before SAs are created or afterwards (e.g. via [[vici]] events or [[updown]] scripts, which both receive configured or, optionally, dynamically generated interface IDs).
156 6 Tobias Brunner
157 6 Tobias Brunner
Using trap policies to dynamically create IPsec SAs based on matching traffic that has been routed to an XFRM interface is also an option.
158 6 Tobias Brunner
159 6 Tobias Brunner
It's possible to use separate interfaces for in- and outbound traffic, which is why interface IDs may be configured for in- and outbound policies/SAs separately (see below).
160 6 Tobias Brunner
161 6 Tobias Brunner
As mentioned in the disclaimer above, to create an XFRM interface it is currently necessary to use strongSwan's @xfrmi@ utility:
162 6 Tobias Brunner
163 6 Tobias Brunner
<pre>
164 6 Tobias Brunner
/usr/local/libexec/ipsec/xfrmi --name <name> --id <interface ID> --dev <underlying interface>
165 1 Tobias Brunner
</pre>
166 6 Tobias Brunner
167 6 Tobias Brunner
_<name>_ can be any valid device name (e.g. _ipsec0_, _xfrm0_ etc.). <interface ID> is a decimal or hex (_0x_ prefix) 32-bit number. The underlying interface currently is mandatory, but doesn't really matter (it only does if an interface is configured on the outbound policy - and it might with hardware IPsec offloading, but that has not been tested by us), so it could be anything, even @lo@.
168 6 Tobias Brunner
169 6 Tobias Brunner
The interface can afterwards be managed via _iproute2_. So to activate it, use @ip link set <name> up@. Addresses, if necessary, can be added with @ip addr@ and the interface may eventually be deleted with @ip link del <name>@.
170 6 Tobias Brunner
171 6 Tobias Brunner
{{collapse(Example)
172 6 Tobias Brunner
<pre>
173 6 Tobias Brunner
/usr/local/libexec/ipsec/xfrmi --name ipsec0 --id 42 --dev eth0
174 6 Tobias Brunner
ip link set ipsec0 up
175 6 Tobias Brunner
ip route add 10.1.0.0/16 dev ipsec0
176 6 Tobias Brunner
ip route add 10.2.0.0/16 dev ipsec0
177 6 Tobias Brunner
</pre>
178 1 Tobias Brunner
}}
179 1 Tobias Brunner
180 6 Tobias Brunner
Statistics are available via @ip -s link show [<name>]@.
181 1 Tobias Brunner
182 6 Tobias Brunner
Since @ip link@ currently does not list the interface ID of XFRM interfaces, @xfrmi@ provides a @--list@ option to list existing XFRM interfaces.
183 6 Tobias Brunner
184 6 Tobias Brunner
h3. Configuration
185 6 Tobias Brunner
186 6 Tobias Brunner
**The daemon will not install any routes for CHILD_SAs with outbound interface ID, so it's not necessary to disable the route installation globally.**
187 6 Tobias Brunner
188 6 Tobias Brunner
Keep in mind that traffic routed to XFRM interfaces has to match the negotiated IPsec policies. Therefore, connections are configured as they would if no interfaces were to be used. However, since policies won't affect traffic that's not routed via XFRM interfaces, it's possible to negotiate _0.0.0.0/0_ or _::/0_ as traffic selector on both ends to tunnel arbitrary traffic.
189 6 Tobias Brunner
190 6 Tobias Brunner
The most important configuration option is the interface ID (_if_id_in|out_ in [[swanctl.conf]]). To use a single interface for in- and outbound traffic set them to the same value (or _%unique_ to generate a unique ID for each CHILD_SA), to use separate interfaces for each direction, configure distinct values (or _%unique-dir_ to generate unique IDs for each CHILD_SA and direction). It's also possible to use an XFRM interface only in one direction by setting only one of the two settings.
191 6 Tobias Brunner
192 6 Tobias Brunner
When setting the options on the connection-level, all CHILD_SAs, for which the settings are not set, will inherit the interface IDs of the IKE_SA (use _%unique_ or _%unique-dir_ to allocate unique IDs for each IKE_SA/direction that are inherited by all CHILD_SAs created under the IKE_SA).
193 6 Tobias Brunner
194 6 Tobias Brunner
It's possible to use transport mode for host-to-host connections between two peers.
195 6 Tobias Brunner
196 6 Tobias Brunner
h3. Sharing XFRM Interfaces
197 6 Tobias Brunner
198 6 Tobias Brunner
Because no endpoint addresses are configured on the interfaces they can easily be shared by multiple SAs, as long as the policies don't conflict. Just configure the same interface ID for the CHILD_SAs (this also works automatically for roadwarrior connections where each client gets an individual IP address assigned - just route the subnets used for virtual IPs to the XFRM interface).
199 6 Tobias Brunner
200 6 Tobias Brunner
h3. Connection-specific XFRM Interfaces
201 6 Tobias Brunner
202 6 Tobias Brunner
Using custom [[vici]] or [[updown]] scripts allows creating connection-specific VTI devices. The interface ID (in particular if _%unique[-dir]_ is used) is available in the scripts to create the XFRM interface dynamically.
203 6 Tobias Brunner
204 6 Tobias Brunner
Note that [[updown]] scripts are called for each combination of of local and remote subnet, so this might cause conflicts if more than one subnet is negotiated in the traffic selectors (i.e. this requires some kind of refcounting). The _child-udpown_ [[vici]] event, however, is only triggered once per CHILD_SA. To create connection-level XFRM interfaces with dynamic interface IDs, use the _ike-updown_ [[vici]] event.
205 6 Tobias Brunner
206 6 Tobias Brunner
h3. Network Namespaces
207 6 Tobias Brunner
208 6 Tobias Brunner
XFRM interfaces can be moved to network namespaces to provide the processes there access to IPsec SAs/policies that were created in a different network namespace. For instance, this allows a single IKE daemon to provide IPsec connections for processes in different network namespaces (or full containers) without them having access to the keys of the SAs (the SAs won't be visible in the other network namespaces, only the XFRM interface).
209 6 Tobias Brunner
210 6 Tobias Brunner
_There was a bug in kernels prior to 5.0. So using this feature with 4.20 kernels requires a kernel patch, see #2845-9. Because 4.19 is a longterm kernel, the fix was backported and is available since 4.19.31._
211 6 Tobias Brunner
212 7 Martin Willi
h3. XFRM interfaces in VRFs
213 7 Martin Willi
214 7 Martin Willi
XFRM interfaces can be associated to a VRF layer 3 master device, so any tunnel terminated by an XFRM interface implicitly is bound to that VRF domain. For example, this allows multi-tenancy setups, where traffic from different tunnels can be separated and routed over different interfaces.
215 7 Martin Willi
216 7 Martin Willi
_Due to a limitation in XFRM interfaces, inbound traffic fails policy checking in kernels prior to version 5.1._
217 6 Tobias Brunner
218 8 Martin Willi
h3. Netfilter IPsec policy match with XFRM interfaces
219 8 Martin Willi
220 8 Martin Willi
Due to a limitation in the Netfilter IPsec _policy_ match, output traffic forwarded over an XFRM interface does not match (inbound it matches, though). _policy_ matching is not really required anymore when using XFRM interfaces, as the Netfilter rules can just mach on the interface. So the work-around is to filter just on XFRM interface names instead of IPsec _policy_ matches.
221 8 Martin Willi
222 1 Tobias Brunner
h2. Marks on Linux
223 1 Tobias Brunner
224 6 Tobias Brunner
One of the core features of VTI devices or XFRM interfaces, dynamically specifying which traffic to tunnel, can actually be replicated directly with marks and firewall rules. By configuring connections with marks and then selectively marking packets directly with Netfilter rules via @MARK@ target in the @PREROUTING@ or @FORWARD@ chains only specific traffic will get tunneled.
225 1 Tobias Brunner
226 1 Tobias Brunner
This may also be used to create multiple identical tunnels for which firewall rules  dynamically decide which traffic is tunneled though which IPsec SA (e.g. for {{tc(ikev2/net2net-psk-dscp, QoS/DiffServ)}}).
227 1 Tobias Brunner
228 1 Tobias Brunner
h2. GRE
229 1 Tobias Brunner
230 6 Tobias Brunner
Another alternative is to use GRE(Generic Routing Encapsulation), which is a generic point-to-point tunneling protocol that adds an additional encapsulation layer (at least 4 bytes).  But it provides a portable way of creating route-based VPNs (running a routing protocol on-top is also easy).
231 1 Tobias Brunner
232 6 Tobias Brunner
While VTI devices depend on site-to-site IPsec connections in tunnel mode (XFRM interfaces are more flexible), GRE uses a host-to-host connection that can also be run in transport mode (avoiding additional overhead). But while VTI devices and XFRM interfaces may be used by only one of the peers, GRE must be used by both of them.
233 1 Tobias Brunner
234 1 Tobias Brunner
Creating a GRE tunnel on Linux can be done as follows:
235 1 Tobias Brunner
236 1 Tobias Brunner
<pre>
237 1 Tobias Brunner
ip tunnel add <name> local <local IP> remote <remote IP> mode gre
238 1 Tobias Brunner
</pre>
239 1 Tobias Brunner
240 1 Tobias Brunner
<name> can be any valid interface name (e.g. _ipsec0_, _gre0_ etc.). But note that the @ip@ command treats names starting with _gre_ special in some instances (e.g. when retrieving device statistics). The IPs are the endpoints of the IPsec tunnel.
241 1 Tobias Brunner
242 1 Tobias Brunner
After creating the device it has to be enabled (@ip link set <name> up@) and then routes may be installed.
243 1 Tobias Brunner
244 1 Tobias Brunner
{{collapse(Example)
245 1 Tobias Brunner
<pre>
246 1 Tobias Brunner
ip tunnel add ipsec0 local 192.168.0.1 remote 192.168.0.2 mode gre
247 1 Tobias Brunner
ip link set ipsec0 up
248 1 Tobias Brunner
ip route add 10.1.0.0/16 dev ipsec0
249 1 Tobias Brunner
ip route add 10.2.0.0/16 dev ipsec0
250 1 Tobias Brunner
</pre>
251 1 Tobias Brunner
}}
252 1 Tobias Brunner
253 1 Tobias Brunner
Statistics on GRE devices may be displayed with @ip -s tunnel show [<name>]@. Note that specifying a name will not show any statistics if the device name starts with _gre_.
254 1 Tobias Brunner
255 1 Tobias Brunner
A GRE device may be removed again with @ip tunnel del <name>@.
256 1 Tobias Brunner
257 1 Tobias Brunner
h3. Configuration
258 1 Tobias Brunner
259 1 Tobias Brunner
As mentioned above, a host-to-host IPsec connection in transport mode can be used. The traffic selectors may even be limited to just the GRE protocol (_local|remote_ts=dynamic[gre]_ in [[swanctl.conf]] or _left|rightsubnet=%dynamic[gre]_ in [[ipsec.conf]]).
260 1 Tobias Brunner
261 1 Tobias Brunner
h2. libipsec And TUN Devices
262 1 Tobias Brunner
263 6 Tobias Brunner
Based on our own userland IPsec implementation and the [[kernel-libipsec]] plugin it is possible to create route-based VPNs with TUN devices. Similar to VTI devices or XFRM interfaces, the negotiated IPsec policies have to match the traffic routed via TUN device.
264 2 Noel Kuntze
In particular because packets have to be copied between kernel and userland it is not as efficient as the solutions above (also read the notes on [[kernel-libipsec]]).
265 2 Noel Kuntze
266 2 Noel Kuntze
h2. Problems
267 2 Noel Kuntze
268 6 Tobias Brunner
Make sure to disable the [[connmark]] plugin when running a VTI. Otherwise, it will insert Netfilter rules into the @*mangle@ table that prevent the VTI from working.