L2TP over IPsec using OpenSwan with Freeradius authentication on Ubuntu 16.04

This article is about the layer 2 tunneling protocol (L2TP) with IPsec to provide end-to-end encryption in the layer 2 VPN because security features are not available in L2TP.  The open source implementations of IPsec are StrongSwan and OpenSwan, both are supported on all Linux distributions. In this tutorial, OpenSwan is used to provide the security channel for L2TP VPN. Freeradius is a well-known open source tool which provides different types of authentication for users. Freeradius is used to authenticate the L2TP VPN user before establishing a secure channel. An android based client will be used for the L2TP based secure tunnel.

Installation of required packages

Following important packages will be installed on the Ubuntu 16.04 LTS. 

  • Freeradius Server/Client
  • Poptop Server
  • xl2tpd
  • Openswan for IPsec
  • MySQL Server/client
  • Bison & Flex
  • GMP development library

As shown below, most of the required packages are all available in the Ubuntu 16.04 LTS repository.

apt-get update

apt-get install -y mysql-server mysql-client freeradius-mysql pptpd xl2tpd

The following screenshot shows how the password for the user "root" of the MySQL database server is being set during the installation process.

The following packages are required for the OpenSwan installation from source on the Ubuntu 16.04 platform.

apt-get install -y build-essential libgmp3-dev bison flex

The Freeradius client and OpenSwan packages are not available in the repository, so both tools have been installed from source.

Installation of the Freeradius client

Download the latest Freeradius client from the following link:

wget https://github.com/FreeRADIUS/freeradius-client/archive/master.zip
unzip master.zip

mv freeradius-client-master freeradius-client
cd freeradius-client

First, run the configure script with the prefix switch and install the software using the make command.

./configure --prefix=/

Configure Freeradius

make && make install

Installation of OpenSwan

The source code of the OpenSwan IPsec tool is available on the following link. Download the archive and unpack it.

wget https://download.openswan.org/openswan/openswan-latest.tar.gz
tar -xzf openswan-latest.tar.gz
cd openswan-*

Run the following command to compile and install OpenSwan.

make programs

Compile OpenSwan

make install  

Configuration

Before we start with the configuration of the installed packages, the following base configurations (iptables and sysctl) are required on the Ubuntu platform.

Enter following iptables rules for both networks (10.20.30.0/24 & 10.10.10.0/24) on the terminal.

iptables -t nat -I POSTROUTING -s 10.20.30.0/24 -j SNAT --to 192.168.15.4
iptables -t nat -I POSTROUTING -s 10.10.10.0/24 -j SNAT --to 192.168.15.4

Above rules should be saved into the /etc/iptables.rc file to apply them at boot time.

chmod +x /etc/iptables.rc
sed -i "/iptables.rc/d" /etc/rc.local
sed -i "1a/etc/iptables.rc" /etc/rc.local


Add the following lines in the /etc/sysctl.conf file to enable forwarding on the Linux machine.

net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1

Run the following command to apply changes.

sysctl -p


Configuration of the Freeradius Server

Run the following command to change the password for freeradius.

sed -i "s/PASSWORD('radpass')/PASSWORD('test')/g" /etc/freeradius/sql/mysql/admin.sql

The following MySQL commands will configure the Freeradius server on Ubuntu.

mysql --protocol=tcp -h localhost -u root -ptest
create database radius  # create DB radius

mysql --protocol=tcp -h localhost -u root -ptest radius < /etc/freeradius/sql/mysql/admin.sql

mysql --protocol=tcp -h localhost -u root -ptest radius < /etc/freeradius/sql/mysql/cui.sql

Adding a proper date to fix the invalid default value issue in /etc/freeradius/sql/mysql/cui.sql.

After correction in the /etc/freeradius/sql/mysql/cui.sql file and rerun above command to fix the above error.

mysql --protocol=tcp -h localhost -u root -ptest radius < /etc/freeradius/sql/mysql/ippool.sql

mysql --protocol=tcp -h localhost -u root -ptest radius < /etc/freeradius/sql/mysql/nas.sql

mysql --protocol=tcp -h localhost -u root -ptest radius < /etc/freeradius/sql/mysql/schema.sql

mysql --protocol=tcp -h localhost -u root -ptest radius < /etc/freeradius/sql/mysql/wimax.sql


Run the folowing sed command to change the default password of user "radius".  In this tutorial, the password for the user "radius" is "test". Chose a secure password on your server.

sed -i "s/password = \"radpass\"/password = \"test\"/g" /etc/freeradius/sql.conf

Creating a soft link for the sql configuration in the modules directory of the Freeradius server.

ln -sf /etc/freeradius/sql.conf /etc/freeradius/modules/sql


Following files are not present on Ubuntu 16.04, therefore, create all required files with the described content.

  • /etc/freeradius/modules/hourlylytraffic
  • /etc/freeradius/modules/dailytraffic
  • /etc/freeradius/modules/monthlytraffic

/etc/freeradius/modules/hourlytraffic

sqlcounter hourlytrafficcounter {
    counter-name = Hourly-Traffic
    check-name = Hourly-Traffic
    sqlmod-inst = sql
    key = User-Name
    reset = 1h
    query = "SELECT SUM(acctinputoctets + acctoutputoctets) DIV 1048576 FROM radacct WHERE UserName='%{%k}' AND UNIX_TIMESTAMP(AcctStartTime) > '%b'"
}

/etc/freeradius/modules/dailytraffic


sqlcounter dailytrafficcounter {
    counter-name = Daily-Traffic
    check-name = Daily-Traffic
    sqlmod-inst = sql
    key = User-Name
    reset = daily
    query = "SELECT SUM(acctinputoctets + acctoutputoctets) DIV 1048576 FROM radacct WHERE UserName='%{%k}' AND UNIX_TIMESTAMP(AcctStartTime) > '%b'"
}


/etc/freeradius/modules/monthlytraffic


sqlcounter monthlytrafficcounter {
    counter-name = Monthly-Traffic
    check-name = Monthly-Traffic
    sqlmod-inst = sql
    key = User-Name
    reset = monthly
    query = "SELECT SUM(acctinputoctets + acctoutputoctets) DIV 1048576 FROM radacct WHERE UserName='%{%k}' AND UNIX_TIMESTAMP(AcctStartTime) > '%b'"
}

The following file is important for freeradius server configuration. Our running configurations are given below.

/etc/freeradius/sites-enabled/default

authorize {
    preprocess
    chap
    mschap
    digest
    suffix
    eap {
        ok = return
    }
    files
    sql
    expiration
    logintime
    pap
    hourlytrafficcounter
    dailytrafficcounter
    monthlytrafficcounter
}
authenticate {
    Auth-Type PAP {
        pap
    }
    Auth-Type CHAP {
        chap
    }
    Auth-Type MS-CHAP {
        mschap
    }
    digest
    unix
    eap
}
preacct {
    preprocess
    acct_unique
    suffix
    files
}
accounting {
    detail
    unix
    radutmp
    sql
    exec
    attr_filter.accounting_response
}
session {
    radutmp
    sql
}
post-auth {
    sql
    exec
    Post-Auth-Type REJECT {
        attr_filter.access_reject
    }
}
pre-proxy {
}
post-proxy {
    eap
}

Use the following command to restart the freeradius server and to verify the configuration.

/etc/init.d/freeradius restart


Configuration of the Freeradius client

Following command sets the hostname and secret in the "servers" file of the freeradius client. 

echo -e "localhost\ttesting123" >> /etc/radiusclient/servers

    

Create the dictionary.microsoft configuration file for Windows based clients.

vi /etc/radiusclient/dictionary.microsoft
#
#       Microsoft's VSA's, from RFC 2548
#
#       \$Id: poptop_ads_howto_8.htm,v 1.8 2008/10/02 08:11:48 wskwok Exp \$
#
VENDOR          Microsoft       311     Microsoft
BEGIN VENDOR    Microsoft
ATTRIBUTE       MS-CHAP-Response        1       string  Microsoft
ATTRIBUTE       MS-CHAP-Error           2       string  Microsoft
ATTRIBUTE       MS-CHAP-CPW-1           3       string  Microsoft
ATTRIBUTE       MS-CHAP-CPW-2           4       string  Microsoft
ATTRIBUTE       MS-CHAP-LM-Enc-PW       5       string  Microsoft
ATTRIBUTE       MS-CHAP-NT-Enc-PW       6       string  Microsoft
ATTRIBUTE       MS-MPPE-Encryption-Policy 7     string  Microsoft
# This is referred to as both singular and plural in the RFC.
# Plural seems to make more sense.
ATTRIBUTE       MS-MPPE-Encryption-Type 8       string  Microsoft
ATTRIBUTE       MS-MPPE-Encryption-Types  8     string  Microsoft
ATTRIBUTE       MS-RAS-Vendor           9       integer Microsoft
ATTRIBUTE       MS-CHAP-Domain          10      string  Microsoft
ATTRIBUTE       MS-CHAP-Challenge       11      string  Microsoft
ATTRIBUTE       MS-CHAP-MPPE-Keys       12      string  Microsoft encrypt=1
ATTRIBUTE       MS-BAP-Usage            13      integer Microsoft
ATTRIBUTE       MS-Link-Utilization-Threshold 14 integer        Microsoft
ATTRIBUTE       MS-Link-Drop-Time-Limit 15      integer Microsoft
ATTRIBUTE       MS-MPPE-Send-Key        16      string  Microsoft
ATTRIBUTE       MS-MPPE-Recv-Key        17      string  Microsoft
ATTRIBUTE       MS-RAS-Version          18      string  Microsof