0

I am trying to setup Strongswan for VPN split tunneling.

What I want is only the subnets 10.88.0.0/16 and 10.0.200.0/24 is accessible through the VPN tunnel. Everyting else is handled throught the default gateway for the network.

All clients are assigned an ip adress belonging to the 10.0.201.0/24 subnet.

In my configuration file I have among others the following:

# Default login method
eap-defaults {
  remote {
   auth = eap-radius
   id = %any
   eap_id = %any
  }
}

connections
{
  conn-unix : conn-defaults, eap-defaults {
    children {
      net {
        local_ts = 10.0.200.0/24, 10.88.0.0/16
      }

      esp_proposals = aes128gcm128-x25519
    }

    pools = IkeVPN-ipv4
    proposals = aes128-sha256-x25519
  }

  conn-windows : conn-defaults, eap-defaults {
    children {
      net {
        local_ts = 10.0.200.0/24, 10.88.0.0/16
      }

      esp_proposals = aes256-sha256-prfsha256-modp1024
    }

    proposals = aes256-sha256-prfsha256-modp1024
    pools = IkeVPN-ipv4
  }
}

pools
{
  IkeVPN-ipv4 {
    addrs = 10.0.201.0/24
    dns = 10.0.88.2
  }
}

When I login over VPN it is possible to ping hosts belonging to 10.88.0.0/16 and 10.0.200.0/24, so I know I can use the VPN tunnel.

However:

If I try to access any other ressource on the Internet while still being connected to the VPN, then I cannot even ping the ip adress belonging to that ressourse.

In my routing table on my Windows computer I can find the following entries:

Partial routing table for a Windows client connected to VPN server

I know that when you have two routes to a given subnet like 0.0.0.0/0 in the routing table, then whatever rule has the lowest metric wins and traffic is forwarded using that rule.

However I do not want the VPN server to install a default route via VPN, but rather only tell that the subnets 10.88.0.0/16 and 10.0.200.0/24 has to be routed via VPN.

What I want is that I see a routing table closer to this without having to edit the routing table by hand on every VPN client:

Desired routing table

So how do I go about doing that?

  • Please have a look at [this](https://wiki.strongswan.org/projects/strongswan/wiki/ForwardingAndSplitTunneling#Split-Tunneling-with-IKEv2) and [this](https://wiki.strongswan.org/projects/strongswan/wiki/WindowsClients#Split-routing-on-Windows-10-and-Windows-10-Mobile) page on the strongSwan wiki. – ecdsa Feb 21 '22 at 09:02
  • Well Strongswan needs to update their documentation then, because it appears Windows DOES set default gateway when you register a new vpn connection. At least for ipv4. – Lasse Michael Mølgaard Feb 21 '22 at 10:40
  • I had to disable `default routing` and enable `disable class based routing addition` (translation from danish) in order to remove the default gateway or at least just traffic for the `10.0.0.0/8` subnet via VPN. What I was hoping for was Strongswan had something equivalent to OpenVPNs `push route` directive. – Lasse Michael Mølgaard Feb 21 '22 at 10:52
  • Searching a bit more on Google told me I have to push `dhcp option code 121 and 249` to the clients. Option code 121 works with Linux and older Windows versions, while option code 249 works with newer Windows versions (newer than Vista) and MacOS. However Strongswan does not use standard gateway, so how does this factor in when pushing routes to clients? – Lasse Michael Mølgaard Feb 22 '22 at 09:17

1 Answers1

0

Turns out my issue with split tunnelling was placed in a completely different area, due to I have 2 routers at home so my home network is something like: ISP <-> R1 <-> R2 <-> Me.

... and R1 was configured to an IP address in the 10.0.0.0/24 range.

When you disable default routing in Windows VPN client, it will then add a class based route insted, so in my case it will add a route that sends everything for 10.0.0.0/8 over VPN, which ment it would of course conflict with setup on router R1.

That is why wanted to remove route 10.0.0.0/8 altogether and push routes for the subnets 10.88.0.0/16 and 10.0.200.0/16 over VPN.

Turns out it is doable.

The class based routing is removed by enabling disable class based routing when you disable default routing in the VPN client.

In Strongswan you have to forward dhcp request from the clients to a DHCP server that has implemented RFC3442.

So in my configuration above I have to replace all occurences of pools = IkeVPN-ipv4 with pools = dhcp and in strongswan.conf I have to add the following to charon plugins subsection:

charon {
  plugins {
    ...
    dhcp {
      server = ip.address.of.dhcp.server
    }
  }
}

I can then delete the whole pools section at the bottom of my configuration.

There are a few more options available which can be read here.

The guide from Strongswan from @ecdsa hint gave some of the information, but that guide is Windows specific, so it will not tell you how to handle Linux, MacOS or Android devices. RFC3442 will however handle the generic case.

In a nutshell what RFC3442 says is that you have to send the following two dhcp options:

  • option 121 (related to Linux, Android and Windows Vista or older)
  • option 249 (related to Windows 7 or newer and MacOS)

Basically you have to encode each route as an array of int using the following syntax:

x,y1,y2,y3,y4,z1,z2,z3,z4

Where:

  • x: CIDR netmask
  • y1 - y4: is the network you want to route, but with the twist that when the tail of the sequence y1,y2,y3,y4 is all zeroes, they are then omitted.
  • z1 - z4: is the nexthop gateway to the subnet.

If there is more than one route to be send via DHCP, then you will have to add another sequence similar to the above at the tail of the first router.

According to Strongswan documentation I can replace standard gateway with 0.0.0.0.

That means my route to 10.0.200.0/24 gets encoded as 24,10,0,200,0,0,0,0 and 10.88.0.0/16 gets encoded to 16,10,88,0,0,0,0.

Combining the two gives me 24,10,0,200,0,0,0,0,16,10,88,0,0,0,0, which leads me to the following configuration in ISC DHCP server:

option rfc-routes code 121 = array of integer 8;
option ms-routes code 249 = array of integer 8;

default-lease-time 21600;
max-lease-time 86000;

subnet 10.0.201.0 netmask 255.255.255.0 {
    range 10.0.201.1 10.0.201.254;

    option domain-name "example.com";
    option domain-name-servers ip.address.of.dns.server;

    option rfc-routes 24,10,0,200,0,0,0,0,16,10,88,0,0,0,0;
    option ms-routes 24,10,0,200,0,0,0,0,16,10,88,0,0,0,0;
}

I hope this helps anybody who is strunggeling with the split tunneling.