Making RADIUS Requests
UDP
To instantiate a client you can use ClientAsync
. A sync version is also provided in pyrad2.client
.
Note
Both your server and client must be loaded with the same dictionary. Remember, this is how the client and server can understand what it means to use a given attribute code.
from pyrad2.client_async import ClientAsync
from pyrad2.dictionary import Dictionary
client = ClientAsync(
server="localhost",
secret=b"Kah3choteereethiejeimaeziecumi",
timeout=4,
dict=Dictionary("dictionary"),
)
Note
In real code, we would never pass the secret hardcoded.
Sending an authentication packet
You can find the example for an auth request here.
$ uv run auth_async.py # make sure the server is running before
2025-07-07 13:06:36.984 | INFO | pyrad2.client_async:connection_made:112 - [localhost:3799] Transport created with binding in ::1:62525
2025-07-07 13:06:36.984 | INFO | pyrad2.client_async:connection_made:112 - [localhost:1812] Transport created with binding in 127.0.0.1:8000
2025-07-07 13:06:36.984 | INFO | pyrad2.client_async:connection_made:112 - [localhost:1813] Transport created with binding in ::1:64970
2025-07-07 13:06:36.989 | INFO | __main__:test_auth1:87 - Access accepted
2025-07-07 13:06:36.989 | INFO | __main__:test_auth1:91 - Attributes returned by server:
2025-07-07 13:06:36.989 | INFO | __main__:test_auth1:93 - Service-Type: ['Framed-User']
2025-07-07 13:06:36.989 | INFO | __main__:test_auth1:93 - Framed-IP-Address: ['192.168.0.1']
2025-07-07 13:06:36.989 | INFO | __main__:test_auth1:93 - Framed-IPv6-Prefix: ['fc66::/64']
This is the core code that creates the packet.
def create_request(client, user):
req = client.CreateAuthPacket(User_Name=user)
req["NAS-IP-Address"] = "192.168.1.10"
req["NAS-Port"] = 0
req["Service-Type"] = "Login-User"
req["NAS-Identifier"] = "trillian"
req["Called-Station-Id"] = "00-04-5F-00-0F-D1"
req["Calling-Station-Id"] = "00-01-24-80-B3-9C"
req["Framed-IP-Address"] = "10.0.0.100"
return req
You can find a list of standard RADIUS attributes here. Note that these do not include vendor-specific attributes.
Setting attributes
To set attributes in the Client
object, you need to replace underscores with hyphens. So instead of User_Name
, you use User-Name
. The former is used in python code and the latter is used directly in the underlying data.
req = srv.CreateAuthPacket(User_Name="wichert")
# But if acessing the attributes directly
req["User-Name"] = "wichert2"
req["NAS-IP-Address"] = "192.168.1.10"
[Suggestion]: Add some description for the valid arguments that could be passed to CreateAuthPacket.
RadSec
Note
This feature is currently experimental.
To use RadSec client, you must import from pyrad2.client.radsec.client
client = RadSecClient(
server="127.0.0.1",
secret=b"radsec",
dict=Dictionary("/dictionary"),
certfile="certs/ca/ca.cert.pem",
keyfile="certs/client/client.cert.pem"
certfile_server="certs/client/client.key.pem"
)
You can find an example implementation here.