$ radiusd -X
Radiusd
The radiusd.conf
file contains the server configuration. When the
server starts, it reads this file and caches it. The data is parsed to
set values for variables or to determine other configuration, such as
modules.
Once the configuration is loaded, the server receives and processes
packets. When the server is running in debugging mode (radiusd -X
),
the configuration that is being used is printed to the current terminal
window. This information includes details about files being read, modules
being loaded, and the names and values of any settings used.
The variables and subsections in the default radiusd.conf
file and
how they define specific functionality are discussed in more detail in
the VARIABLES section. To conserve space, this document describes only the variables that are commonly modified; the radiusd.conf
file
contains many more variables, which are documented in the comments
section next to the variable definitions.
Run the server in debugging mode and READ the output.
Note
|
This point cannot be emphasized strongly enough. The vast majority of problems can be solved by carefully reading the debugging output, which includes warnings about common issues and suggestions for how they may be fixed. There may be a lot of output, but look carefully for words like: "warning", "error", "reject", or "failure". The messages there will usually be enough to guide towards a solution. |
Note
|
Before asking a question on the mailing list, in addition to explaining what occurred, make sure to include the output from debugging mode (radiusd -X). |
The location of other config files and logfiles are declared in this file.
Also, general configuration for modules can be done in this file, as it is exported through the API to modules that ask for it.
See man radiusd.conf
for documentation on the format of this file. Note that the individual configuration items are NOT documented in that "man" page. They are only documented here, in the comments.
The "unlang" policy language can be used to create complex if / else policies. See man unlang
for details.
prefix = @prefix@
exec_prefix = @exec_prefix@
sysconfdir = @sysconfdir@
localstatedir = @localstatedir@
sbindir = @sbindir@
logdir = @logdir@
raddbdir = @raddbdir@
radacctdir = @radacctdir@
name of the running server.
See also the "-n" command-line option.
name = radiusd
Location of config and logfiles.
confdir = ${raddbdir}
modconfdir = ${confdir}/mods-config
certdir = ${confdir}/certs
cadir = ${confdir}/certs
run_dir = ${localstatedir}/run/${name}
Should likely be ${localstatedir}/lib/radiusd
db_dir = ${raddbdir}
In Version 2, all of the other configuration sections like "authorize {}", "authenticate {}", "accounting {}", have been moved to the following file:
raddb/sites-available/default
This is the default virtual server, which has the same configuration as in versions 1.0.x and 1.1.x. The default installation enables this virtual server. To create policies for the local site, this file should be edited.
For more documentation on virtual servers, see:
raddb/sites-available/README
Directives
- Syntax
-
checkrad = filename
- Default
-
${sbindir}/checkrad
- Description
-
The program to execute to do concurrency checks.
- Syntax
-
cleanup_delay = integer
- Default
-
5
- Description
-
The time to wait (in seconds) before cleaning up a reply that was sent to the NAS.
-
Useful range of values: 2 to 10
-
This RADIUS request and the reply are normally cached internally for a short period of time after the reply is sent to the NAS. The reply packet may be lost in the network, and the NAS will not see it. The NAS will then re-send the request, and the server will respond quickly with the cached reply.
-
If this value is set too low, then duplicate requests from the NAS may not be detected and will instead be handled as separate requests.
-
If this value is set too high, then the server will cache too many requests, and some new requests may get blocked. (See
max_requests
.)
- Syntax
-
hostname_lookups = boolean
- Default
-
no
- Description
-
Logs the names of clients or just their IP addresses; e.g., www.freeradius.org (yes) or 206.47.27.232 (no).
-
The default is
no
because enabling it means that each client request results in at least one lookup request to the nameserver. Enabling hostname_lookups also causes the server to stop randomly for 30 seconds from time to time if the DNS requests take too long. -
Turning
hostname_lookups
off also means that, if the server sees an IP address with no associated name, then the server won’t block for 30 seconds.
- Syntax
-
libdir = string
- Default
-
@libdir@
- Description
-
The libdir directive outlines where to find the rlm_* modules.
-
This directive is set automatically at configuration time.
-
NOTE: If the server builds and installs but ultimately fails at execution time and returns an 'undefined symbol' error, then the libdir directive can be used to work around the problem. The cause of this problem is usually that a library has been installed on the system in a place where the dynamic linker cannot find it. When executing as root (or another user), the personal environment may be set up to allow the dynamic linker to find the library. When executing as a daemon, FreeRADIUS may not have the same personalized configuration.
-
To work around the problem, find out which library contains that symbol, then add the directory containing that library to the end of 'libdir' with a colon separating the directory names. No spaces are allowed.
e.g., libdir = /usr/local/lib:/opt/package/lib
-
The LD_LIBRARY_PATH environment variable can also be set in the script that starts the server.
-
If that does not work, then the server can be re-configured and re-built to not use shared libraries, via:
./configure --disable-shared
make
make install
- Syntax
-
max_request_time = integer
- Default
-
30
- Description
-
The maximum time (in seconds) to handle a request.
-
Useful range of values: 5 to 120
-
Requests that take more time to process may be killed, in which case a REJECT message is returned.
Warning
|
If requests take a long time to be handled, this delay may indicate a bug located either in the server, in one of the modules used to handle a request, or in the local configuration. This problem is most often seen when using an SQL database. If it takes more than a second or two to receive an answer from the SQL database, this likely means that the database hasn’t been indexed. See the SQL server documentation for more information. |
- Syntax
-
max_requests = integer
- Default
-
1024
- Description
-
The maximum number of requests of which the server keeps track. This number should be 256 multiplied by the number of clients; e.g., for 4 clients this number should be 1024.
-
Useful range of values: 256 to infinity
-
If this number is too low, then when the server becomes busy, it will not respond to any new requests until the
cleanup_delay
time has passed and the old requests have been removed. -
If this number is set too high, then the server will use a bit more memory for no real benefit.
-
It is better to set it too high than too low. Setting it to 1000 per client is the highest it should be.
Syntax: panic_action = string
- Description
-
Command to execute if the server dies unexpectedly.
Note
|
For production systems, actions should always exit. An interactive action means the server is not responding to requests. An interactive action means the server will not restart. |
Note
|
The server must not be allowed execute untrusted panic action code. |
-
The panic action is a command that will be executed if the server receives a fatal, non-user-generated signal, i.e., SIGSEGV, SIGBUS, SIGABRT, or SIGFPE.
-
This command can be used to start an interactive debugging session so that information regarding the current state of the server can be acquired.
-
The following string substitutions are available:
%e |
The currently executing program, e.g., /sbin/radiusd |
%p |
The PID of the currently executing program, e.g., 12345 |
-
Standard
${}
substitutions are also allowed. -
An example panic action for opening an interactive session in GDB (not to be used on a production system) would be:
panic_action = "gdb %e %p"
-
An example panic action for opening an automated session in GDB (may be used on a production system) would be:
panic_action = "gdb -silent -x ${raddbdir}/panic.gdb %e %p 2>&1 | tee ${logdir}/gdb-${name}-%p.log"
- Syntax
-
pidfile = filename
- Default
-
${run_dir}/${name}.pid
- Description
-
This directive is where to place the PID of the RADIUS server.
-
The server may be signalled while running by use of this file.
-
This file is written only when running in daemon mode:
e.g., kill -HUP `cat /var/run/radiusd/radiusd.pid`
Clients Configuration
The client configuration is defined in clients.conf
.
The clients.conf
file contains all of the information from the old clients
and naslist
configuration files. It is not recommended to use clients
or naslist
, although they are still supported.
Anything listed in clients.conf
will take precedence over the information from the old-style configuration files.
$INCLUDE clients.conf
Concurrency checks
The program to execute to do concurrency checks:
checkrad = ${sbindir}/checkrad
Instantiation
This section orders the loading of the modules. Modules listed here will get loaded before the later sections (authorize
, authenticate
, etc.) get examined.
Listing modules here also ensures that the order in which they are initialized is controlled. Listing modules in order here ensures that, in the event of one module requiring information defined by another module, the configuration will be OK.
This section is not strictly needed. Modules are automatically loaded and initialized when a section like authorize
references them. However, if some modules are not listed in any of the referenced sections, they can be listed here.
For versions higher than Version 2, all of the modules in the mods-enabled
directory are loaded after the modules listed here. Loading the mods-enabled
directory means that modules don’t actually need to be listed here.
The counter module is listed here so that the check_name attribute is registered before any module that sets it daily.
Subsections can be thought of as "virtual" modules, e.g., if there are two redundant SQL servers and they should be used in the authorize and the accounting
sections, then a "redundant" block, containing the exact same text, can be placed in each section.
Alternatively, the following lines can be uncommented and redundant_sql
listed in the authorize and accounting
sections:
redundant redundant_sql {
sql1
sql2
}
Load virtual servers.
This next $INCLUDE line loads files in the directory that matches the regular expression: /[a-zA-Z0-9_.]+/
It allows the definition of new virtual servers simply by placing a file into the raddb/sites-enabled/ directory.
$INCLUDE sites-enabled/
Logging section
Logging section. The various "log_*" configuration items will eventually be moved here.
Directives
- Syntax
-
auth = boolean
- Default
-
no
- Description
-
Logs authentication requests to the log file.
- Syntax
-
auth_badpass = boolean
- Default
-
no
- Description
-
Logs passwords with the authentication requests: logs password if it’s rejected.
- Syntax
-
auth_goodpass = boolean
- Default
-
no
- Description
-
Logs passwords with the authentication requests: logs password if it’s correct.
- Syntax
-
colourise = boolean
- Default
-
yes
- Description
-
Highlights important messages sent to stderr and stdout.
-
Option will be ignored (disabled) if output of TERM is not an xterm or output is not to a TTY.
- Syntax
-
destination = string
- Default
-
files
- Description
-
Destination for log messages. This can be one of:
files |
log to "file", as defined below. |
syslog |
to syslog (see also the "syslog_facility", below. |
stdout |
standard output |
stderr |
standard error. |
-
The command-line option "-X" overrides this option and forces logging to go to stdout.
- Syntax
-
file = filename
- Default
-
${logdir}/radius.log
- Description
-
If destination = "files", then the logging messages for the server are appended to the tail of this file. If the server is running in debugging mode, then this file is NOT used.
- Syntax
-
msg_denied = string
- Description
-
The message when the user exceeds the Simultaneous-Use limit.
- Syntax
-
msg_badpass = string
- Description
-
Logs additional text at the end of the
Login OK
messages. For this directive to work, theauth
andauth_badpass
configurations have to be set toyes
. -
The strings below are dynamically expanded, which means that they can be anything. However, note that this expansion can be slow and can negatively impact server performance.
- Syntax
-
msg_goodpass = string
- Description
-
Logs additional text at the end of the
Login OK
messages. For this directive to work, theauth
andauth_goodpass
configurations have to be set toyes
. -
The strings below are dynamically expanded, which means that they can be anything. However, note that this expansion can be slow and can negatively impact server performance.
- Syntax
-
requests = filename
- Default
-
${logdir}/radiusd-%\{%{Virtual-Server}:-DEFAULT}-%Y%m%d.log
- Description
-
If this configuration parameter is set, then log messages for a request go to this file, rather than to radius.log. In other words, this file becomes a log file per request, once the server has accepted the request as being from a valid client. Messages that are not associated with a request still go to radius.log.
-
Not all log messages in the server core have been updated to use this new internal API. As a result, some messages will still go to radius.log.
-
The file name is expanded dynamically. Only server-side attributes should be used for the filename (e.g., things that can be controlled). Using this feature may also slow down the server substantially, especially if things like SQL calls are used as part of the expansion of the filename.
-
To avoid having the log messages distributed over multiple files, the name of the log file should use attributes that don’t change over the lifetime of a request, such as User-Name, Virtual-Server, or Packet-Src-IP-Address.
-
Logging can be enabled for an individual request by a special dynamic expansion macro: %\{debug: 1}, where the debug level for this request is set to '1' (or 2, 3, etc.); e.g.,
update control {
Tmp-String-0 = "%\{debug:1}"
}
-
The attribute to which value is assigned is unimportant and should be a "throw-away" attribute with no side effects.
- Syntax
-
stripped_names = boolean
- Default
-
no
- Description
-
Logs the full
User-Name
attribute, as it was found in the request.
- Syntax
-
syslog_facility = string
- Default
-
daemon
- Description
-
Which syslog facility to use, if ${destination} == "syslog". The exact values permitted here are OS-dependent. This value probably should not be changed.
Module Configuration
The names and configuration of each module are located in this section.
After the modules are defined here, they may be referred to by name in other sections of this configuration file.
Each module has a configuration as follows:
name [ instance ] {
config_item = value
...
}
The 'name' above is used to load the rlm_name
library that implements the functionality of the module.
The 'instance' is optional. To have two different instances of a module, it first must be referred to by 'name'. The different copies of the module are then created by inventing two 'instance' names, e.g., 'instance1' and 'instance2'.
The instance names can then be used in later configuration instead of the original 'name'. See the radutmp
configuration for an example.
As of 3.0, modules are in mods-enabled/. Files matching the regex /[a-zA-Z0-9_.]+/ are loaded. The modules are initialized ONLY if they are referenced in a processing section, such as authorize, authenticate, accounting, pre/post-proxy, etc.
$INCLUDE mods-enabled/
Policy
Policies are virtual modules, similar to those defined in the instantiate
section above.
Defining a policy in one of the policy.d files means that it can be referenced in multiple places as a name
, rather than as a series of conditions to match and actions to take.
Policies are something like subroutines in a normal language, except that they cannot be called recursively. They MUST be defined in order.
Note
|
If policy A calls policy B, then B MUST be defined before A. |
$INCLUDE policy.d/
Proxy Configuration
The server has proxying turned on by default. If a system is NOT set up to proxy requests to another server, then turn proxying off here. This will save a small amount of resources on the server.
If proxying is turned off and the configuration files say to proxy a request, then an error message will be logged.
To disable proxying, change the yes
to no
and comment the $INCLUDE line:
$INCLUDE proxy.conf
Directives
- Syntax
-
proxy_requests = boolean
- Default
-
yes
- Description
-
Turns proxying of RADIUS requests on or off.
Security
There may be multiple methods of attacking a server. This section holds the configuration items that minimize the impact of those attacks.
Directives
- Syntax
-
allow_core_dumps = boolean
- Default
-
no
- Description
-
Core dumps are a bad thing. This value should only be set to
yes
if a problem with the server is being debugged.
- Syntax
-
allow_vulnerable_openssl = boolean
- Default
-
no
- Description
-
Allows the server to start with versions of OpenSSL known to have critical vulnerabilities.
-
This check is based on the version number reported by libssl and may not reflect patches applied to libssl by distribution maintainers.
- Syntax
-
chroot = filename
- Default
-
/path/to/chroot/directory
- Description
-
The directory where the server does
chroot
. -
The
chroot
process is done very early in the course of starting the server. After the chroot process has been performed, the server switches to theuser
configuration item listed in this document (which MUST be specified). Ifgroup
is specified, the server switches to that group, too. Any other groups listed for the specifieduser
in/etc/group
are also added as part of this process. -
The current working directory (chdir / cd) is left outside of the chroot process until all of the modules have been initialized. This allows the
raddb
directory to be left outside of the chroot process. Once the modules have been initialized, the server does achdir
to${logdir}
. Proceeding in this manner means that it should be impossible to break out of the chroot. -
To avoid any security issues related to this use of chdir, simply ensure that the
raddb
directory is inside of the chroot and runcd raddb
BEFORE starting the server. -
If the server is statically linked, then the only files that have to exist in the chroot are ${run_dir} and ${logdir}. If you do the "cd raddb" as discussed above, then the "raddb" directory has to be inside of the chroot directory, too.
- Syntax
-
group = string
- Default
-
radius
- Description
-
Radiusd is run as the number of this group.
-
If commented out, the server will run as the group that started it. In order to change to a different group, the server MUST be started as root (or have root privileges).
-
It is STRONGLY recommended that the server be run with as few permissions as possible. That is, if shadow passwords are not being used, then the group items below should be set to radius.
-
NOTE that some kernels refuse to setgid(group) when the value of (unsigned)group is above 60000; don’t use group
nobody
on these systems! -
On systems with shadow passwords,
group = shadow
might need to be set for the server to be able to read the shadow password file. If users can be authenticated while in debug mode, but not while in daemon mode, then it may be that the debugging mode server is running as a user that can read the shadow info and that the user listed below cannot. -
The server will also try to use
initgroups
to read /etc/groups. It will join all groups whereuser
is a member. This can allow for some finer-grained access controls.
- Syntax
-
max_attributes = integer
- Default
-
200
- Description
-
The maximum number of attributes permitted in a RADIUS packet. Packets that have MORE than this number of attributes in them will be dropped.
-
If this number is set too low, then no RADIUS packets will be accepted.
-
If this number is set too high, then an attacker may be able to send a small number of packets that will cause the server to use all available memory on the machine.
-
Setting this number to 0 means "allow any number of attributes".
- Syntax
-
reject_delay = integer
- Default
-
1
- Description
-
When sending an
Access-Reject
, a delay of a few seconds may occur. This delay may help slow down a DoS attack. The delay also helps to slow down any potential use of brute-force to crack a user’s password. -
Setting this number to 0 means "send rejects immediately"
-
If this number is set higher than
cleanup_delay
, then the rejects will be sent atcleanup_delay
time, when the request is deleted from the internal cache of requests. -
Useful ranges: 1 to 5
- Syntax
-
status_server = boolean
- Default
-
yes
- Description
-
Whether or not the server will respond to Status-Server requests.
-
When sent a Status-Server message, the server responds with an Access-Accept or Accounting-Response packet.
-
This is mainly useful for administrators who want to "ping" the server without adding test users or creating fake accounting packets.
-
It’s also useful when an NAS marks a RADIUS server "dead". The NAS can periodically "ping" the server with a Status-Server packet. If the server responds, it must be alive, and the NAS can start using it for real requests.
-
See also raddb/sites-available/status
- Syntax
-
user = string
- Default
-
radius
- Description
-
Radiusd is run as the name of this user.
-
If commented out, the server will run as the user that started it. In order to change to a different user, the server MUST be started as root (or have root privileges).
-
It is STRONGLY recommended that the server be run with as few permissions as possible. That is, if shadow passwords are not being used, then the user items below should be set to radius.
-
NOTE that some kernels refuse to setgid(group) when the value of (unsigned)group is above 60000; don’t use group
nobody
on these systems! -
On systems with shadow passwords,
group = shadow
might need to be set for the server to be able to read the shadow password file. If users can be authenticated while in debug mode, but not while in daemon mode, then it may be that the debugging mode server is running as a user that can read the shadow info and that the user listed below cannot. -
The server will also try to use
initgroups
to read /etc/groups. It will join all groups whereuser
is a member. This can allow for some finer-grained access controls.
SNMP notifications
Uncomment the following line to enable snmptraps. Note that the full path must be configured to the snmptrap
command in the trigger.conf
file.
$INCLUDE trigger.conf
Thread pool
The thread pool is a long-lived group of threads that take turns (round-robin) handling any incoming requests.
It is a good idea to have a few spare threads around so that high-load situations can be handled immediately. If there aren’t any spare threads, then the request handling will be delayed while a new thread is created and added to the pool.
Too many spare threads are not a good idea, as they’ll be sitting there taking up resources and not doing anything productive.
The numbers given below should be adequate for most situations.
Directives
- Syntax
-
auto_limit_acct = boolean
- Default
-
no
- Description
-
Automatically limits the number of accounting requests. This configuration item tracks how many requests per second the server can handle. It does this by tracking the packets received by the server for processing and comparing them to the packets handled by the child threads.
-
If the received PPS is larger than the processed PPS and the queue is more than half full, then new accounting requests are probabilistically discarded. This lowers the number of packets that the server needs to process. Over time, the server will "catch up" with the traffic.
-
Throwing away accounting packets is usually safe and low impact. The NAS will retransmit them in a few seconds or even in a few minutes. Vendors should read RFC 5080 Section 2.2.1 to see how accounting packets should be retransmitted. Using any other method is likely to cause network meltdowns.
- Syntax
-
max_queue_size = integer
- Default
-
65536
- Description
-
When the server receives a packet, it places it onto an internal queue, where the worker threads (configured above) pick it up for processing. The maximum size of that queue is given here.
-
When the queue is full, any new packets are silently discarded.
-
The most common cause of the queue being full is that the server is dependent on a slow database and it has received a large "spike" of traffic. When that happens, there is very little that can be done other than ensurin the server receives less traffic or ensuring that the database can handle the load.
- Syntax
-
max_requests_per_server = integer
- Default
-
0
- Description
-
There may be memory leaks or resource allocation problems with the server. If so, set this value to approximately 300 so that the resources will be cleaned up periodically.
-
This should only be necessary if there are serious bugs in the server that have not yet been fixed.
-
'0' is a special value meaning 'infinity' or 'the servers never exit'.
- Syntax
-
max_servers = integer
- Default
-
32
- Description
-
Limit on the total number of servers running.
-
If this limit is ever reached, clients will be locked out, so
max_servers
should not be set too low. This number is intended mainly as a brake to keep a runaway server from taking the system with it as it spirals down. -
Sometimes the server regularly reaches the
max_servers
number of threads and increasingmax_servers
doesn’t seem to make much difference. -
If this is the case, then the problem is most likely that the back-end databases are taking too long to respond and are preventing the server from responding in a timely manner.
-
The solution is NOT do keep increasing the
max_servers
value, but instead to fix the underlying cause of the problem: a slow database, orhostname_lookups=yes
. -
For more information, see
max_request_time
.
- Syntax
-
max_spare_servers = integer
- Default
-
10
- Description
-
Server-pool size regulation. Rather guessing how many servers are needed, FreeRADIUS dynamically adapts to the load it sees; that is, it tries to maintain enough servers to handle the current load plus a few spare servers to handle transient load spikes.
-
FreeRADIUS does this by periodically checking how many servers are waiting for a request. If there are more than
max_spare_servers
, some of the spares die off. The default values are probably OK for most sites.
- Syntax
-
min_spare_servers = integer
- Default
-
3
- Description
-
Server-pool size regulation. Rather than guessing how many servers are needed, FreeRADIUS dynamically adapts to the load it sees; that is, it tries to maintain enough servers to handle the current load plus a few spare servers to handle transient load spikes.
-
FreeRADIUS does this by periodically checking how many servers are waiting for a request. If there are fewer than
min_spare_servers
, it creates a new spare. The default values are probably OK for most sites.
- Syntax
-
start_servers = integer
- Default
-
5
- Description
-
The number of servers to start initially. This number should be a reasonable ballpark figure.