pyrad2

A modern Python toolkit for building RADIUS clients and servers.
pyrad2 gives you the protocol - packet encoding, dictionary parsing, transport handling, retransmission, TLS - so you can write the business logic. Build an authentication backend, a CoA proxy, a RadSec accounting collector, or a network-access controller without touching wire formats.
from pyrad2.client_async import ClientAsync
from pyrad2.dictionary import Dictionary
client = ClientAsync(server="radius.example.com", secret=b"...", dict=Dictionary("dictionary"))
req = client.create_auth_packet(User_Name="alice", User_Password="hunter2")
reply = await client.send_packet(req)
if reply.code == PacketType.AccessAccept:
print("Welcome,", reply["User-Name"][0])
Where to next
-
New here? → Getting Started
Install, run a working exchange in 30 seconds, and learn the three concepts you actually need.
-
Building a server? → Running a RADIUS Server
Authentication, accounting, CoA, Status-Server, duplicate detection, RadSec.
-
Building a client? → Making RADIUS Requests
Send your first request, then layer in EAP, Message-Authenticator, health checks, and RadSec.
-
Coming from
pyrad? → CompatibilityWhat changed in the fork and what you need to update.
What's new in 3.1
- FreeRADIUS conformance suite — 281 vendor/RFC/internal dictionaries plus all 41 of FreeRADIUS v4's
decode-protopacket vectors regression-tested against upstream. See FreeRADIUS Conformance. - Shared
RetryPolicywith exponential backoff, jitter, and per-attempt waits — works on both syncClientandClientAsync. The legacyretries=/timeout=kwargs continue to behave identically. See Retries and backoff. EapMethodABC + registry.pyrad2.eapis now a package; the sync, async, and RadSec clients share one method-agnostic challenge loop. Adding a new method is aregister_method("eap-foo", FooMethod)call.ipv4prefixcodec (RFC 5090) — full encode/decode wired intoencode_attr/decode_attr.- PEP 561 typing —
py.typedships in the wheel. - Proxy fix +
make scenario_proxydemo wiring a downstream client through aProxyto an upstreamServerin one process. - Full release notes in CHANGELOG.md.
What's in the box
| Feature | Spec |
|---|---|
| RADIUS client & server (sync + async) | RFC 2865 |
| RadSec - RADIUS over TLS | RFC 6614 |
| RADIUS/1.1 over RadSec (experimental) | RFC 9765 |
| CoA & Disconnect (Dynamic Authorization) | RFC 5176 |
| Status-Server health checks | RFC 5997 |
| Duplicate detection / response cache | RFC 5080 §2.2.2 |
| BlastRADIUS-safe defaults | CVE-2024-3596 - Message-Authenticator enforced on Access-Request out of the box |
| FreeRADIUS dictionary support | Extended attributes, vendor formats, EVS, nested TLVs, WiMAX continuation, RFC 8044 arrays - see Dictionary Reference |
| FreeRADIUS interop conformance | 281 dictionaries + 41 packet vectors regression-tested against upstream FreeRADIUS - see FreeRADIUS Conformance |
| Authentication methods | PAP, CHAP, EAP-MD5, EAP-GTC out of the box; MS-CHAPv2 + EAP-MSCHAPv2 via pip install pyrad2[mschap] - see Authentication Methods |
| Wire-level packet tracing | PYRAD2_TRACE=1 + PYRAD2_TRACE_UNSAFE=1 |
pyrad2 is a library, not a daemon. It is not a drop-in replacement for FreeRADIUS; it gives you the moving parts to build your own.
Project
- Source: github.com/pyradius/pyrad2
- Releases: Release notes
- Issues & PRs: Issue tracker - PRs are very welcome.