This is a continuation of my previous question in sending static routes from Freeradius DHCP server implementation in combination with Strongswan VPN server.
When debugging Freeradius using tcpdump and Wireshark I found out that I can send classless static routes from Freeradius DHCP server by through adding DHCP-Classless-Static-Route
and DHCP-Site-specific-25
(aka Microsoft static route) options to my DHCP-Discover
and DHCP-Request
sections of the dhcp server configuration file.
However: It appears that the static routes are not accepted by Microsoft VPN client if I set the default gateway to be 0.0.0.0
as suggested by Strongswan documentation.
At least I cannot find the advetised routes on my Windows client when using route print -4
.
Also I cannot add the routes manually on Windows client when I am using 0.0.0.0
as standard gateway over VPN interface.
However:
Lets say I want to access the subnet 192.168.200.0/24
over VPN and my VPN server assign the address 192.168.201.2/24
to my Windows client. Then it is actually possible to create a static route on windows client side by declaring that the subnet 192.168.200.0/24 is accessible via 192.168.201.2 using the windows command:
route add 192.168.200.0 mask 255.255.255.0 192.168.201.2
I know it looks a bit weird, but I can ping any host on the 192.168.200.0
subnet, so as long as it works I am happy. :-)
But: I would be more happy if I could do the same thing by advertising the routes from my VPN server instead of doing it manually on all VPN clients. :-)
That means I have to do a bit of dynamic programming to the DHCP configuration in Freeradius. I my case it means I have to make a reference to a perl module in DHCP-Discover and DHCP-request that grabs the assigned client vpn ip address, convert it into octets and combine it with the static routes that is also given as octets.
An example:
The subnet 192.168.200.0/24
will be encoded as 0x18c0a8c8
as subnet mask is encoded first.
The client 192.168.201.2/24
will be encoded as 0xc0a8c902
as it is just converting each number in the ip address to hex.
The final encoding for the route will be: 0x18c0a8c8c0a8c902
as it is just a concatination of the two strings.
I then have to use update reply
with the following code:
update reply {
&DHCP-Classless-Static-Route = 0x18c0a8c8c0a8c902
&DHCP-Site-specific-25 = 0x18c0a8c8c0a8c902
}
If there are any more routes then all the routes will be concatenated into one long string.
The tricky part:
Assume you have the default configuration of Freeradius DHCP server as found in freeradius/3.0/sites-available/dhcp
file.
The general structure of the file for DHCP-Discover and DHCP-Request is as follows:
dhcp DHCP-Request {
update reply {
&DHCP-Message-Type = DHCP-Ack
}
update reply {
# General DHCP options, such as default GW, DNS, IP-address lease time etc.
}
update control {
&Pool-Name := "vpn_pool"
}
dhcp_sqlippool
ok
}
Then as far as I have gathered I need to call my perl module after dhcp_sqlippool
has been called and before returning ok
, because dhcp_sqlippool
is the module that assigns the ipaddress to the VPN client.
That means my version would be something like:
dhcp DHCP-Request {
update reply {
&DHCP-Message-Type = DHCP-Ack
}
update reply {
# General DHCP options, such as default GW, DNS, IP-address lease time etc.
}
update control {
&Pool-Name := "vpn_pool"
}
dhcp_sqlippool
perl
# If perl module returned no error
if(ok) {
update reply {
# Perl-Route contains a hex encoded string with all routes.
&DHCP-Classless-Static-Route = Perl-Route
&DHCP-Site-specific-25 = Perl-Route
}
}
# Not sure if this one is needed?
update reply {
&DHCP-End-Of-Options = 255
}
ok
}
In order to make it work, I have to enable perl under the freeradius/3.0/mods-enabled
folder and modify the filename in freeradius/3.0/mods-enabled/perl
to point it to my perl module. Like for instance:
filename = ${modconfdir}/${.:instance}/dhcp/Options.pm
But how do I do reference the call to perl the right way?
I thought I had to enable the line func_post_auth = post_auth
in freeradius/3.0/mods-enabled/perl
and create a sub post_auth
section in my perl module to handle calls from Freeradius, but as far as I can see in my log I get the following error in Freeradius:
(8) perl: perl_embed:: module = /etc/freeradius/3.0/mods-config/perl/dhcp/Options.pm ,
func = post_auth exit status= Undefined subroutine &main::post_auth called.
...
(8) [perl] = fail
(8) } # dhcp DHCP-Discover = fail
So what is it that I am not seeing?