RADIUS Change of Authorization
Dynamic rate changes via RADIUS CoA.
Overview
RADIUS Change of Authorization (CoA) allows your RADIUS server to modify subscriber session parameters in real-time without requiring session reconnection.
How It Works
Configuration
Enable CoA in config:
radius:
servers:
- host: "10.255.0.10"
port: 1812
acct_port: 1813
coa_enabled: true
coa_port: 3799
coa_secret: "a-unique-secret" # required; commit is refused without it
coa_allowed_clients: # who may send CoA (empty = any source)
- "10.255.0.10"
- "10.255.0.0/24"
coa_bind_address: "10.255.0.1" # optional; default 0.0.0.0
coa_vrf: "mgmt" # required if the bind address is on a
# VRF-enslaved interface
If coa_bind_address is an address on a VRF-enslaved interface (a management
port, typically), you must also set coa_vrf. Binding such an address from
the default VRF fails with EADDRNOTAVAIL, and the listener will not come up.
Setting coa_vrf also fixes reply routing. With the default 0.0.0.0 bind the
kernel picks the reply's source address by route, which on a box whose
management network sits in a VRF means replies leave with the upstream
address — and every CoA client discards a reply that does not come from the
address it sent to. Bound in the VRF, replies carry the right source.
A CoA listener that cannot bind is logged as an error and skipped; it never prevents abngd from starting.
The listener is rebound by commit — changing the port, bind address, VRF,
secret or allow-list takes effect immediately, and setting coa_enabled false
stops it. No abngd restart is needed, which matters because restarting abngd
drops active PPPoE sessions.
From the CLI:
abng# set radius coa_enabled true
abng# set radius coa_secret a-unique-secret
abng# set radius coa_allowed_clients 10.255.0.10
abng# set radius coa_bind_address 10.255.0.1
abng# set radius coa_vrf mgmt
abng# commit
coa_secret is mandatory when CoA is enabled — a commit is refused without
one, and placeholder secrets are rejected. Leaving coa_allowed_clients empty
is permitted but means the listener accepts authenticated packets from any
source IP; the commit logs a warning when it does.
Sending CoA
Using radclient
echo "Acct-Session-Id = 'abng-1709312400-42', Athena-Rate-Down = '200mbit', Athena-Rate-Up = '80mbit'" | \
radclient -x 10.255.0.1:3799 coa YourCoaSecret
Using FreeRADIUS
In FreeRADIUS, send CoA via radclient:
#!/bin/bash
SESSION_ID=$1
RATE_DOWN=$2
RATE_UP=$3
echo "Acct-Session-Id = '$SESSION_ID', Athena-Rate-Down = '$RATE_DOWN', Athena-Rate-Up = '$RATE_UP'" | \
radclient -x 10.255.0.1:3799 coa my-secret
Supported Attributes
Identifying the session
A CoA or Disconnect must say which session it targets. Any one of these works — they are tried most-specific first, so a request carrying several acts on the one that can only mean a single session:
| Attribute | Notes |
|---|---|
Acct-Session-Id | Most precise. The full string is verified against the stored session, so a stale boot-epoch id cannot act on a same-numbered current session. |
Framed-IP-Address | The subscriber's IPv4 address — how most billing/BSS platforms address a session. |
Delegated-IPv6-Prefix | RFC 4818. Targets a v6-only IPoE subscriber that has no Acct-Session-Id. |
User-Name | Least specific. If the name matches more than one active session the request is rejected (Error-Cause 404) rather than applied to an arbitrary pick — use one of the above to disambiguate. |
If none is present the request is NAK'd with Error-Cause 402 (Missing Attribute); if the identifier matches nothing, 503 (Session-Context-Not-Found).
Action attributes
| Attribute | Type | Description |
|---|---|---|
Athena-Rate-Down | String | Download rate (e.g., "50mbit") |
Athena-Rate-Up | String | Upload rate (e.g., "20mbit") |
A CoA-Request must carry both rate attributes; one alone is NAK'd with Error-Cause 402. A Disconnect-Request needs only an identifier.
Use Cases
Upgrade/Downgrade
Subscriber upgrades plan:
radclient -x 10.255.0.1:3799 coa secret <<EOF
Acct-Session-Id = "abng-1709312400-42"
Athena-Rate-Down = "200mbit"
Athena-Rate-Up = "80mbit"
EOF
Throttle for Abuse
Subscriber violates terms:
radclient -x 10.255.0.1:3799 coa secret <<EOF
Acct-Session-Id = "abng-1709312400-42"
Athena-Rate-Down = "1mbit"
Athena-Rate-Up = "1mbit"
EOF
Restore Normal Rate
Subscriber resolves issue:
radclient -x 10.255.0.1:3799 coa secret <<EOF
Acct-Session-Id = "abng-1709312400-42"
Athena-Rate-Down = "100mbit"
Athena-Rate-Up = "40mbit"
EOF
Troubleshooting
CoA Not Working
-
Check CoA is enabled:
abng> show configuration | match coa -
Check CoA port is correct:
sudo netstat -tlnp | grep 3799 -
Check firewall allows UDP 3799:
sudo ufw allow 3799/udp -
Check abngd logs:
sudo journalctl -u abngd -f | grep -i coa
Session Not Found
CoA-NAK: Session not found
Solution: Verify Acct-Session-Id matches session in show subscribers.
Next Steps
- Router-on-a-Stick — Router on same interface
- VRF Steering — VRF-based traffic steering