A full-featured Radius server with many options for special requirements and non-standard environments.




-d, -Debug number, -Debug=number
The first form increases the debug level by one, while the next two forms set the debug level to that value. Default zero, may be applied multiple times. Debug level one logs events, Debug level two also gives a dump of each packet. Turning debug on prevents the server from daemonizing.

-C filename, -Config filename, -Config=filename
Sets the config file to be filename instead of the default radiance.conf. Note that the presense of radiusd.conf is also checked for backwards compatibility.

-D filename, -Directory filename, -Directory=filename
Sets the base directory the server will use to find all other files from. The default is /usr/local/radiance for POSIX systems, and C:\Program Files\Iagu\Radiance for Win32.

-Accounting filename, -Accounting=filename
Sets the accounting file, unless overriden by per-realm or per-user data. The default is ``accounting''.

-StoreForward filename, -StoreForward=filename
Turns on the Accounting store and forward database, using the named file as the buffer for unsent data. Requires MLDBM support. Off by default.

-Clients filename, -Clients=filename
Sets the clients file for storing per-client data, including secrets. The default is ``clients''.

-Dictionary filename, -Dictionary=filename
Sets the dictionary to be used for mapping various strings to numbers and back again. Unlike many other radius servers, this dictionary is also used by the code itself in the processing chain, not just for display, so modifying it can change the behaviour of radiance. The default is ``dictionary''.

-Status filename, -Status=filename
Status database used to record current and recent accoutning records, used by things such as the radiance-status.cgi script. Off by default as it uses the Berkeley DB, and some Solaris versions go into internal infinite loops when demonized.

-Realms filename, -Realms=filename
Set the directory to find per-realm and per-user configuration data. Defaults to ``realms/''.

-AuthPort port, -AuthPort=port
Sets the port to listen on for authentication. Defaults to port 1812. If you think it should default to 1645, go and read the section on ``Incorrect Port''.

-AcctPort port, -AcctPort=port
Sets the port to listen of for accounting. Defaults to AuthPort + 1. Note that radiance will quite happily process any radius packet received on either the AuthPort or the AcctPort.

-IP address, -IP=address
By default, radiance binds to INADDR_ANY on the designated ports. If you wish it to bind to a specific IP address for some reason, you may specify such an IP address with this option.

-InetD number, -InetD=number
DEPRECIATED. Tells radiance that it is running under inetd or some equivalent if the number is set to be 1. Normally not necessary, as radiance assumes it is run from inetd if standard input is a socket.

All command line options can also be specified in the Config file. The leading hyphens are removed in this case, the ``='' format is required, and white-space around the equals signs is allowed.


Each line must be one of the following:

        Blank line


        [ # Comment ]


        IP_Address [ / bit_mask ] [ : udp_port_number ] secret
            [ - flags ]
            [ [ line_number - line_number / ]
                [ dialed_number_contains : ]
                [ @ ] default_realm ] *
            [ # Comment ]

A default realm is appended only if no realm already exists in the username. A leading @ on the realm forces appending that realm name, regardless of the whether or not the username already has a realm.

This peer can't sign packets correctly, so ignore incorrectly signed authenticators.

Some radius servers don't correctly reflect back the State-ID in a proxied packet as required by the RFC's. Normally radiance complains about this to syslog. This option supresses syslog reporting of the lack of presence of a State-ID in a response, to avoid filling up log files unnecessarily.

Examples      secret         secret_4        -s      not_so_secret         not_so_secret_1 -a kind_of_secret   kind_of_secret  1-12/

In the second to last example, if the dialed phone number finishes with 4060, the realm ``'' is forced on the end of the username. Otherwise, the realm ``'' is appended to the username only if there isn't an existing realm on the username. The presence of the @ forces appending, otherwise it's just a default realm.

In the last example, the realm ``'' is forced on if the NAS-Port is in the range 1-12, otherwise it's as per the previous line.


Go into the realms directory. Note that the username and any realm is lowercased in advance of any matching.

If there is no realm specified in the current username, look for ``NULL''.
If there is a realm specified, look for a match. If one is not found, start stripping the domain components from left to right one at a time looking for a match.
If there is a realm specified but no mtahc is found, look for ``DEFAULT''.

If the match is on a file, that is then is read in as a UserInfo structure. If it's a directory, the search continues.

Look in that directory for a file called ``username@realm''
Look in that directory for a file called ``username''
Look in that directory for a file called ``DEFAULT''

Once a file is found, that is read in as a UserInfo structure. If no match is found, then authentication fails and accounting packets use the default accounting file and perform no special actions.


These files define the behaviour of the radius server for this username. Comments can occur anywhere and start with a ``#'' and last to the end of the line. Blank lines are allowed. A string can consist of any number of non-space characters, or be surrounded by double quotes and have any non-double quote characters (including whitespace) inside. A line finishing with a backslash ``\'' is continued on the next line (including comments!)

Password = string
Define a plain-text password for the user.

Unix-Crypt = string
Define a password stored in standard Unix crypt format. Cannot be used for CHAP authentication.

MD5-Hash = string
Define the MD5-hash of a password. Cannot be used for CHAP authentication.

Auth-Succeed = string
Authentication automatically succeeds for the following types of requests. Used for outbound dialing,

Group = string
Use the filename as a userinfo structure to inherit defaults from. Usuaully used to group together a common set of defaults for a number of users.

Radius = (hostname:port realm)
Specify a Radius server to proxy the packet to. Note that one is added to the target port if it is an accounting request.

The ``realm'' is optional. It specifies a realm to add to the Username prior to proxying, or the special realm ``-'', which indicates the realm should be stripped prior ro proxying.

This user may not roam. If the NAS-IP-Address in the request is not covered by the clients file, authentication is denied. Designed for use with GRiC and/or iPass.

Concurrency-Limit = number
Define a maximum number of simultaneous logins this user may have. Often set to 1 in associaion with block-hour accounts with atomated cut-off.

Accounting = string
Define an alternate file for accounting to be logged into.

Module = module_name (arguments)
Push this module onto the stack of modules to be processed for this request.

Fail-Message = string
Return this message if authentication fails. Often used for overdrawn accounts in combination with ``Concurrency-Limit=0''

+string = string
Set this value in authentication. For example:
        +Session-Timeout = 2147
        +Cisco-AVpair = "lcp:interface-config=ip unnumbered ethernet 0"
        +Cisco-AVpair = "ip:inacl#1=permit tcp any host eq telnet"
        +Cisco-AVpair = "ip:inacl#2=deny icmp any any"
        +Cisco-AVpair = "ip:route#1="
        +Cisco-AVpair = "ip:route#2=10.720.0"
        +Cisco-AVpair = "ipx:inacl#3=deny any"

> string = string
Set this value in accounting.

Remove this value in proxy authentication responses.

> string
Remove this value in proxy accounting responses.


After the UserInfo structure is parsed for a particular radius packet, it is passed to all defined modules to modify or act on. The code is called as follows:

        Module_Name -> radius_userinfo
                (\$username, \$info, \$packet, arguments);

Thus the second argument is a pointer to a hash of the current userinfo structure, and the third argument is a pointer to the current parsed radius packet. This allows you to modify the userinfo structure if desired. Of particular interest is pushing on attributes. Do the following:

        push (@{$info -> {'+'}, 'Session-Timeout', '2147');

For packet details, a quick look at the code for unpack_data in is a good idea, but the highlights include:

$packet -> {'code'}
Radius code, 1 for authentication request, 2 for authentication successful, 3 for authentication failure, 4 for accounting request and 5 for accounting response. As you are passed the request packet (the response packet is constructed after all modules have been called), you should only see codes 1 and 4.

$packet -> {'av'} -> [$main::RAD_ATTR_SESSION_ID]
An array containging all Session-ID attributes for this packet. All values are dynamically determined from the dictionary, so if you add something to the dictionary it can be referenced in the code as well.


Accounting Store & Forward has not been fully implemented.


Incorrect Port
This Radius server uses the correctly assigned ports by default of 1812 for authentication and 1813 for accounting, not 1645 and 1646 as many people assume. See if you don't believe me, and observe ``datametrics'' on 1645 and ``sa-msg-port'' on 1646. So many people have got it wrong because Livingston used an unassigned port number before standardisation.

Null Termination
From RFC 2138, ``Remote Authentication Dial In User Service (RADIUS)'':

Note that a ``string'' in RADIUS does not require termination by an ASCII NUL because the Attribute already has a length field.

Some Radius clients and servers put nulls in where they are not supposed to. This Radius server tries to do the right thing in either case, but may sometimes decide the null should be treated as data rather than be discarded. In most cases, it will turn up in logs but not actually affect operation. If it does affect operation, either complain to the other vendor, or talk to me about the specific situation and I may provide a workaround.


Bruce Munro <>
Andrew Edwards <>
Darren Kruse <>