I am trying to setup a Strongswan server that runs in split tunnel mode, which means I have to disable using the server as a default gateway on client side and also disable classfull routing in the VPN client.
I then have to send DHCP option 121
(classless static route) and DHCP option 249
(Microsoft variant of classless static route) when a client request an ip-address from Strongswan VPN server.
I need both option 121 and 249 in order to account for all combinations of operating systems that can connect (Windows, Linux, Android, MacOS, iPhones etc).
I did not have that much success in using ISC DHCP server with Strongswan, since it was not happy to listen on trafic over a WireGuard interface. It said it didn't support WireGuard or loopback interface and it basically ignored DHCP requests comming from the Strongswan VPN server on the other side of the wireguard link.
So I switched to Freeradius DHCP server, since Strongswan was already using Freeradius for user authentication when logging into the Strongswan VPN server.
After all: How hard could it be, since I was just going to add "a few config files to Freeradius"? :-)
Turns out it is a little tricky, but I managed to get Freeradius to listen to traffic on my Wireguard link using the following configuration:
listen {
type = dhcp
# The subnet 192.168.200.0/24 is my WireGuard subnet that act as a
# VPN site-to-site backbone.
ipaddr = 192.168.200.4
src_ipaddr = 192.168.200.4
port = 67
interface = wg0
broadcast = no
}
In my strongswan.conf file I have the following:
charon {
load_modular = yes
plugins {
include strongswan.d/charon/*.conf
dhcp {
force_server_address = yes
identity_lease = yes
interface = wg0
load = yes
server = 192.168.200.4
use_server_port = yes
}
}
}
Anyhow: I have gotten Freeradius DHCP server to handout ip-addresses to VPN client when Strongswan sends DHCP-Discover or DHCP-Request to Freeradius DHCP server, but somehow I cannot get it to send the static routes?
I can see in the file dictionary
that resides in /etc/freeradius/3.0
that the dictionary for dhcp specific options is being loaded from /usr/share/freeradius/dictionary.dhcp
.
In that file I can find the two following informations:
# Classless Static Route Option
ATTRIBUTE DHCP-Classless-Static-Route 121 octets
...
ATTRIBUTE DHCP-Site-specific-25 249 octets
According to StrongSwan Wiki I can set the next hop gateway for my static route to 0.0.0.0
, so if I want to tell that the subnet 192.168.200.0/24
is accessible through the VPN link I have to encode the route as octets written as hex code using the order: {CIDR}{Network}{Gateway}.
So 192.168.200.0/24 via 0.0.0.0
becomes 0x18C0A8C800000000
So I thought that I should just modify the update reply
in dhcp DHCP-Discover
and dhcp DHCP-Request
to the following:
update reply {
&DHCP-Domain-Name-Server = 192.168.200.1
&DHCP-Subnet-Mask = 255.255.255.0
&DHCP-IP-Address-Lease-Time = 86400
&DHCP-Classless-Static-Route = 0x18C0A8C800000000
&DHCP-Site-specific-25 = 0x18C0A8C800000000
&DHCP-DHCP-Server-Identifier = 192.168.200.4
}
However I cannot see that the route is being pushed to my routing table, when I try to login via Windows VPN client.
So what am I missing?
Update
Turns out the encoding for DHCP Option 249 is a tiny bit different than DHCP option 121.
At least according to Microsoft webpage for DHCP option 249.
However I am getting a little bit confused to how this translates to encoding in Freeradius.
As far as I can tell, I have already told that the header begins with DHCP option 249, due to how DHCP-Site-specific-25
is being defined in the dictionary.
But Microsoft webpage says that the first byte after that is the length of the all the routes in the DHCP measured in bytes, followed by the same encoding for the routes as defined in DHCP option 121.
So the encoded route 0x18C0A8C800000000
must be prepended with 08
, so line with Microsoft Static Routes now reads:
&DHCP-Site-specific-25 = 0x0818C0A8C800000000
I have tested with that modification, but still no luck.
Second update
A little more fiddeling with the configuration file for DHCP and then monitoring via tcpdump
on what is actually going on.
Whenever a client log on to Strongswan the request for an IP address is forwarded to DCHP server, so in essense Strongswan is acting as DHCP relay agent if I got that part right.
In tcpdump i can see the following exchange taking place:
Client sends DHCP Discover
Server replies with DHCP Offer
Client sends DHCP Request
Server replies with DHCP ACK
My first takeaway from monitoring tcpdump is that I dont have to calculate bytelength on the encoded static route, because that garbles up the output from tcpdump.
In other words encoding for DHCP option 121 and DHCP option 249 is the same.
Further reading suggest static routing is associated with DHCP Information, but I never saw that packet in tcpdump.
The output from tcpdump when running with my initial configuration of update reply
above gives the following session:
tcpdump: listening on wg0, link-type RAW (Raw IP), capture size 262144 bytes
10:58:17.185671 IP (tos 0x0, ttl 64, id 46089, offset 0, flags [none], proto UDP (17), length 300)
192.168.200.1.67 > 192.168.200.4.67: [udp sum ok] BOOTP/DHCP, Request from 7a:a7:8f:1f:b7:88, length 272, xid 0x5c9716b5, Flags [none] (0x0000)
Gateway-IP 192.168.200.1
Client-Ethernet-Address 7a:a7:8f:1f:b7:88
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Discover
Client-ID Option 61, length 22: hardware-type 108, 61:73:73:65:40:68:6f:6d:65:2e:6d:6f:6c:67:61:61:72:64:2e:65:75
Parameter-Request Option 55, length 2:
Domain-Name-Server, Netbios-Name-Server
END Option 255, length 0
10:58:17.195305 IP (tos 0x0, ttl 64, id 19475, offset 0, flags [none], proto UDP (17), length 328)
192.168.200.4.67 > 192.168.200.1.67: [bad udp cksum 0x129d -> 0x9ffd!] BOOTP/DHCP, Reply, length 300, xid 0x5c9716b5, Flags [none] (0x0000)
Your-IP 192.168.201.13
Gateway-IP 192.168.200.1
Client-Ethernet-Address 7a:a7:8f:1f:b7:88
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Offer
Subnet-Mask Option 1, length 4: 255.255.255.0
Domain-Name-Server Option 6, length 4: 192.168.200.1
Lease-Time Option 51, length 4: 86400
Server-ID Option 54, length 4: 192.168.200.4
Classless-Static-Route Option 121, length 8: (192.168.200.0/24:0.0.0.0)
Classless-Static-Route-Microsoft Option 249, length 8: (192.168.200.0/24:0.0.0.0)
END Option 255, length 0
PAD Option 0, length 0, occurs 12
10:58:17.219444 IP (tos 0x0, ttl 64, id 46098, offset 0, flags [none], proto UDP (17), length 312)
192.168.200.1.67 > 192.168.200.4.67: [udp sum ok] BOOTP/DHCP, Request from 7a:a7:8f:1f:b7:88, length 284, xid 0x5c9716b5, Flags [none] (0x0000)
Gateway-IP 192.168.200.1
Client-Ethernet-Address 7a:a7:8f:1f:b7:88
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: Request
Client-ID Option 61, length 22: hardware-type 108, 61:73:73:65:40:68:6f:6d:65:2e:6d:6f:6c:67:61:61:72:64:2e:65:75
Requested-IP Option 50, length 4: 192.168.201.13
Server-ID Option 54, length 4: 192.168.200.4
Parameter-Request Option 55, length 2:
Domain-Name-Server, Netbios-Name-Server
END Option 255, length 0
10:58:17.228663 IP (tos 0x0, ttl 64, id 19477, offset 0, flags [none], proto UDP (17), length 328)
192.168.200.4.67 > 192.168.200.1.67: [bad udp cksum 0x129d -> 0x9d02!] BOOTP/DHCP, Reply, length 300, xid 0x5c9716b5, Flags [none] (0x0000)
Your-IP 192.168.201.8
Gateway-IP 192.168.200.1
Client-Ethernet-Address 7a:a7:8f:1f:b7:88
Vendor-rfc1048 Extensions
Magic Cookie 0x63825363
DHCP-Message Option 53, length 1: ACK
Subnet-Mask Option 1, length 4: 255.255.255.0
Domain-Name-Server Option 6, length 4: 192.168.200.1
Lease-Time Option 51, length 4: 86400
Server-ID Option 54, length 4: 192.168.200.4
Classless-Static-Route Option 121, length 8: (192.168.200.0/24:0.0.0.0)
Classless-Static-Route-Microsoft Option 249, length 8: (192.168.200.0/24:0.0.0.0)
END Option 255, length 0
PAD Option 0, length 0, occurs 12
The fact that I can see Classless-Static-Route
and Classless-Static-Route-Microsoft
being announced and they indeed tells that the subnet 192.168.200.0/24
is available through the tunnel, gives me hint that I am on the right track.
However:
The route does still not appear in my routing table.
Perhaps it has something todo with the following line:
192.168.200.4.67 > 192.168.200.1.67: [bad udp cksum 0x129d -> 0x9ffd!] BOOTP/DHCP, Reply, length 300, xid 0x5c9716b5, Flags [none] (0x0000)
Anyone knows what is what needs fixing?