Linux IPsec – Policy-Based IPsec Routing

ipsec

In linux, when it comes to route-based IPsec tunnels, it's pretty straight forward. Install one of the mainly ipsec implementations. Establish your security associations, add a VTI interface on each endpoint, add a mark to the VTI, change some sysctl opts and you can route traffic between the two endpoints.

How do you route traffic when doing policy-based routing ? All the tutorials I have encountered thus far only mention how to setup the ipsec connection, but none really explain how to route the traffic between the two endpoints or what additional steps are required for this process. Do I create a tunnel ? do I have to mark it ? add a route ? if so, then how is that any different from a route-based setup ?

Can someone shed some light on this ?

Best Answer

"Generally IPsec processing is based on policies. After regular route lookups are done the OS kernel consults its Security Policy Database for a matching policy and if one is found that is associated with an IPsec SA the packet is processed.

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."

Source: RouteBasedVPN

So policy based routing has nothing to do with the routing table of the OS but it's using a separate "database" so ip route and such does not play here. You set up these policies with the IPSec config. IPSec can do the tunneling on its own.

Here is the output of my ip route and swanctl --list-sas (I'm using swanctl to configure and control strongswan):

enter image description here

As you can see I have an IPSec connection between my hosted server called sv1 (37.17.x.x) and my home router (87.97.x.x). The server's routing table has only the default settings but you can see the IPSec policies called home-invitel, home-securewifi and home-lan that routes every traffic from the server to the home LAN subnets 192.168.100.0/24, 192.168.87.0/28 and 192.168.88.0/24 respectively. A fourth policy called sv1-local routes the traffic between my home endpoint and the 10.1.1.0/24 local subnet on the server.

Here is the swanctl config I use on the server:

connections {
        home {
                local_addrs = 37.17.x.x
                remote_addrs = vpn.example.org
                version = 2
                proposals = aes256-sha256-ecp384
                keyingtries = 0
                dpd_delay = 60s
                local1 {
                        auth = psk
                }
                remote1 {
                        auth = psk
                }
                children {
                        sv1-local {
                                local_ts = 10.1.1.0/24
                                esp_proposals = aes256gcm16-ecp384
                                dpd_action = restart
                                close_action = start
                                start_action = start
                        }
                        home-securewifi {
                                remote_ts = 192.168.87.0/28
                                esp_proposals = aes256gcm16-ecp384
                                dpd_action = restart
                                close_action = start
                                start_action = start
                        }
                        home-lan {
                                remote_ts = 192.168.88.0/24
                                esp_proposals = aes256gcm16-ecp384
                                dpd_action = restart
                                close_action = start
                                start_action = start
                        }
                        home-invitel {
                                remote_ts = 192.168.100.0/24
                                esp_proposals = aes256gcm16-ecp384
                                dpd_action = restart
                                close_action = start
                                start_action = start
                        }
                }
        }
}

secrets {
        ike-local {
                id = 37.17.x.x
                secret = "preshared-secret-key-goes-here"
        }
        ike-remote {
                id = vpn.example.org
                secret = "preshared-secret-key-goes-here"
        }
}

For example when I ping home to 192.168.88.5 from sv1 then:

  • the OS checks the route table but found no 192.168.88.5 specific rule
  • the OS then checks the IPSec policy database for a matching policy
  • the home-lan policy matches so the OS hands out the packet to IPSec
  • IPSec encapsulates (encrypt) the packet and sends it over the home-lan tunnel
  • my home router receives the encapsulated (encrypted) packet, finds a matching policy in its own IPSec policy database, decapsulate (decrypt) the packet and sends the now unencrypten packet to 192.168.88.5
Related Topic