Skip to content

pyrad2

Tests python pre-commit Code style: ruff Checked with mypy

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?  → Compatibility

    What 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-proto packet vectors regression-tested against upstream. See FreeRADIUS Conformance.
  • Shared RetryPolicy with exponential backoff, jitter, and per-attempt waits — works on both sync Client and ClientAsync. The legacy retries= / timeout= kwargs continue to behave identically. See Retries and backoff.
  • EapMethod ABC + registry. pyrad2.eap is now a package; the sync, async, and RadSec clients share one method-agnostic challenge loop. Adding a new method is a register_method("eap-foo", FooMethod) call.
  • ipv4prefix codec (RFC 5090) — full encode/decode wired into encode_attr / decode_attr.
  • PEP 561 typingpy.typed ships in the wheel.
  • Proxy fix + make scenario_proxy demo wiring a downstream client through a Proxy to an upstream Server in 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