Set Up pppd RADIUS Authentication with the radius.so Plugin
The radius.so plugin swaps pppd's local secrets file for a proper RADIUS server. It carries PAP, CHAP, MS-CHAP or MS-CHAPv2 authentication over to that server instead. This targets the Ubuntu package ppp version 2.4.9-1+1.1ubuntu4, which installs the plugin under /usr/lib/pppd/2.4.9/.
The route
Jump straight to the step you need, or tick off Done means at the end.
Twenty minutes if the RADIUS service and PPP transport already exist. You need root access, a reachable RADIUS server and its shared secret, a working PPP transport, and permission to edit the RADIUS client configuration. Every example value is deliberately fictional: replace anything marked CHANGE_ME before you actually use it.
1. Check the installed plugin and version
Start read-only. The plugin option is privileged, so the eventual daemon invocation needs an appropriately elevated service context, and a plugin built for a different pppd version is not safe to assume will load.
$ dpkg-query -W -f='${Package} ${Version}\n' ppp
ppp 2.4.9-1+1.1ubuntu4
$ ls -l /usr/lib/pppd/2.4.9/radius.so
-rw-r--r-- 1 root root ... /usr/lib/pppd/2.4.9/radius.so
On this package, plugin radius.so alone is enough: pppd searches its own versioned plugin directory for it. An absolute path also works, but the short form keeps the configuration tied to whichever pppd is actually running.
2. Check the RADIUS client configuration
Server and client settings are not the plugin's own job; it hands them off to the radiusclient library, which reads /etc/radiusclient/radiusclient.conf unless you point it elsewhere. That same directory usually holds the server definitions and shared secrets the library needs.
$ sudo ls -l /etc/radiusclient/radiusclient.conf /etc/radiusclient/servers
$ sudo sed -n '1,160p' /etc/radiusclient/radiusclient.conf
$ sudo sed -n '1,80p' /etc/radiusclient/servers
Check the installed library's own documentation before touching these files, since pppd-radius(8) does not define the server-file syntax. The shared secret is properly sensitive: keep it root-owned, restrict its mode to whoever must run the PPP service, and never paste it into a ticket or a shell command.
Running a separate client configuration? Keep it in a root-owned location and pass its path explicitly, rather than silently editing the default that some other PPP service may already rely on:
$ sudo install -o root -g root -m 0640 /path/to/radiusclient.conf /etc/ppp/radiusclient-office.conf
That command changes state, so the undo is deliberate: remove the copied file once you have confirmed nothing else refers to it:
$ sudo rm /etc/ppp/radiusclient-office.conf
3. Build a peer options file
A named peer file gives the service a repeatable configuration to load instead of a one-off command line. Below is the plugin, an explicit RADIUS configuration path, and the default interface-name mapping for the RADIUS NAS-Port attribute.
$ sudo install -o root -g root -m 0644 /dev/null /etc/ppp/peers/radius-office
$ sudoedit /etc/ppp/peers/radius-office
plugin radius.so
radius-config-file /etc/ppp/radiusclient-office.conf
map-to-ifname
Use map-to-ifname when the RADIUS server expects NAS-Port derived from the PPP interface name; the plugin documents it as the default. Use map-to-ttyname only when your RADIUS policy specifically wants the value libradiusclient supplies instead.
Do not bolt on login or local pap-secrets entries expecting both systems to be consulted. This plugin skips the normal local PPP authentication schemes entirely. Identity and password still come from the peer's negotiated PPP exchange; RADIUS is what validates them.
4. Select optional request attributes
Need an Attribute-Value pair in every RADIUS request? That is what avpair is for. Confirm the attribute name and value against the server policy first, then add it:
plugin radius.so
radius-config-file /etc/ppp/radiusclient-office.conf
avpair NAS-Identifier=ppp-gateway-01
This is not something every deployment needs. An unknown attribute, a wrongly formatted value, or one that disagrees with server policy can sink an otherwise valid login, so add one pair at a time and keep a copy of the last known-good peer file.
5. Start one controlled test
Run the peer through whatever service or privileged wrapper normally owns the PPP device. Both the plugin option and the plugin option in pppd(8) itself are marked privileged, so a generic invocation like the one below still needs a real transport option from your environment; do not copy it as a complete dial-up command:
$ sudo pppd call radius-office
Supply the serial, modem, tunnel or other transport settings your deployment needs through the peer file or service. On success the PPP link comes up and the peer address arrives via the RADIUS server's Framed-IP-Address attribute, which the plugin's man page names as the expected way RADIUS assigns that address.
Check the daemon and network logs from a separate terminal while testing:
$ sudo journalctl -b --no-pager | rg 'pppd|radius|PPP'
$ ip -brief address show | rg '^ppp'
Do not switch on packet debugging casually. PPP debug output can expose authentication details and other network data straight into system logs. If you must turn logging up, keep the test window short, protect the logs, and remove the extra setting afterwards.
6. Diagnose the usual failures
- Plugin not found: check that
radius.soexists in the directory matching the installedpppdversion. A stale absolute path or a plugin from another package version is a common cause. - Configuration not found: check the spelling and permissions of
radius-config-file. If the option is absent, inspect the default/etc/radiusclient/radiusclient.confinstead. - Authentication rejected: verify the username, negotiated authentication protocol, RADIUS client address, shared secret, and server policy. Do not fall back to local secrets without deciding that the change is acceptable.
- Timeouts: test routing and firewall access to the configured RADIUS server, then check that the server recognises this PPP host as a client. A timeout is not evidence of a bad password.
- Unexpected port policy: compare the server's expected
NAS-Portrepresentation withmap-to-ifnameandmap-to-ttyname. Change only the mapping that matches the server's documented policy.
If the test breaks an existing service, stop the new PPP attempt, restore the previous peer file from your backup, and restart only the affected service. Do not delete shared RADIUS configuration while another PPP instance may still use it.
Done means
pppandradius.somatch the runningpppdversion.- The RADIUS client configuration points to the intended server and is protected from ordinary users.
- The peer file loads
plugin radius.soand, when needed, the correctradius-config-file. - A controlled test authenticates through RADIUS and receives a peer address from
Framed-IP-Address. - Logs contain no unnecessary credentials or long-lived packet debugging output.