Skip to content

FreeRADIUS IdP Setup

This example shows a modern FreeRADIUS 3.x Identity Provider deployment for local user authentication.

Install Packages

On Debian or Ubuntu:

apt update
apt install freeradius freeradius-utils freeradius-ldap freeradius-mysql

Install only the backend modules you need.

Service Management

systemctl enable --now freeradius
freeradius -XC

Use freeradius -XC to validate configuration syntax before any restart.

FreeRADIUS 3.x Layout

Key locations:

/etc/freeradius/3.0/clients.conf
/etc/freeradius/3.0/mods-enabled/eap
/etc/freeradius/3.0/mods-enabled/ldap
/etc/freeradius/3.0/mods-enabled/sql
/etc/freeradius/3.0/proxy.conf
/etc/freeradius/3.0/sites-enabled/default
/etc/freeradius/3.0/sites-enabled/inner-tunnel

For IdP service, default handles the outer request and inner-tunnel handles inner authentication for PEAP and TTLS.

EAP Configuration

Edit mods-enabled/eap and ensure a real server certificate is used. Do not use test certificates in production.

eap {
    default_eap_type = peap
    timer_expire     = 60
    ignore_unknown_eap_types = no
    cisco_accounting_username_bug = no

    tls-config tls-common {
        private_key_file = /etc/freeradius/3.0/certs/radius.key
        certificate_file = /etc/freeradius/3.0/certs/radius.crt
        ca_file = /etc/freeradius/3.0/certs/ca-chain.pem
        dh_file = /etc/freeradius/3.0/certs/dh
        cipher_list = "HIGH"
        cipher_server_preference = yes
        tls_min_version = "1.2"
    }

    ttls {
        tls = tls-common
        default_eap_type = pap
        copy_request_to_tunnel = yes
        use_tunneled_reply = yes
    }

    peap {
        tls = tls-common
        default_eap_type = mschapv2
        copy_request_to_tunnel = yes
        use_tunneled_reply = yes
    }
}

Local Realm Definition

Define your local realm in proxy.conf:

realm institution.ac.ke {
    nostrip
}

If you operate multiple local realms, define each explicitly.

AP and Controller Clients

Add only known wireless infrastructure in clients.conf:

client wlan-controller-1 {
    ipaddr = 10.10.10.20
    secret = <strong-shared-secret>
    shortname = wlan-controller-1
    nastype = other
}

Use unique, strong secrets per client wherever possible.

LDAP Example

Example mods-enabled/ldap highlights:

ldap {
    server = "ldaps://ldap.institution.ac.ke"
    identity = "uid=radius-bind,ou=service,dc=institution,dc=ac,dc=ke"
    password = <bind-password>
    base_dn = "dc=institution,dc=ac,dc=ke"
    user {
        base_dn = "${..base_dn}"
        filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
    }
    group {
        base_dn = "ou=groups,dc=institution,dc=ac,dc=ke"
        filter = "(member=%{control:Ldap-UserDn})"
    }
    start_tls = no
}

Call the module in authorize and authenticate as required by your backend design.

Active Directory Notes

For AD-backed PEAP-MSCHAPv2 deployments, common patterns are:

  • LDAP for group lookup and policy
  • ntlm_auth or Samba/winbind integration for MSCHAP authentication

If using AD, test password expiry, lockout, and group lookups carefully before production rollout.

Dynamic VLAN Example

In sites-enabled/inner-tunnel, return VLANs based on realm or LDAP group:

post-auth {
    if (&Realm == "students.institution.ac.ke") {
        update reply {
            Tunnel-Type := VLAN
            Tunnel-Medium-Type := IEEE-802
            Tunnel-Private-Group-Id := "20"
        }
    }
    elsif (LDAP-Group == "cn=staff,ou=groups,dc=institution,dc=ac,dc=ke") {
        update reply {
            Tunnel-Type := VLAN
            Tunnel-Medium-Type := IEEE-802
            Tunnel-Private-Group-Id := "10"
        }
    }
}

Ensure the wireless controller honors these attributes.

SQL Accounting Example

Enable SQL and accounting if a local database is used:

sql {
    driver = "rlm_sql_mysql"
    dialect = "mysql"
    server = "127.0.0.1"
    port = 3306
    login = "radius"
    password = <sql-password>
    radius_db = "radius"
}

In sites-enabled/default:

accounting {
    detail
    sql
}
session {
    sql
}
post-auth {
    sql
}

Certificate Guidance

  • use a production certificate, not make or test certificates
  • include the full CA chain
  • ensure the server name in client profiles matches the certificate
  • monitor expiry and renew early

Restart and Validate

freeradius -XC
systemctl restart freeradius
systemctl status freeradius