Setting up OpenVPN AS with FreeRADIUS AND stunnel

If you’re ever curious as to how do VPN service providers manage all their users and their authentication. I hope this might give you a little peek.

This article will serve to setup FreeRADIUS as the authentication mechanism, OpenVPN as the VPN protocol and stunnel as an introduction to obfuscating censorship. With all these setup, you’re one step closer to start providing VPN services.

Setup FreeRADIUS

Install Freeradius


  $ yum install freeradius freeradius-mysql

Create Freeradius Database

Install MySQL

  $ yum install mysql-server

Login to MySQL as root and create databases

  $ mysql -uroot -p
  mysql> create database radius;
  mysql> GRANT ALL ON radius.* TO [email protected] IDENTIFIED BY "radpass";
  mysql> use radius;
  mysql> SOURCE /etc/raddb/sql/mysql/schema.sql

_Create your first vpn user _

  mysql> use radius;
  mysql> INSERT INTO radcheck (username, attribute, op, value) VALUES ('chantra','Cleartext-Password',':=','chantrapass');

Configure Freeradius

Create /etc/raddb/sql.conf

# Connection info:
  server = "localhost"
  #port = 3306
  login = "radius"
  password = "radpass"

  # Database table configuration for everything except Oracle
  radius_db = "radius"


# /etc/raddb/radiusd.conf
$INCLUDE sql.conf  

Do the magical uncomments

# /etc/raddb/sites-available/default
# /etc/raddb/sites-available/inner-tunnel

  # uncomment the line containing 'sql'
#  /etc/raddb/sites-available/inner-tunnel

 # uncomment the line containing 'sql'


Change freeradius secret

  # /etc/raddb/clients.conf

  secret = testing123 # into something more awesome

Lets check radius!

  $ service radiusd start
  $ service radiusd stop

Setup OpenVPN AS

Grab OpenVPN

  $ wget
  $ rpm -i openvpn-as-1.8.3-CentOS5.x86_64.rpm

You should see:

The Access Server has been successfully installed in /usr/local/openvpn_as Configuration log file has been written to /usr/local/openvpn_as/init.log Please enter “passwd openvpn” to set the initial administrative password, then login as “openvpn” to continue configuration here: To reconfigure manually, use the /usr/local/openvpn_as/bin/ovpn-init tool.

Change OpenVPN password

  $ passwd openvpn

Login to OpenVPN admin

Access https://x:943/admin and login with your username/password

Under Authentication > General

You should see 4 options:

  • Local
  • PAM
  • Radius
  • LDAP

Select “Radius” and “update running server”

Authentication > Radius

Select “CHAP”


Add server ip of FreeRADIUS server and shared_secret (hint: “testing123” which was configured above)

Check “Enable RADIUS Accounting”

Hit “Update Running Server”

Hook FreeRADIUS and OpenVPN

Add OpenVPN server into FreeRADIUS records

In the FreeRADIUS server:

  $ vim /etc/raddb/clients.conf

  # find the line:
  # coa_server = coa

  # add the following below

  client OPENVPN_IP_HERE {
    secret    = YOUR SECRET HERE
      shortname = yourVPN # anyname
      nastype     = other
  $ sudo service radiusd restart


Setup STunnel

What is Stunnel?

STunnel Server

You can run this on the same server as your OpenVPN. For this example, we will run it on our same server.

  $ yum install stunnel

In your stunnel directory, sometimes at /etc/stunnel/

  $ openssl genrsa -out server.key 4096
  $ openssl req -new -key server.key -out server.csr
  $ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
  $ cat server.key > server.pem && cat server.crt >> server.pem

In /etc/stunnel/stunnel.conf

  # create if file doesn't exist
  sslVersion = all
  options = NO_SSLv2
  chroot = /var/lib/stunnel4/
  ; PID is created inside the chroot jail
  pid = /
  ; Debugging stuff (may useful for troubleshooting)
  ; debug = 7
  ; output = /var/log/stunnel4/stunnel4.log
  setuid = stunnel4
  setgid = stunnel4
  socket = l:TCP_NODELAY=1
  socket = r:TCP_NODELAY=1
  compression = zlib
  accept =
  connect =

2 things here, accept and connect accept should be the port that is listening to openvpn connections. In the case of hiding from Deep Packet Inspection, setting this to 443 will hide your OpenVPN connections underneath an unblockable port (SSL) connect should be the ip:port of your actual OpenVPN server that is listening.

Note: Ensure that you’re only accepting TCP connection in your OpenVPN AS Web Panel

  $ sudo service stunnel start

Stunnel Client

This should be run by your OpenVPN clients

Do the same setup as above, install stunnel via the distro’s package managers.

Your stunnel.conf on the client should look like this

client = yes
compression = zlib
client = yes
accept =
connect = STUNNEL_SERVER_IP:443

accept should always be your localhost with any port that you decide connect will point to your stunnel server and the port that it is listening to. In this example, its 443.

  $ sudo service stunnel start

Connecting to OpenVPN

To make your life easier, just go to https://openvpn_ip:943 and login with your username/password from FreeRADIUS.

You should see a link to download your connection settings (profile) for yourself.

It should look something like:

proto tcp
remote localhost # always set this to point to localhost if you're using stunnel
port 8088 # this should be the port that your stunnel is accepting connection
dev tun
dev-type tun
ns-cert-type server
reneg-sec 604800
sndbuf 100000
rcvbuf 100000
# NOTE: LZO commands are pushed by the Access Server at connect time.
# NOTE: The below line doesn't disable LZO.
comp-lzo no
verb 3

You’ll also need to add your own routing to your VPN server to ensure that traffic gets sent over there

# add the following just below
# ENDPOINT_IP being your OpenVPN server ip
route ENDPOINT_IP net_gateway