RADIUS Server Installation with FreeRADIUS

FreeRADIUS is the most widely deployed RADIUS server for network authentication and accounting, supporting Wi-Fi, VPN, and 802.1X environments. This guide covers installing FreeRADIUS on Linux, configuring clients, EAP methods, LDAP backend integration, and VPN authentication.

Prerequisites

  • Ubuntu 22.04/Debian 12 or CentOS/Rocky 9
  • Root or sudo access
  • A reachable LDAP or Active Directory server (optional)
  • Network devices (switches, APs, VPN) that support RADIUS
  • Ports 1812 (auth) and 1813 (accounting) open in firewall

Install FreeRADIUS

# Ubuntu/Debian
sudo apt update
sudo apt install -y freeradius freeradius-utils freeradius-ldap

# CentOS/Rocky
sudo dnf install -y freeradius freeradius-utils freeradius-ldap

# Enable and start the service
sudo systemctl enable freeradius
# Do NOT start yet - configure first

FreeRADIUS configuration lives in /etc/freeradius/3.0/ (Debian) or /etc/raddb/ (RHEL).

# Set a variable for the config directory
RADDB=/etc/freeradius/3.0       # Debian/Ubuntu
# RADDB=/etc/raddb              # CentOS/Rocky

Basic Configuration

Test FreeRADIUS in debug mode before starting as a service:

# Stop service if running, then start in debug mode
sudo systemctl stop freeradius
sudo freeradius -X 2>&1 | head -50

Edit the main configuration to set the server name:

sudo nano $RADDB/radiusd.conf

Key settings to review:

# Set your organization name
name = radiusd

# Log authentication attempts
auth = yes
auth_badpass = yes
auth_goodpass = no

# Log to syslog
destination = syslog
syslog_facility = daemon

Add a test user to verify the installation:

# Add a test user to the users file
echo 'testuser Cleartext-Password := "testpassword"' | \
  sudo tee -a $RADDB/users

# Test authentication locally
sudo freeradius -X &
sleep 3
radtest testuser testpassword localhost 0 testing123
kill %1

Configure RADIUS Clients

Clients are network devices (APs, switches, VPN concentrators) that send authentication requests. Edit /etc/freeradius/3.0/clients.conf:

sudo tee -a $RADDB/clients.conf << 'EOF'

# Cisco switch
client switch-01 {
    ipaddr          = 192.168.1.10
    secret          = SwitchSharedSecret123
    shortname       = switch-01
    nas_type        = cisco
}

# Ubiquiti Access Point
client ap-lobby {
    ipaddr          = 192.168.1.20
    secret          = APSharedSecret456
    shortname       = ap-lobby
    nas_type        = other
}

# VPN server (OpenVPN/StrongSwan)
client vpn-gateway {
    ipaddr          = 10.0.0.1
    secret          = VPNSharedSecret789
    shortname       = vpn-gw
    nas_type        = other
}

# Entire subnet of APs
client wifi-aps {
    ipaddr          = 192.168.2.0/24
    secret          = SubnetSecret321
    shortname       = wifi-aps
}
EOF

EAP Authentication Methods

EAP is used for Wi-Fi (WPA2-Enterprise/802.1X) authentication. Configure EAP in $RADDB/mods-available/eap:

sudo nano $RADDB/mods-available/eap

Key EAP settings:

eap {
    default_eap_type = peap   # Most common for WPA2-Enterprise

    timer_expire = 60
    ignore_unknown_eap_types = no

    tls-config tls-common {
        private_key_file = ${certdir}/server.pem
        certificate_file = ${certdir}/server.pem
        ca_file          = ${cadir}/ca.pem
        ca_path          = ${cadir}
        cipher_list      = "DEFAULT@SECLEVEL=1"
        tls_min_version  = "1.2"
    }

    peap {
        tls = tls-common
        default_eap_type = mschapv2   # inner method
        virtual_server = "inner-tunnel"
    }

    mschapv2 {
        send_error = no
    }

    ttls {
        tls = tls-common
        default_eap_type = pap
        virtual_server = "inner-tunnel"
    }
}

Generate self-signed certificates for EAP:

cd $RADDB/certs
# Edit ca.cnf and server.cnf to set your organization details
sudo nano ca.cnf
sudo nano server.cnf

# Generate certificates
sudo make ca
sudo make server

# Verify certificates were created
ls -la $RADDB/certs/*.pem

LDAP Backend Integration

Authenticate users against an LDAP directory:

# Enable the LDAP module
sudo ln -s $RADDB/mods-available/ldap $RADDB/mods-enabled/ldap

sudo nano $RADDB/mods-enabled/ldap
ldap {
    server      = "ldap.example.com"
    port        = 389
    identity    = "cn=radius-reader,ou=ServiceAccounts,dc=example,dc=com"
    password    = "ServiceAccountPassword"
    base_dn     = "dc=example,dc=com"

    user {
        base_dn = "ou=Users,${..base_dn}"
        filter  = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
    }

    group {
        base_dn        = "ou=Groups,${..base_dn}"
        filter         = "(objectClass=groupOfNames)"
        membership_filter = "(|(member=%{control:Ldap-UserDn})(uniqueMember=%{control:Ldap-UserDn}))"
        membership_attribute = memberOf
    }

    # Require users to be in this group
    access_attribute = memberOf
    access_positive  = yes

    options {
        chase_referrals = yes
        rebind          = yes
        net_timeout     = 10
        timeout         = 30
    }

    tls {
        start_tls   = no
    }
}

Configure the default site to use LDAP:

sudo nano $RADDB/sites-enabled/default
# In the 'authorize' section, add before 'pap':
#   ldap
#   if (ok || updated) { update control { Auth-Type := ldap } }

VPN Authentication Setup

Configure FreeRADIUS to authenticate OpenVPN users:

# On the OpenVPN server, add to server.conf:
# plugin /usr/lib/openvpn/radiusplugin.so /etc/openvpn/radiusplugin.cnf

# Create the RADIUS plugin config
cat > /etc/openvpn/radiusplugin.cnf << 'EOF'
NAS-Identifier=openvpn
Service-Type=5
Framed-Protocol=1
NAS-Port-Type=5
NAS-IP-Address=10.0.0.1
OpenVPNConfig=/etc/openvpn/server.conf
subnet=255.255.255.0
overwriteccfiles=true
nonfatalaccounting=false
server
{
        name=192.168.1.100   # FreeRADIUS server IP
        authport=1812
        acctport=1813
        timeout=30
        retries=3
        sharedsecret=VPNSharedSecret789
}
EOF

Add accounting support in FreeRADIUS (already enabled by default):

# Verify accounting site is enabled
ls $RADDB/sites-enabled/
# Should show: default, inner-tunnel

VLAN Assignment

Return VLAN attributes to network devices based on group membership:

# Add to $RADDB/users or a policy file
sudo tee -a $RADDB/users << 'EOF'

# Users in sysadmins group get VLAN 10
DEFAULT Ldap-Group == "cn=sysadmins,ou=Groups,dc=example,dc=com"
    Tunnel-Type = VLAN,
    Tunnel-Medium-Type = IEEE-802,
    Tunnel-Private-Group-Id = "10"

# Users in employees group get VLAN 20
DEFAULT Ldap-Group == "cn=employees,ou=Groups,dc=example,dc=com"
    Tunnel-Type = VLAN,
    Tunnel-Medium-Type = IEEE-802,
    Tunnel-Private-Group-Id = "20"

# Default VLAN for all others
DEFAULT
    Tunnel-Type = VLAN,
    Tunnel-Medium-Type = IEEE-802,
    Tunnel-Private-Group-Id = "99"
EOF

Troubleshooting

Run in debug mode to trace authentication:

sudo systemctl stop freeradius
sudo freeradius -X 2>&1 | tee /tmp/radius-debug.log
# In another terminal, send a test auth:
radtest user password 127.0.0.1 0 testing123

Test RADIUS from command line:

# Test against a specific NAS secret
echo "User-Name=testuser,User-Password=testpass" | \
  radclient -x 127.0.0.1 auth testing123

LDAP connection failures:

# Test LDAP independently
ldapsearch -H ldap://ldap.example.com \
  -D "cn=radius-reader,ou=ServiceAccounts,dc=example,dc=com" \
  -w ServiceAccountPassword \
  -b "ou=Users,dc=example,dc=com" "(uid=testuser)"

EAP certificate errors:

# Verify certificate validity
openssl x509 -in /etc/freeradius/3.0/certs/server.pem -noout -dates
# Regenerate if expired
cd /etc/freeradius/3.0/certs && sudo make destroycerts && sudo make

Conclusion

FreeRADIUS provides enterprise-grade authentication and accounting for network infrastructure including Wi-Fi, VPN, and wired 802.1X environments. With LDAP integration and EAP-PEAP, you can authenticate users against your existing directory while assigning VLANs dynamically based on group membership. Always run FreeRADIUS in debug mode (-X) when troubleshooting authentication failures, as it shows the full attribute processing pipeline.