Processing Packets
This page walks through the packet processing output of FreeRADIUS
version 4, line by line. It follows on from
Startup Text: once the server has printed
Ready to process requests, this is what you see when packets arrive.
The output on this page authenticates a user bob with the pap
module. Two requests are shown:
-
request
(0)with a wrong password (rejected) and request -
request
(1)with the correct password (accepted).
Request numbers
Every line for a packet starts with a request number in parentheses,
for example, (0). The number lets you match up all the messages for
one packet when the output contains messages from multiple packets
which are interleaved due to threading.
Receiving a packet
The first message for a new packet comes from the network listener
proto_radius_udp, and does not yet have a request number:
proto_radius_udp - Received Access-Request ID 3 length 61 radius_udp server * port 1812
All further processing for the request happens inside a virtual
server, which shows the virtuakl server name on the next line, in this
case default {. The following messages shows the packet type, the
RADIUS ID, the source and destination address and port, and the
network interface.
(0) default {
(0) Received Access-Request ID 104 from 127.0.0.1:58504 to 127.0.0.1:1812 via lo0
After the Received message, the server prints the attributes which
it received in the packet. For RADIUS, there are also some attributes
added by the server which describe the packet. A Net attribute
which contains the IP addresses and ports (source and destination)
socket details, and a Packet attribute which contains the RADIUS
header information. Finally, the Packet-Type attribute gives the
packet type.
(0) Message-Authenticator = 0xce9fbd43b2b13998783af1081aa112e3
(0) User-Name = bob
(0) User-Password = <<< secret >>>
(0) Net = {
(0) Src = {
(0) IP = 127.0.0.1
(0) Port = 52356
(0) }
(0) Dst = {
(0) IP = 127.0.0.1
(0) Port = 1812
(0) }
(0) Timestamp = 2026-06-12T22:08:14Z
(0) Interface = lo
(0) }
(0) Packet = {
(0) Id = 3
(0) Authenticator = 0x03e0b76e3a5ee133d76ab8bd8e767a70
(0) }
(0) Packet-Type = Access-Request
In v4, secret values such as User-Password are redacted
to <<< secret >>> by default, controlled by the suppress_secrets
setting in the log section of the main
radiusd.conf configuration
file. This allows you to share debug output without risk. Set
suppress_secrets = no if you need to see the real value of the
secret while debugging.
|
| If an attribute is not printed here, then it was not in the packet. No amount of changing the server configuration will add an attribute that the NAS did not send. If you need an attribute to be present, you must configure the NAS to send it. |
The recv Access-Request section
In v4, we now call the first processing section recv Access-Request.
In version 3 this section was called authorize. Its job is the same:
look up the user in a database, determine what type of authentication
to use, and set up the Auth-Type control attribute that tells the
server which authenticate section to run next.
(0) Running 'recv Access-Request' from file ./raddb/sites-enabled/default
(0) recv Access-Request {
The Running line names the section which is being run, and the file
where the section was loaded from. If you suspect that the server
isn’t using the configuration you’re editing, you can use this
information to double-check where the server is loading its policies
from.
Each module in the section runs in order. Messages which come from a module are prefixed with the module’s name and ` - `. After the module returns, the server prints the module name and its return code in parentheses.
(0) files - Looking for key "bob" (0) files - Found match "bob" on line 169 of ./raddb/mods-config/files/authorize (0) files (ok) (0) pap - Setting control.Auth-Type = pap (0) pap (updated) (0) } # recv Access-Request ((updated))
See the module rcode page for
the meaning and behavior of the various return codes such as ok or
updated.
In this output, the files module finds the user bob in the users
file and sets control.Password.Cleartext from the entry there,
returning ok. The pap module then sees a known-good password is
available, sets control.Auth-Type = pap, and returns updated.
The section closes with } # recv Access-Request updated, so the
final return code of the section is updated.
When you are diagnosing a problem, read this section carefully to answer:
-
Was the user found in the database? Look for the
files(orsql,ldap, etc.) module result. -
Was
Auth-Typeset? If none ofpap,chap,mschap,eap, etc. sets it, then the user will be rejected.
Authentication
After the recv Access-Request section, the server checks whether
Auth-Type was set. If it was not set, the server rejects the
request immediately:
(0) No 'Auth-Type' attribute found, cannot authenticate the user - rejecting the request
In this trace, Auth-Type = pap was set, so the server runs the
authenticate pap section.
(0) Running 'authenticate pap' from file ./raddb/sites-enabled/default
(0) authenticate pap {
The pap module compares the User-Password from the packet against
the known-good password that was set earlier by the files module.
For a wrong password, you should see output similar to this:
(0) pap - Login attempt with password (0) pap - Comparing with "known-good" Cleartext (5) (0) pap - ERROR: Cleartext password does not match "known good" password (0) pap (reject) (0) } # authenticate pap ((reject)) (0) Failed to authenticate the user
For a correct password, you should see output similar to this:
(1) pap - Login attempt with password (1) pap - Comparing with "known-good" Cleartext (5) (1) pap - User authenticated successfully (1) pap (ok) (1) } # authenticate pap ((ok))
If the pap module returns noop in the authenticate section,
that usually means no known-good password (such as
control.Password.Cleartext) was set in the recv Access-Request
section. Go back and check that the database module (files, sql,
ldap, etc.) found the user and returned ok or updated.
|
Sending a reply
When the server sends a reply, it runs a send section which is named
after the packet type.
Access-Reject
When authentication fails, the server runs the send Access-Reject
section before sending the reply.
(0) Running 'send Access-Reject' from file ./raddb/sites-enabled/default
(0) send Access-Reject {
(0) attr_filter.access_reject - Matched entry DEFAULT at line 11
(0) attr_filter.access_reject (updated)
(0) delay_reject - Delaying request by ~1.0s
(0) delay_reject (noop)
(0) } # send Access-Reject ((updated))
The attr_filter.access_reject module strips any reply attributes
that are not permitted in an Access-Reject packet.
The delay_reject module (an instance of rlm_delay) delays the
reply for a configurable time (default one second) before sending it
to the NAS. This delay protects against brute-force dictionary
attacks.
After the section finishes, the virtual server block closes and the reply is sent.
(0) default (noop) (0) } # default (noop) (0) Done request (0) Sending Access-Reject ID 104 from 0.0.0.0:1812 to 127.0.0.1:58504 length 50 via socket radius_udp server 127.0.0.1 port 1812 (0) Reply-Message = "Hello, bob" (0) Packet-Type = Access-Reject (0) Finished request
The Sending line mirrors the Received line, with the source and
destination swapped to show that the server is sending the reply to
the client. Any attributes in the reply are then printed.
| Always check the reply attributes. If the server is sending the correct reply but the user is still not getting the expected service, the problem is in the NAS, not the server. |
Access-Accept
When authentication succeeds, the server runs the send Access-Accept
section. With the default configuration, the send Access-Accept
section copies the user name into the reply, and then runs the various
policies in order to enforce standard compliance. These policies can,
of course, be edited or deleted.
(1) Running 'send Access-Accept' from file /etc/raddb/sites-enabled/default
(1) send Access-Accept {
(1) reply += {
(1) Session-State-User-Name = "bob"
(1) }
(1) policy remove_reply_message_if_eap {
...
(1) } # policy remove_reply_message_if_eap (noop)
(1) } # send Access-Accept ((noop))
(1) default (noop)
(1) } # default (noop)
(1) Done request
(1) Sending Access-Accept ID 79 from 0.0.0.0/0:1812 to 127.0.0.1:47730 length 50 via socket radius_udp server * port 1812
(1) Reply-Message = Hello, bob
(1) Packet-Type = Access-Accept
(1) Finished request
Accounting packets
Accounting packets follow a similar pattern, but use recv and send
section names taken from the accounting packet names.. The recv
Accounting-Request section runs when the server receives an
Accounting-Request packet. After that section runs, the server
looks at Acct-Status-Type, and runs an accounting section named
for that status type. For example, accounting Start { }. This
behavior lets you configure policies which are run only when specific
types of accounting messages are received.
For example, you likely want to run different policies on "Start" packets, than "Stop" packets.
Finally, the send Accounting-Response section runs before the reply
is sent.
(2) default {
(2) Received Accounting-Request ID 123 from 127.0.0.1:42980 to 127.0.0.1:1813 via lo
...
(2) Running 'recv Accounting-Request' from file /etc/raddb/sites-enabled/default
(2) recv Accounting-Request {
...
(2) } # recv Accounting-Request ((ok))
(2) accounting Start {
(2) ... ignoring empty subsection ...
(2) }
(2) Running 'send Accounting-Response' from file /etc/raddb/sites-enabled/default
(2) send Accounting-Response {
(2) detail (ok)
(2) attr_filter.accounting_response - Matched entry DEFAULT at line 12
(2) attr_filter.accounting_response (updated)
(2) } # send Accounting-Response ((updated))
(2) default (ok)
(2) } # default (ok)
(2) Done request
(2) Sending Accounting-Response ID 123 from 0.0.0.0/0:1813 to 127.0.0.1:42980 length 20 via socket radius_udp server * port 1813
(2) Packet-Type = Accounting-Response
(2) Finished request
If the server stops producing output
If Ready to process requests was printed but nothing appears after
that, the server is not receiving any packets. That is a network or
firewall problem, not a server configuration problem. Check that the
NAS is sending packets to the correct IP address and port, and that no
firewall is blocking UDP on port 1812 or 1813.