Authenticate OpenVPN Clients Thru the Freeradius Server

Authenticate OpenVPN Clients Freeradius Server

Introduction

The FreeRADIUS Server is a daemon for unix and unix like operating systems which allows one to set up a radius protocol server, which can be used for Authentication and Accounting various types of network access. To use the server, you also need a correctly setup client which will talk to it. Samples are hotspots, vpn protocols such as openvpn, strongswan or softether and some other router OS.

OpenVPN is an open-source software application that implements virtual private network (VPN) techniques for creating secure point-to-point or site-to-site connections in routed or bridged configurations and remote access facilities. It uses a custom security protocol that utilizes SSL/TLS for key exchange.

For this project we will configure openvpn to authenticate over our newly setup freeradius server. Once the client enters his/her username the radiusplugin will then relay this information to freeradius to verify if the credentials exists in the radius database and if the user is allowed. Once radius has confirmed that the user is allowed to login it will reply with an access-accept packet to openvpn server to allow the client.


Prerequisites

In this tutorial we will assume the following:

  • That you have successfully setup openvpn server (if not please take a look at this guide[1])
  • That freeradius is already setup and configured for use (if it is not yet installed please follow this tutorial[2])

Once all the ingredients are ready we will start modifying our openvpn configuration to authenticate via freeradius. This guide will be applicable for CentOS/Fedora and Ubuntu/Debian.


Installing Radiusplugin

Go to your openvpn server (in this case I am using CentOS 7 64bit) and login as root.
Then install the required dependencies to successfully compile our radiusplugin.

Ubuntu/Debian:

apt-get install libgcrypt11 libgcrypt11-dev build-essential

CentOS/Fedora:

yum install libgcrypt libgcrypt-devel gcc-c++

After installing the dependencies we can now download the radiusplugin source. We will create a folder and download the source files from there.

Ubuntu/Debian/CentOS/Fedora:

mkdir /etc/radiusplugin

Then we will go inside the folder and download the source.

Ubuntu/Debian/CentOS/Fedora:

cd /etc/radiusplugin/

Ubuntu/Debian/CentOS/Fedora:

wget http://www.nongnu.org/radiusplugin/radiusplugin_v2.1a_beta1.tar.gz

After we download we need to extract the source files.

Ubuntu/Debian/CentOS/Fedora:

tar xvf radiusplugin_v2.1a_beta1.tar.gz

Then we will go inside the radiusplugin folder and execute the make command.
Ubuntu/Debian/CentOS/Fedora:

cd radiusplugin_v2.1a_beta1
make

We will get the file radiusplugin.so after compiling from source and we will need to transfer this file to a better location, most probably in the openvpn folder. But first we will need to create a radius folder inside openvpn.
Ubuntu/Debian/CentOS/Fedora:

mkdir /etc/openvpn/radius

Ubuntu/Debian/CentOS/Fedora:

cp -r radiusplugin.so /etc/openvpn/radius

Creating Radiusplugin Configuration file

Next we will make a file we will call radius.cnf inside the '/etc/openvpn/radius/' folder. This will be the radiusplugin configuration file consisting of the details of our radius server including the radius server ip address and secret.
Ubuntu/Debian/CentOS/Fedora:

nano /etc/openvpn/radius/radius.cnf

And then copy the below details and paste it in the file.

NAS-Identifier=000.000.000.000_TCP_443

# The service type which is sent to the RADIUS server
Service-Type=5

# The framed protocol which is sent to the RADIUS server
Framed-Protocol=1

# The NAS port type which is sent to the RADIUS server
NAS-Port-Type=5

# The NAS IP address which is sent to the RADIUS server
NAS-IP-Address=000.000.000.000

# Path to the OpenVPN configfile. The plugin searches there for
# client-config-dir PATH   (searches for the path)
# status FILE              (searches for the file, version must be 1)
# client-cert-not-required (if the option is used or not)
# username-as-common-name  (if the option is used or not)

OpenVPNConfig=/etc/openvpn/443_tcp.conf


# Support for topology option in OpenVPN 2.1
# If you don't specify anything, option "net30" (default in OpenVPN) is used. 
# You can only use one of the options at the same time.
# If you use topology option "subnet", fill in the right netmask, e.g. from OpenVPN option "--server NETWORK NETMASK"  
subnet=255.255.255.0
# If you use topology option "p2p", fill in the right network, e.g. from OpenVPN option "--server NETWORK NETMASK"
# p2p=10.8.0.1


# Allows the plugin to overwrite the client config in client config file directory,
# default is true
overwriteccfiles=true

# Allows the plugin to use auth control files if OpenVPN (>= 2.1 rc8) provides them.
# default is false
# useauthcontrolfile=false

# Only the accouting functionality is used, if no user name to forwarded to the plugin, the common name of certificate is used
# as user name for radius accounting.
# default is false
# accountingonly=false


# If the accounting is non essential, nonfatalaccounting can be set to true. 
# If set to true all errors during the accounting procedure are ignored, which can be
# - radius accounting can fail
# - FramedRouted (if configured) maybe not configured correctly
# - errors during vendor specific attributes script execution are ignored
# But if set to true the performance is increased because OpenVPN does not block during the accounting procedure.
# default is false
nonfatalaccounting=false

# Path to a script for vendor specific attributes.
# Leave it out if you don't use an own script.
# vsascript=/root/workspace/radiusplugin_v2.0.5_beta/vsascript.pl

# Path to the pipe for communication with the vsascript.
# Leave it out if you don't use an own script.
# vsanamedpipe=/tmp/vsapipe

# A radius server definition, there could be more than one.
# The priority of the server depends on the order in this file. The first one has the highest priority.
server
{
    # The UDP port for radius accounting.
    acctport=1813
    # The UDP port for radius authentication.
    authport=1812
    # The name or ip address of the radius server.
    name=192.168.0.153
    # How many times should the plugin send the if there is no response?
    retry=1
    # How long should the plugin wait for a response?
    wait=1
    # The shared secret.
    sharedsecret=mysecret
}

Where:
mysecret is the freeradius server secret we configured on freeradius. You can change this depending on your freeradius setup.
192.168.0.153 is the ip address of our radius server. This will surely need to be changed.
000.000.000.000 is the ip address of our OpenVPN server. This will also need to be changed.
/etc/openvpn/443_tcp.conf is the path to our OpenVPN configuration file. Each OpenVPN configuration file needs its own radiusplugin configuration file as well. Again, this should be changed depending on your setup.

if all else is done save the file and exit.

We are done with radiusclient and we will configure openvpn next.


Configuring OpenVPN for Radius Authentication

To configure OpenVPN for radius authentication we will need to add several lines of into our OpenVPN configuration file. In our earlier tutorial[3] we setup OpenVPN with Certificate authentication and for this guide we will be using username / password authentication.

From our last OpenVPN configuration, we will need to change it like below:

port 443
proto tcp
dev tun
server 10.11.0.0 255.255.255.0
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key
dh /etc/openvpn/easy-rsa/keys/dh2048.pem
plugin /etc/openvpn/radius/radiusplugin.so /etc/openvpn/radius/radius.cnf ifconfig-pool-persist ipp.txt persist-key
persist-tun
keepalive 10 60
reneg-sec 0
comp-lzo
tun-mtu 1468
tun-mtu-extra 32
mssfix 1400
push "persist-key"
push "persist-tun"
push "redirect-gateway def1"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
status /etc/openvpn/443.log
verb 3

What we added:

plugin /etc/openvpn/radius/radiusplugin.so /etc/openvpn/radius/radius.cnf 

Is the path to the radiusclient configuration file and program.

ifconfig-pool-persist ipp.txt  

Is the file to be read by radiusplugin for accounting information.

Once all is done you can save the file and exit. Then we will restart openvpn to make the changes.
Ubuntu/Debian/CentOS/Fedora:

service openvpn restart

CentOS 7:

systemctl start openvpn@443_tcp.service

Connect from the OpenVPN client and login using your radius username & password credentials.


Thats it! You can now connect to OpenVPN server using your radius account. If you have some questions and clarifications please do not hesitate to comment below.

[1]: https://www.vpsserver.com/community/tutorials/7/setup-and-configuration-of-openvpn-server-on-centos-7-2/
[2]: https://www.vpsserver.com/community/tutorials/10/setup-and-configuration-of-freeradius-mysql-on-ubuntu-14-04-64bit/
[3]: https://www.vpsserver.com/community/tutorials/7/setup-and-configuration-of-openvpn-server-on-centos-7-2/

comments (3)

  • notjoe

    - 6 years ago

    Hey there,

    Great write-up but I am having some issues. I was wondering if I could ask you about a problem with the password that is hitting the Radius which is being provided by OpenVPN. I'd definitely compensate you for your services!

    • Mark

      - 6 years ago

      Hi,

      You can tell me what the issue is all about. For password issues you can check out the database column auth-type in the radcheck table. Make sure to enter the correct password type: eg. cleartext, md5 etc..

  • Houman

    - 3 years ago

    Hi Mark,

    That was a very useful tutorial. Sadly you chose radiusplugin, which is a decade old and very difficult to compile on latest operating systems, due to lack of libgcrypt11 (replaced now with libgcrypt20).

    Would you be able to use https://github.com/FreeRADIUS/pam_radius instead? Which seems to be the official plugin for connecting OpenVPN and Freeradius. There is not a single good tutorial on this topic. It would be a great opportunity.

    Best Regards, Houman