Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Unifi Security Gateway (USG) OpenVPN server with RADIUS authentication

Last Updated: 8/30/18

Details

I wanted to run an OpenVPN server on the USG. Since it has a Radius server built in, I figured this would be a much better way to handle OpenVPN authentication. Make sure you have the Radius server enabled on your USG under Settings > Services > Radius > Server in the controller. Add OpenVpn users under Settings > Services > Radius > Server.

Thanks to the following resources in helping to configure this:

Configure easy-rsa and generate keys

SSH into your USG and run the following commands

sudo bash
curl -O http://ftp.us.debian.org/debian/pool/main/e/easy-rsa/easy-rsa_2.2.2-1~bpo70+1_all.deb
sudo dpkg -i easy-rsa_2.2.2-1~bpo70+1_all.deb

# Generate Keys
cd /usr/share/easy-rsa
. vars
./clean-all
./build-ca

# Give it a common-name like "OpenVPN CA"
./build-key-server server

# Set the common name to “server”
# Answer yes to signing the certificate and commiting it.
./build-dh

# Copy the generated keys
mkdir /config/auth/keys/
cp keys/* /config/auth/keys/

Configure OpenVPN on the USG

configure
set interfaces openvpn vtun0 mode server

# Make sure to use a subnet not in use anywhere else on your USG
set interfaces openvpn vtun0 server subnet 10.72.1.0/24
set interfaces openvpn vtun0 tls ca-cert-file /config/auth/keys/ca.crt
set interfaces openvpn vtun0 tls cert-file /config/auth/keys/server.crt
set interfaces openvpn vtun0 tls key-file /config/auth/keys/server.key
set interfaces openvpn vtun0 tls dh-file /config/auth/keys/dh2048.pem
set interfaces openvpn vtun0 encryption aes128
set interfaces openvpn vtun0 openvpn-option "--keepalive 8 30"
set interfaces openvpn vtun0 openvpn-option "--comp-lzo"
set interfaces openvpn vtun0 openvpn-option "--duplicate-cn"
set interfaces openvpn vtun0 openvpn-option "--user nobody --group nogroup"
set interfaces openvpn vtun0 openvpn-option "--plugin /usr/lib/openvpn/openvpn-auth-pam.so openvpn"
set interfaces openvpn vtun0 openvpn-option "--client-cert-not-required --username-as-common-name"
set interfaces openvpn vtun0 openvpn-option "--verb 1"
set interfaces openvpn vtun0 openvpn-option "--proto udp6"
set interfaces openvpn vtun0 openvpn-option "--port 1194"
set interfaces openvpn vtun0 openvpn-option "--push redirect-gateway def1"
set interfaces openvpn vtun0 openvpn-option "--push dhcp-option DNS 8.8.8.8"
set interfaces openvpn vtun0 openvpn-option "--push dhcp-option DNS 8.8.4.4"

# Configure the firewall
set firewall name WAN_LOCAL rule 20 action accept
set firewall name WAN_LOCAL rule 20 description "Allow OpenVPN clients in"
set firewall name WAN_LOCAL rule 20 destination port 1194
set firewall name WAN_LOCAL rule 20 log disable
set firewall name WAN_LOCAL rule 20 protocol udp

# (Optional) Configure the firewall for IPv6
set firewall ipv6-name wan_local-6 rule 20 action accept
set firewall ipv6-name wan_local-6 rule 20 description "Allow OpenVPN clients in"
set firewall ipv6-name wan_local-6 rule 20 destination port 1194
set firewall ipv6-name wan_local-6 rule 20 log disable
set firewall ipv6-name wan_local-6 rule 20 protocol udp

# Forward traffic to the internet
set service nat rule 5010 description "Masquerade for WAN"
set service nat rule 5010 outbound-interface eth0
set service nat rule 5010 type masquerade

commit
save
exit

Create a .ovpn file

Give this to your clients for connection. Make sure to change the relevant details

client
float
dev tun

# EDIT THIS HOSTNAME
remote my.hostname.com 1194 udp

resolv-retry infinite
nobind
persist-key
persist-tun
auth-user-pass
cipher AES-128-CBC
comp-lzo
verb 3
<ca>
 -----BEGIN CERTIFICATE----- 
# put your certificate block here. Copy it from your /config/auth/keys/ca.crt file on your USG
-----END CERTIFICATE----- 
</ca> 

# this is an random certificate. The .ovpn file needs one, but doesn't use it, so you can leave this as is
<cert> 
-----BEGIN CERTIFICATE-----
MIIB1jCCAT+gAwIBAgIEAmLSTjANBgkqhkiG9w0BAQUFADAVMRMwEQYDVQQDEwpP
cGVuVlBOIENBMB4XDTEzMDExNzAyMTExMloXDTIzMDEyMjAyMTExMlowKDEmMCQG
A1UEAxQdZnJyaWN0aW9uQGdtYWlsLmNvbV9BVVRPTE9HSU4wgZ8wDQYJKoZIhvcN
AQEBBQADgY0AMIGJAoGBALVEXIZYYu1Inmejuo4Si6Eo5AguTX5sg1pGbLkJSTR4
BXQsy6ocUnZ9py8htYkipkUUhjY7zDu+wJlUtWnVCwCYtewYfEc/+azH7+7eU6ue
T2K2IKdik1KWhdtNbaNphVvSlgdyKiuZDTCedptgWyiL50N7FMcUUMjjXYh/hftB
AgMBAAGjIDAeMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgeAMA0GCSqGSIb3
DQEBBQUAA4GBABhVzSYXHlQEPNaKGmx9hMwwnNKcHgD9cCmC9lX/KR2Y+vT/QGxK
7sYlJInb/xmpa5TUQYc1nzDs9JBps1mCtZbYNNDpYnKINAKSDsM+KOQaSYQ2FhHk
bmBZk/K96P7VntzYI5S02+hOWnvjq5Wk4gOt1+L18+R/XujuxGbwnHW2
-----END CERTIFICATE-----
</cert>

# this is an random key. The .ovpn file needs one, but doesn't use it, so you can leave this as is
<key>
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALVEXIZYYu1Inmej
uo4Si6Eo5AguTX5sg1pGbLkJSTR4BXQsy6ocUnZ9py8htYkipkUUhjY7zDu+wJlU
tWnVCwCYtewYfEc/+azH7+7eU6ueT2K2IKdik1KWhdtNbaNphVvSlgdyKiuZDTCe
dptgWyiL50N7FMcUUMjjXYh/hftBAgMBAAECgYEAsNjgOEYVRhEaUlzfzmpzhakC
SKT8AALYaAPbYO+ZVzJdh8mIbg+xuF7A9G+7z+5ZL35lrpXKnONuvmlxkK5ESwvV
Q7EOQYCZCqa8xf3li3GUBLwcwXKtOUr3AYXhdbOh2viQdisD4Ky7H6/Nd3yMc3bu
R4pErmWeHei+l6dIwAECQQDqljNxi9babmHiei6lHaznCMg5+jfAyDXgHvO/afFr
1bDQVDTDK+64kax4E9pvDZC6B/HGse9hOUGWXTjb0WZBAkEAxdAw/14iJIUcE5sz
HDy2R0RmbUQYFjrNgBCi5tnmr1Ay1zHAs1VEF+Rg5IOtCBO50I9jm4WCSwCtN6zF
FoFVAQJAUGfBJDcZIm9ZL6ZPXJrqS5oP/wdLmtFE3hfd1gr7C8oHu7BREWB6h1qu
8c1kPlI4+/qDHWaZtQpJ977mIToJwQJAMcgUHKAm/YPWLgT31tpckRDgqgzh9u4z
e1A0ft5FlMcdFFT8BuWlblHWJIwSxp6YO6lqSuBNiuyPqxw6uVAxAQJAWGxOgn2I
fGkWLLw4WMpkFHmwDVTQVwhTpmMP8rWGYEdYX+k9HeOJyVMrJKg2ZPXOPtybrw8T
PUZE7FgzVNxypQ==
-----END PRIVATE KEY-----
</key>

Configure OpenVPN to authenticate with Radius

Create the file /etc/pam_radius_auth.conf and add the following contents to it. RADIUSSERVERIP should be the IP of your USG, 10.0.1.1 in my case. Enter the shared secret you created when you enabled the Radius server.

RADIUSSERVERIP SHAREDSECRET

Create the file /etc/pam.d/openvpn and add the following contents:

auth sufficient pam_radius_auth.so debug
account sufficient pam_permit.so
session sufficient pam_permit.so

You should now be able to connect to your USG via OpenVPN using Radius authentication with the username and password you configured in the beginning.

Persist your changes

Files will be overwritten after provisions. In order to persist your changes, you'll need to add a script to the /config/scripts directory to copy your files over and schedule a task to complete this after each provision.

Copy the files pam_radius_auth.conf and openvpn from the previous steps into a new directory in /config/scripts. I used ovpn_radius_config.

Copy the following script to /config/script/postprovision.sh:

#!/bin/vbash
readonly logFile="/var/log/postprovision.log"

#restore the ssmtp configuration

cp /config/scripts/ovpn_radius_config/pam_radius_auth.conf /etc
cp /config/scripts/ovpn_radius_config/openvpn /etc/pam.d/openvpn

#the following lines remove the postprovision scheduled task
#do not modify below this line

source /opt/vyatta/etc/functions/script-template

configure > ${logFile}
delete system task-scheduler task postprovision >> ${logFile}
commit >> ${logFile}
save >> ${logFile}
#exit

#end no edit

exit

Mark your script executable: sudo chmod +x /config/scripts/postprovision.sh

Update your config:

configure
set system task-scheduler task postprovision executable path "/config/scripts/postprovision.sh"
set system task-scheduler task postprovision interval 3m
commit
save
exit

Finally, follow the instructions provided here to persist your configuration changes.

Troubleshoot

If you find you have trouble connecting, check your USG logs with show log | grep openvpn

Changelog

  • 8/30/18: Added post provision script
  • 8/29/18: First release
@PhillySports
Copy link

PhillySports commented Oct 11, 2019

Hello.

Sorry if this is a stupid question, but beginning with the instructions at "Create a .ovpn file" section. I am unclear how this is supposed to be done? Am I supposed to create a txt file using the nano command?

Also, at some point am I actually supposed to download the OpenVPN software -- if so, how is that done?

Thanks in advance for all you help.

@shpydah
Copy link

shpydah commented Nov 18, 2019

Great guide and comments all around, thank you so much for putting this together.

I'm just now in the process of setting this up on our new USG. One question I'd love to poll everyone on is the approximate time it took everyone to finish generating DH parameters. I'm currently at more than 2 hours and it's still running. Some resources I've found estimate that a 2048 DH generation can take upwards of 12 hours or more, has anyone found this to be accurate?

@fongd
Copy link

fongd commented Dec 2, 2019

There also seems to be an issue with the easy-rsa deb package in the above instructions.

You can use http://ftp.us.debian.org/debian/pool/main/e/easy-rsa/easy-rsa_2.2.2-2_all.deb as the updated path to the EasyRSA .deb package. Otherwise just browse to http://ftp.us.debian.org/debian/pool/main/e/easy-rsa/ and download the latest 2.x release. The 3.x releases don't work with the USG.

@xatru
Copy link

xatru commented Dec 25, 2019

Hello.

Sorry if this is a stupid question, but beginning with the instructions at "Create a .ovpn file" section. I am unclear how this is supposed to be done? Am I supposed to create a txt file using the nano command?

Also, at some point am I actually supposed to download the OpenVPN software -- if so, how is that done?

Thanks in advance for all you help.

You create your .ovpn file (or copy the file) on the machine that is supposed to connect to the VPN and not on the USG. On that system you also need the VPN software. For Windows systems you find the software on https://openvpn.net/community-downloads/, for Unix systems use the internal package manager, e.g.,sudo apt install openvpnfor Ubuntu.

Using a simple text editor (nano, notepad, ...) is sufficient, but be careful with the line endings (use thedos2unixcommand if you see ^M line endings by inspecting the .opvn file withcat <filename.ovpn>)

Great guide and comments all around, thank you so much for putting this together.

I'm just now in the process of setting this up on our new USG. One question I'd love to poll everyone on is the approximate time it took everyone to finish generating DH parameters. I'm currently at more than 2 hours and it's still running. Some resources I've found estimate that a 2048 DH generation can take upwards of 12 hours or more, has anyone found this to be accurate?

I did the same mistake and generated the keys directly on the USG. For the DH key, it took really a long time (~3h) but the solution is easy: Generate the keys on a Linux/Unix machine or use the Unix subsystem for Windows and copy it to the USG via SSH/SCP.

@xatru
Copy link

xatru commented Dec 25, 2019

I did all the steps above and my VPN works quite fine now with one exception: IPv6

All the traffic from the client is tunneled via VPN to the internet if I use IPv4 addresses but it does not work for IPv6. The IPv6 traffic is still going directly form the client through the e.g., hotel hostpot. As more and more services are using IPv6 addresses this might be an issue now, but for sure it will be in the future.
As far as I was able to figure out, the option push route-ipv6 has to be set in the server config, but I wasn't able to figure out the correct settings here. Any experience on that?

@schwubbs
Copy link

schwubbs commented May 17, 2020

First of all, thank you very much for this great guide! Such a well-written manual - not too much and not too little - doesn't come across to me very often.

So far, everything went well for me at first go: The connection is established and the complete data traffic of my OpenVPN client is routed via the USG to the WAN.

But one thing unfortunately doesn't work: My USG establishes Auto IPsec VTI connections to three other USGs. The clients from the different subnets can reach each other. OpenVPN clients can only reach the "home subnet", but unfortunately not the other subnets (it works for the remote user L2TP server).

Does anyone have any ideas how I can solve the problem? I've already played around with the routes and the firewall a bit and also searched the internet, but unfortunately I haven't found anything that causes it.

@Juanito87
Copy link

Juanito87 commented Dec 31, 2020

Hi, I'm trying to understand one thing that I'm not sure with this guide.
Copying keys from the easy-rsa install folder to the config folder, is in order to persist them after reboot right?
So each time i create a new user certificate, i need to also copy index and serial?
Thanks for the help.

@unixwizard107
Copy link

unixwizard107 commented Jun 8, 2021

This is a super guide. Thank you all.

I'm putting a Unify system into my Church and a VPN would be extremely handy for the admins of the network infrastructure remotely. At work, we use OpenVPN for some DOD/DOE contracts so I'm basically familiar with the client-side and how to set it up on macOS, Winders, and the basic Unix family.

Note I'm a 45+ yr UNIX hacker (actually wrote one of the original TCP implementations/one of the original Unix kernel developers in the 1970s, so I'm hardly a 'newbie'). But I am newish to the Unify scheme and know enough to be dangerous.

The load of easy-rsa seems to be on the USG. Note that I want to run a Unify Cloud Key2 as the controller there. Last summer when I installed Unify at home on a RPi (without a VPN), I noticed if I made a change to the USG config, the controller wiped it out when I made modifications via that SW. It was clear, they really did not want you to mix Edge commands and commands coming from the controller SW.

Q1) How do I ensure that these changes to the config files are 'known' to the controller so it includes them with any update we might do (like add/delete of users or enable/disable/change other services)?

Q2) Since you are running the OpenVPN server on the USG, it was not clear what my.hostname.com from:

EDIT THIS HOSTNAME
remote my.hostname.com 1194 udp

Needs to be. I would expect that to be the external IP address of the USG assigned by our ISP and then mapped to vpn.ourdomain.org via our DNS provider.

Client then are able to connect to vpn.ourdomain.org

Thanks for the clarifications.

@IceC00l
Copy link

IceC00l commented Aug 27, 2021

On the USG-3P with version 4.4.55 I am getting a "RADIUS server failed to respond" when I use the LAN IP of the USG. However when I revert to 127.0.0.1 it does respond, but I get a "openvpn[30843]: pam_radius_auth: packet from RADIUS server 127.0.0.1 fails verification: The shared secret is probably incorrect." Naturally the shared secret is correct and there are no strange characters. Has there been some firewall hardening on the internal LAN IP? Any heads up?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment