OpenVPN + Radius Plugin

Hi Everyone,

have any of you managed to setup OpenVPN with Radius plugin? I can’t find any documentation for this.

best regards
Sebastian

I am also interested in this one. I suppose it can be done through set interfaces openvpn vtun0 openvpn-option... or something similar. Has anyone had experience with that?

I have a working solution I created probably for 1.1.8 originally long ago, now it works well for us in 1.3. However, my solution has some limitations and was tested with Active Directory only. No other Radius server was ever tested, but I believe the solution will work with minor, if any, modifications with any Radius server.

A. I believe Radius authentication with OpenVPN server in VyOS cannot be configured natively. But there is a workaround. It persists over reboots and upgrades if you place all involved files and configurations under /config directory.
B. The limitation I mentioned above is that you will need to store your Radius secret in a configuration file (under /config directory) which must be world readable, i.e. it needs 0644 or better file permissions set. This is required, as we call radius authentication via script which runs under unprivileged user every time a remote client tries to login. That said, I believe this is acceptable as long as your whole infrastructure (vyos + radius server) is configured properly. Also, consider the fact that /config/config.boot file also may contain secrets and is also world-readable in standard VyOS installation. Anyway, you’ve been warned :slight_smile:

If you accept those disclaimers above, continue reading.

  1. Git clone this repo to /config/radtest/. Add execute file permissions if necessary to the .py files.
  2. Configure vyos for OpenVPN as you normally would, similar to the following (adjust freely as necessary). The most relevant part is about auth-user-pass-verify, script-security 2, and probably also username-as-common-name, verify-client-cert none, duplicate-cn options):
# show interfaces openvpn vtun0
 description OPENVPN
 encryption {
     ncp-ciphers aes256gcm
     ncp-ciphers aes192gcm
     ncp-ciphers aes128gcm
 }
 firewall {
     in {
         name VTUN0-IN
     }
     local {
         name VTUN0-LOCAL
     }
     out {
         name VTUN0-OUT
     }
 }
 hash sha1
 local-host 195.xxx.xxx.xxx
 local-port 1194
 mode server
 openvpn-option duplicate-cn
 openvpn-option "tls-auth /config/auth/keys/ta.key 0"
 openvpn-option "keepalive 10 30"
 openvpn-option "script-security 2"
 openvpn-option "tmp-dir /dev/shm"
 openvpn-option tls-server
 openvpn-option "tls-version-min 1.2"
 openvpn-option "verify-client-cert none"
 openvpn-option username-as-common-name
 openvpn-option "auth-user-pass-verify /config/auth/ovpnauth-radius.sh via-file"
 openvpn-option "data-ciphers-fallback aes-192-cbc"
 openvpn-option "push "route 192.168.xxx.0 255.255.255.0 vpn_gateway""
 openvpn-option "push "route 172.16.xxx.0 255.255.255.0 vpn_gateway""
 persistent-tunnel
 protocol udp
 server {
     domain-name mydomain.com
     name-server 192.168.xxx.xxx
     name-server 192.168.xxx.xxx
     push-route 172.16.xxx.0/24 {
     }
     push-route 192.168.xxx.0/24 {
     }
     subnet 192.168.xx.0/24
     topology subnet
 }
 tls {
     ca-cert-file /config/auth/keys/ca.crt
     cert-file /config/auth/keys/server.crt
     dh-file /config/auth/dh3072.pem
     key-file /config/auth/keys/server.key
 }
  1. Create the following file /config/auth/ovpnauth-radius.sh, give world read and execute file permission to it, set Radius secret and address inside:
#!/bin/sh

# Config parameters

secret="************************************************"
NASidentifier="Radtest"
RADIUShost="192.168.xxx.xxx"
dictFILE="/config/radtest/pyRadtest-master/dictRadius.xml"

# End of config parameters

userpass=`cat $1`
username=`echo $userpass | awk '{print $1}'`
password=`echo $userpass | awk '{print $2}'`

clearpassword=$password

/config/radtest/pyRadtest-master/Radtest.py -host $RADIUShost -u $username -p $clearpassword -s $secret -nas_identifier $NASidentifier -f $dictFILE > /dev/shm/$$.calc 2>&1
if ! [ -z `cat /dev/shm/$$.calc | grep "Access-Accept" | awk -F: '{print $3}'` ]; then
  rm /dev/shm/$$.calc
  # authentication successfull
  exit 0
else
  rm /dev/shm/$$.calc
  # authentication failed
  exit 1
fi

# authentication failed
exit 1
  1. If necessary, edit the parameter _called_station_id in the file /config/radtest/pyRadtest-master/Radtest.py to whaterver your VyOS router to be presented to the Radius server if this is required as to your Radius server configuration. For example:
_called_station_id="vyos-router"
  1. Enjoy :slightly_smiling_face:

Important: You may need to check your Radius server response with the log files and may need to edit the actual authentication string in the script file above prior to production use. Please test extensively before you go live with that setup. The configuration of the Radius server side is out of the scope of this question, I guess.

Hope this helps.

1 Like

@dutty many thanks for the time you invested to help with this issue! I will check when I find some time and let you know. As you say, thorough testing is needed to check the response of a specific Radius server in auth-user-pass-verify. We use FreeRadius. I’m glad there is a real Linux based router like VyOS, so one can even think of solutions like this one.

Regards
Milos

I don’t know if it’s any different with OpenVPN, but I have setup OpenConnect VPN (ocserv) with RADIUS authentication only using the configuration shell.

There is a task with this issue ⚓ T2541 Openvpn Radius authentication support. I hope it will get developers interested soon. In the meantime, does anyone use Debian -- Details of package openvpn-auth-radius in buster in the form of openvpn-option method? A working example would be nice to have.