Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mzpqnxow/b7a4c967060e6477a1891060129d6d52 to your computer and use it in GitHub Desktop.
Save mzpqnxow/b7a4c967060e6477a1891060129d6d52 to your computer and use it in GitHub Desktop.
# This could use some cleanup and robustness changes, but it works for me. Modifications are welcome!
# How to setup a Ubiquiti EdgeRouter POE for FreeRADIUS
# Based on
# https://community.ui.com/questions/FreeRADIUS-on-Edgerouter-2-x/6869cef3-aeca-42c3-9081-e69daa44f397
# https://networkjutsu.com/freeradius-with-two-factor-authentication/
# https://wiki.freeradius.org/guide/Getting-Started
# SSH into your router
configure # Enter configuration mode
show system package repository # Check the current repository settings
# If a message of "Configuration under specified path is empty" is returned, add
# the required repository as described in https://help.ui.com/hc/en-us/articles/205202560-EdgeRouter-Add-Debian-Packages-to-EdgeOS
set system package repository stretch components 'main contrib non-free'
set system package repository stretch distribution stretch
set system package repository stretch url http://http.us.debian.org/debian
commit ; save
show system package repository # Check the current repository settings
# Switch to the root user from here out
sudo bash
# Update the apt repository data
apt-get update
# make is needed only when you are setting up your certificates (one time process)
# libpam-pwdfile provides for an alternate password file to be used (so that radius can use different users than the main router login)
# google-authenticator to provides two-factor authentication
apt-get --no-install-recommends install \
make \
freeradius \
freeradius-utils \
libpam-pwdfile \
libpam-google-authenticator
# Wait while the Diffie-Hellman parameters are generated
# Do not edit the configuration files directly in /etc as those will be lost on upgrade
# Move the files into /config so that they will be saved
systemctl stop freeradius # use systemctl to manage freeradius service
mv /etc/freeradius /config/freeradius
ln -s /config/freeradius /etc/freeradius
# Set FreeRADIUS to start on bootup
systemctl enable freeradius # enable service on boot
systemctl status freeradius # check if freeradius is running
systemctl start freeradius # start the service (if not already running)
# Set Freeradius to use PAM
sed -i 's/^#[[:space:]]*pam$/ pam/g' /etc/freeradius/3.0/sites-available/default
ln -s /etc/freeradius/3.0/mods-available/pam /etc/freeradius/3.0/mods-enabled/pam
sed -i '1s/^/# Instruct FreeRADIUS to use PAM to authenticate users\n/' /etc/freeradius/3.0/mods-config/files/authorize
sed -i '2s/^/DEFAULT Auth-Type := PAM\n/' /etc/freeradius/3.0/mods-config/files/authorize
# Set PAM to use google authenticator for radius
## Turn everything else off (handled by overwriting the file)
#sed -i 's/@include/#@include/g' /etc/pam.d/radiusd
# Use google authenticator with an alternate secret location, use the freerad user so
# that the google authenticator file can be read correctly, and forward the password
# part to password verification
echo "auth requisite pam_google_authenticator.so secret=/etc/freeradius/google_authenticator/${USER}/.google_authenticator user=freerad forward_pass" > /etc/pam.d/radiusd
# Use an alternate password verification location (so that the main router login is
# not used/modified)
echo "auth required pam_pwdfile.so pwdfile=/etc/freeradius/passwd_alt use_first_pass" >> /etc/pam.d/radiusd
# after authentication, approve the account
echo "account required pam_permit.so" >> /etc/pam.d/radiusd
## restart freeradius so that the above changes take effect
systemctl restart freeradius
# Create a user (replace "my_username" with the actual username and "my_password" with the actual password)
export NEWUSER=my_username
export NEWPASSWORD=my_password
## Remove the current password from the file, if it exists
sed -i '/^'"${NEWUSER}"'/d' /etc/freeradius/passwd_alt
## Add the username and password to the file
echo ${NEWUSER}:$(echo ${NEWPASSWORD} | mkpasswd) >> /etc/freeradius/passwd_alt
mkdir -p /etc/freeradius/google_authenticator/${NEWUSER}
google-authenticator \
--time-based --disallow-reuse --force \
--label="VPN radius" --issuer="unifi" \
--rate-limit=3 --rate-time=30 \
--secret=/etc/freeradius/google_authenticator/${NEWUSER}/.google_authenticator \
--window-size=3
## The QR code will be shown now. Add it to your Google authenticator app.
chown freerad.freerad /etc/freeradius/google_authenticator/${NEWUSER} \
/etc/freeradius/google_authenticator/${NEWUSER}/.google_authenticator
chmod 600 /etc/freeradius/google_authenticator/${NEWUSER}/.google_authenticator
# Test the PAM setup (optional)
# pamtester -v radiusd ${NEWUSER} authenticate
# confirm that the new user works
systemctl stop freeradius
/usr/sbin/freeradius -X
## The password here and for the actual VPN access is given as [password+2fa value],
## so if the password is "mypass" and the current 2FA value is "123456", then you
## would enter "mypass123456" for [password+2fa value]
radtest $NEWUSER [password+2fa value] 127.0.0.1 0 testing123
# Configure the router settings
set vpn l2tp remote-access authentication mode radius
set vpn ipsec ipsec-interfaces interface eth0
set vpn l2tp remote-access authentication radius-server 127.0.0.1 key testing123
set vpn l2tp remote-access authentication radius-server 127.0.0.1 port 1812
commit ; save
## in the config tree of the web interface:
# vpn > l2tp > remote-access > dhcp-interface = eth0
# vpn > l2tp > remote-access > idle = 1800
# vpn > l2tp > remote-access > authentication > mode = radius
# vpn > l2tp > remote-access > authentication > radius-server = 127.0.0.1
# vpn > l2tp > remote-access > authentication > radius-server > 127.0.0.1 > key = testing123
# vpn > l2tp > remote-access > authentication > radius-server = 127.0.0.1 > port = 1812
# vpn > l2tp > remote-access > ipsec-settings > authentication > mode = pre-shared-secret
# vpn > l2tp > remote-access > ipsec-settings > authentication > pre-shared-secret = [l2tp secret value]
# Windows 10 configuration
# Initial VPN setup
# Settings > search for VPN
# Add a VPN connection
# VPN provider: Windows (built-in)
# Connection name: [VPN name that you will remember]
# Server name or address: [enter the DNS name or IP address]
# Type of sign-in info: User name and password
# User name (optional): enter the username
# Do NOT check "remember my sign-in info"
# Modify the VPN
# View network connections
# Right click on the [VPN name that you will remember]
# Properties
# Security tab
# Type of VPN: Layer 2 tunneling protocol with IPsec (L2TP/IPsec)
# Advanced settings
# Use preshared key for authentication; Key: [l2tp secret value]
# OK
# Data encryption: Require encryption
# Authentication: Allow these protocols
# Unencrypted password (PAP); this is required to allow the separation of the password from the 2fa key, and it is secure because https://documentation.meraki.com/MX/Client_VPN/Client_VPN_Authentication_Protocol
# OK
## Put everything below here into /config/firstboot.d/freeradius-2fa-vpn.sh and run
# chmod 755 /config/firstboot.d/freeradius-2fa-vpn.sh
#!/bin/bash
# Update the apt repository data
apt-get update
# make is needed only when you are setting up your certificates (one time process)
# libpam-pwdfile provides for an alternate password file to be used (so that radius can use different users than$
# google-authenticator to provides two-factor authentication
apt-get --no-install-recommends install \
make \
freeradius \
freeradius-utils \
libpam-pwdfile \
libpam-google-authenticator
# Wait while the Diffie-Hellman parameters are generated
# Use google authenticator with an alternate secret location, use the freerad user so
# that the google authenticator file can be read correctly, and forward the password
# part to password verification
echo "auth requisite pam_google_authenticator.so secret=/etc/freeradius/google_authenticator/${USER}/.google_aut$
# Use an alternate password verification location (so that the main router login is
# not used/modified)
echo "auth required pam_pwdfile.so pwdfile=/etc/freeradius/passwd_alt use_first_pass" >> /etc/pam.d/radiusd
# after authentication, approve the account
echo "account required pam_permit.so" >> /etc/pam.d/radiusd
systemctl restart freeradius
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment