CNIT 107, Homework #7 -- April 24, 2004 -- Dan Keller

Installing and Operating a RADIUS Server


Whenever access to a resource must be regulated, there must be a regulation mechanism. A RADIUS server is a mechanism for regulating access to a computer network by users (customers, usually.) It makes sure that they are authorized. Specifically, the public wireless (WiFi) networks I am installing in some McDonalds restaurants include a RADIUS server. Not anyone can use these networks, only those customers to whom McDonalds has given a password. The RADIUS server checks the passwords entered by the users and grants or denies access as appropriate. It also keeps a record of network usage so that the restaurants' management can see when and how much their networks are being used.

In this paper, I describe what a RADIUS server does, the steps I followed in setting it up, how I used the server once it was in place, and some projects for making RADIUS useful in a business context.


The service called RADIUS (Remote Access Dial-In User Service) consists of computer user authentication, authorization, and accounting. In this context, here are definitions of these key terms.

Authentication is the process of determining the identity of a user. The most common form of authentication is by user name and password. This is the form used here. Other forms use digital certificates, digital signatures, etc.

Authorization is the process of determining which service(s) a user is permitted to use and to what extent. It requires that the identity of the user be previously established by some authentication process. The authenticated user ID is then authorized by lookup in a file, table, database, or directory service such as LDAP.

Accounting is the process of keeping track of network usage. It records the date and time of the start of each user's session, its duration and the number of bytes transferred.

These are the fundamental elements of the RADIUS service. Additional terminology is defined in my glossary of WiFi terms (

The RADIUS Service

In my RADIUS service, authentication and authorization are done by lookup in a MySQL database, and accounting is done by recording usage information there.

The sequence of events in the lifecycle of a RADIUS-mediated WiFi connection is:

  1. An administrator provides commands to the RADIUS server to cause it to store in its database the name and password of a user.
  2. A user with a laptop connects wirelessly to the access point and requests something such as a web page, a file transfer from a remote host, a connection to a POP (email) server, etc.
  3. The access point challenges the laptop user for an ID and a password.
  4. The access point contacts the RADIUS server across the Internet and asks it to authenticate the user.
  5. The RADIUS finds the user and password in its database, bestows its blessing, and logs the start of a new session.
  6. The access point proceeds to grant the laptop user the services he or she requests.
  7. When the user session terminates (whether or not by the user's choice) the access point informs the RADIUS server which logs the end of the session.

The RADIUS Protocol

RADIUS (Remote Access Dial-In User Service) is actually a protocol not a program, an interface not an implementation. That is, it is the definition of a standardized "conversation" for the purposes described above. One side of the conversation is the server; the other is the client.

There are several implementations of the server side of the RADIUS protocol, including:

On the client side of the protocol are a variety of devices called network access servers (NAS). A NAS is a piece of equipment that directly accepts users' connections. For example, in a wireless network the access point (the transmitter/receiver to which the customers connect from their laptops as they eat their burgers) serves as the NAS. In an ISP's dialup network, the NAS is the switch that connects the receiving modems to the computers providing the dialup services (e.g. e-mail and web browsing.)

RADIUS is a standardized protocol. As with other Internet-related protocols, the standard is established by the Internet Engineering Task Force (IETF) and documented in a document termed a Request for Comments (RFC). Specifically, RADIUS is documented in:

With regard to the RADIUS protocol, these documents are the ultimate authority.

One essential detail of the RADIUS specification is that it uses port 1812. Port numbers are part of the TCP/IP mechanism for connecting clients and servers on the Internet. Unless the default is overridden, the FreeRadius server gets the port number by lookup in the /etc/services file, the standard place in Unix (and Linux, Solaris, etc.) where port numbers are kept.


The components -- software and hardware -- that comprise my installation are:

Installation Procedure

  1. Get the freeradius tarball from:
  2. Copy it to the server:
    C:\> ftp
  3. Uncompress it:
    # gunzip freeradius-0.9.3.tar.gz
  4. Build the makefiles:
    # ./configure
  5. Compile the binaries:
    # make
  6. Install the binaries, the 'man' pages, and the configuration files:
    # make install

  7. Run the server in debug mode:
    # /usr/local/sbin/radiusd -X
    This mode yields voluminous output -- see Appendix 2. It shows where logs and libraries are kept, whether there were any errors parsing the configuration files, etc.

  8. Kill the server:
    kill -9 `ps -A | grep radiusd | gawk '{ print $1 }'`

  9. Run the server in production mode:
    # /usr/local/sbin/radiusd
    Sat Apr 24 21:32:52 2004 : Info: Starting - reading configuration files ...

  10. Confirm that it's working (it is!):
      # radtest test test localhost 0 testing123
      Sending Access-Request of id 138 to
           User-Name = "test"
           User-Password = "test"
           NAS-IP-Address =
           NAS-Port = 0
      Re-sending Access-Request of id 138 to
           User-Name = "test"
           User-Password = " \276\373\034X\352V\203\363\316\020\3066\021\211\352"
           NAS-IP-Address =
           NAS-Port = 0
      rad_recv: Access-Reject packet from host, id=138, length=20
    It doesn't matter whether the authentication request is accepted or rejected, what matters is that the server received the request and responded to it.

  11. Edit /usr/local/etc/raddb/clients.conf -- add the following entry:
      client {
             secret      = laraine
             shortname   =

  12. Restart the server (so it reads the modified clients.conf file)

  13. Verify the configuration with a RADIUS testing tool (a client simulator) such as NTRadPing from MasterSoft ( Download and run this tool.

  14. Configure the DWL-900AP+ access point to use the new RADIUS server (via the access point's browser-based administrative interface):

    Enabled Disabled
    Encryption Key

    Length 64 bits 128 bits 256 bits (AirPlus only)

    RADIUS Server 1

    Shared Secret

    RADIUS Server 2

    Shared Secret

    Values to enter into the form:

  15. The access point should challenge me for a user ID and a password when I attempt to connect, but it doesn't. The form containing these fields is not built-in to the access point. I must configure the RADIUS server (how? need more time...) to tell the access point to direct users to the URL of a web page with a form with fields for user ID and password. I have constructed this web page at

    WiFi-Italia Login Screen
    Nome Utente Esempio:
    Parola Chiave

    Servizio Internet ad alta velocitą fornito da WiFi-Italia

    We are your gateway to the high-speed on-line world of information, entertainment, education and enhanced work productivity.

    By signing on to our service, you are acknowledging that you have read our Terms of Use Policy and that you agree to abide by it.

    McDonald's is pleased to provide to you the opportunity to use wireless internet access service operated by Wifi-Italia. McDonald's does not own, control or operate Wifi-Italia's service and is not responsible for its policies or practices. You should carefully review Wifi-Italia's policies and agreements before using the site.

    Users of Wifi-Italia's services agree to comply with Wifi-Italia's Terms of Use Policy.

  16. With my laptop I can no longer connect wirelessly to the the administrative interface of the DWL-900AP+ access point. (I am able to connect to it via the wired Ethernet LAN.) I interpret this to mean that 802.1X authentication is now running on the access point. However, no entries appear in the server's RADIUS log. It appears that the access point is not yet contacting the RADIUS server. This could be due to a firewall on the server blocking port 1812, or any of several other issues. More time is needed for a diagnosis.

  17. Another approach is to use an ACL in the RADIUS. To do this , I would add the MAC address of the laptop -- 00-90-96-78-16-8D -- to the ACL in the RADIUS.

  18. The next step will be to find and install a RADIUS client program on the server. From my reading, I have seen that such a program exists somewhere. This program will enable me to communicate with the RADIUS via a command-line user interface.

Conclusion: All these things will be done. More time is needed.

What's Next?

A RADIUS server is just one of several elements required for a viable wireless network business model. In the rudimentary form described here, it is inadequate for production use. Toward that end, many follow-on projects suggest themselves, including:


Wifi networking technology is gaining acceptance in both consumer and commercial applications with spectacular rapidity. Business models for deploying and operating these networks are still very much in flux; it is not yet clear who (apart from the equipment manufacturers) will make money from them and how. Nonetheless, any shared usage model will certainly require carefully regulated access. RADIUS is a popular and mature mechanism for this purpose. It seems likely that this popularity will continue to grow and ancillary tools such as those described above -- all of which are already nascent -- will quickly become polished and widespread, cementing RADIUS in its place as the foundation for an essential and long-lived technology.


Appendix 1: The radiusd man page

RADIUSD(8)              FreeRADIUS Daemon              RADIUSD(8)

       radiusd  -  Authentication,  Authorization  and Accounting

       radiusd [-A] [-S] [-a accounting_directory] [-b] [-c]  [-d
       config_directory]  [-f] [-i ip-address] [-l log_directory]
       [-g facility] [-p port] [-s] [-v] [-x] [-X] [-y] [-z]

       This is the FreeRADIUS implementation of  the  well  known
       radius  server  program.   Even  though  this  program  is
       largely compatible with Livingston's radius  version  2.0,
       it's not based on any part of that code.

       RADIUS is a protocol spoken between an access server, typ­
       ically a device connected to several modems or ISDN lines,
       and  a  radius  server. When a user connects to the access
       server, (s)he is asked for a  loginname  and  a  password.
       This  information  is  then sent to the radius server. The
       server replies with "access denied", or  "access  OK".  In
       the  latter  case login information is sent along, such as
       the IP address in the case of a PPP connection.

       The access server also sends login and logout  records  to
       the radius server so accounting can be done. These records
       are kept for each terminal server  seperately  in  a  file
       called   detail,   and  in  the  wtmp  compatible  logfile

       -A     Write a file detail.auth in addition to  the  stan­
              dard  detail  file in the same directory. This file
              will   contain   all   the   authentication-request
              records.  This can be useful for debugging, but not
              for normal operation.

       -S     Write the stripped  usernames  (without  prefix  or
              suffix)  in  the  detail  file  instead  of the raw
              record as received from the terminal server.

              This command line option is  deprecated.   See  the
              log_stripped_names   configuration   item   in  the
              radiusd.conf file.

       -a accounting directory
              This defaults to /var/log/radacct. If  that  direc­
              tory exists, radiusd will write an ascii accounting
              record into a detail file  for  every  login/logout
              recorded.  The  location  of  the  detail  file  is

              This command line option is  deprecated.   See  the
              radacctdir  configuration  item in the radiusd.conf

       -l logging directory
              This defaults to /var/log. Radiusd writes a logfile
              here  called  radius.log. It contains informational
              and error messages,  and  optionally  a  record  of
              every login attempt (for aiding an ISP's helpdesk).
              The special arguments stdout and stderr  cause  the
              information  to get written to the standard output,
              or standard error  instead.  The  special  argument
              syslog sends the information with syslog(3).

              This  command  line  option is deprecated.  See the
              log_dir  configuration  item  in  the  radiusd.conf

       -g facility
              Specifies  the  syslog  facility to be used with -l
              syslog.  Default  is  daemon.  Another   reasonable
              choice would be authpriv.

       -d config directory
              Defaults  to /etc/raddb. Radiusd looks here for its
              configuration files such as the dictionary and  the
              users files.

       -i ip-address
              Defines  which IP addres to bind to for sending and
              receiving packets- useful for multi-homed hosts.

              This command line option is  deprecated.   See  the
              bind_address configuration item in the radiusd.conf

       -b     If the radius server binary was compiled  with  dbm
              support,  this  flag  tells  it to actually use the
              database files instead of the flat users file.

              This command line option is  deprecated,  and  does
              not do anything.

       -c     This  is  still an experimental feature.  Cache the
              password, group and shadow files in a hash-table in
              memory.   This  makes  the radius process use a bit
              more memory, but username lookups in  the  password
              file are much faster.

              After  every change in the real password file (user
              added, password changed) you need to send a  SIGHUP
              to the radius server to let it re-read its configu­
              ration and the password/group/shadow files !

              This command line option is  deprecated.   See  the
              cache configuration item for the unix module in the
              radiusd.conf file.

       -f     Do not fork, stay running as a foreground  process.

       -p port
              Normally  radiusd listens on the ports specified in
              /etc/services  (radius  and  radacct).  With   this
              option  radiusd  listens  on the specified port for
              authentication requests and on the  specified  port
              +1 for accounting requests.

              This  command  line  option is deprecated.  See the
              port configuration item in the radiusd.conf file.

       -s     Normally, the server forks a seperate  process  for
              accounting,   and  a  seperate  process  for  every
              authentication request. With this flag  the  server
              will  not do that. It won't even "daemonize" (auto-
              background) itself.

       -x     Debug mode. In this  mode  the  server  will  print
              details  of  every  request  on it's stderr output.
              Most useful in combination with -s.  You can  spec­
              ify this option 2 times (-x -x or -xx) to get a bit
              more debugging output.

       -X     Extended debug mode.  Equivalent to -sfxx, but sim­
              pler to explain.

       -y     Write details about every authentication request in
              the radius.log file.

              This command line option is  deprecated.   See  the
              log_auth  configuration  item  in  the radiusd.conf

       -z     Include the password in the  radius.log  file  even
              for successful logins. This is very insecure!.

              This  command  line  option is deprecated.  See the
              log_auth_badpass and the log_auth_goodpass configu­
              ration items in the radiusd.conf file.

       Radiusd  uses  a  number of configuration files. Each file
       has it's own manpage describing the format  of  the  file.
       These files are:

              The  main configuration file, which sets the admin­
              istrator-controlled items.

              This file is usually static.  It  defines  all  the
              possible  RADIUS  attributes used in the other con­
              figuration files.  You don't have to modify it.  It
              includes  other dictionary files in the same direc­

              [ Deprecated ] Contains the IP address and a secret
              key  for  every client that wants to connect to the

              Contains an entry for  every  NAS  (Network  Access
              Server)  in  the network. This is not the same as a
              client, especially if you have radius proxy  server
              in  your network. In that case, the proxy server is
              the client and  it  sends  requests  for  different

              It also contains a abbreviated name for each termi­
              nal server, used to create the directory name where
              the  detail  file  is  written,  and  used  for the
              /var/log/radwtmp file. Finally it also defines what
              type  of NAS (Cisco, Livingston, Portslave) the NAS

       hints  Defines certain hints to the radius server based on
              the  users's  loginname or other attributes sent by
              the access server. It  also  provides  for  mapping
              user  names  (such  as Pusername -> username). This
              provides the functionality that the Livingston  2.0
              server  has as "Prefix" and "Suffix" support in the
              users file, but is more general. Ofcourse the  Liv­
              ingston  way of doing things is also supported, and
              you can even use both at the same time (within cer­
              tain limits).

              Defines  the huntgroups that you have, and makes it
              possible to restrict access to  certain  huntgroups
              to certain (groups of) users.

       users  Here  the  users  are  defined. On a typical setup,
              this file mainly contains DEFAULT entries  to  pro­
              cess  the different types of logins, based on hints
              from the hints file. Authentication is  then  based
              on  the contents of the UNIX /etc/passwd file. How­
              ever it is also possible to define all  users,  and
              their passwords, in this file.

       radiusd.conf(5),    users(5),   huntgroups(5),   hints(5),
       clients(5), dictionary(5).

       Miquel van Smoorenburg,, and others.

                           23 June 2003                RADIUSD(8)

Appendix 2: The radiusd debug mode startup messages

Starting - reading configuration files ...
reread_config:  reading radiusd.conf
Config:   including file: /usr/local/etc/raddb/proxy.conf
Config:   including file: /usr/local/etc/raddb/clients.conf
Config:   including file: /usr/local/etc/raddb/snmp.conf
Config:   including file: /usr/local/etc/raddb/sql.conf
main: prefix = "/usr/local"
main: localstatedir = "/usr/local/var"
main: logdir = "/usr/local/var/log/radius"
main: libdir = "/usr/local/lib"
main: radacctdir = "/usr/local/var/log/radius/radacct"
main: hostname_lookups = no
main: snmp = no
main: max_request_time = 30
main: cleanup_delay = 5
main: max_requests = 1024
main: delete_blocked_requests = 0
main: port = 0
main: allow_core_dumps = no
main: log_stripped_names = no
main: log_file = "/usr/local/var/log/radius/radius.log"
main: log_auth = no
main: log_auth_badpass = no
main: log_auth_goodpass = no
main: pidfile = "/usr/local/var/run/radiusd/"
main: user = "(null)"
main: group = "(null)"
main: usercollide = no
main: lower_user = "no"
main: lower_pass = "no"
main: nospace_user = "no"
main: nospace_pass = "no"
main: checkrad = "/usr/local/sbin/checkrad"
main: proxy_requests = yes
proxy: retry_delay = 5
proxy: retry_count = 3
proxy: synchronous = no
proxy: default_fallback = yes
proxy: dead_time = 120
proxy: post_proxy_authorize = yes
proxy: wake_all_if_all_dead = no
security: max_attributes = 200
security: reject_delay = 1
security: status_server = no
main: debug_level = 0
read_config_files:  reading dictionary
read_config_files:  reading naslist
Using deprecated naslist file.  Support for this will go away soon.
read_config_files:  reading clients
Using deprecated clients file.  Support for this will go away soon.
read_config_files:  reading realms
Using deprecated realms file.  Support for this will go away soon.
radiusd:  entering modules setup
Module: Library search path is /usr/local/lib
Module: Loaded expr
Module: Instantiated expr (expr)
Module: Loaded PAP
pap: encryption_scheme = "crypt"
Module: Instantiated pap (pap)
Module: Loaded CHAP
Module: Instantiated chap (chap)
Module: Loaded MS-CHAP
mschap: use_mppe = yes
mschap: require_encryption = no
mschap: require_strong = no
mschap: passwd = "(null)"
mschap: authtype = "MS-CHAP"
Module: Instantiated mschap (mschap)
Module: Loaded System
unix: cache = no
unix: passwd = "(null)"
unix: shadow = "(null)"
unix: group = "(null)"
unix: radwtmp = "/usr/local/var/log/radius/radwtmp"
unix: usegroup = no
unix: cache_reload = 600
Module: Instantiated unix (unix)
Module: Loaded eap
eap: default_eap_type = "md5"
eap: timer_expire = 60
rlm_eap: Loaded and initialized the type md5
rlm_eap: Loaded and initialized the type leap
Module: Instantiated eap (eap)
Module: Loaded preprocess
preprocess: huntgroups = "/usr/local/etc/raddb/huntgroups"
preprocess: hints = "/usr/local/etc/raddb/hints"
preprocess: with_ascend_hack = no
preprocess: ascend_channels_per_line = 23
preprocess: with_ntdomain_hack = no
preprocess: with_specialix_jetstream_hack = no
preprocess: with_cisco_vsa_hack = no
Module: Instantiated preprocess (preprocess)
Module: Loaded realm
realm: format = "suffix"
realm: delimiter = "@"
Module: Instantiated realm (suffix)
Module: Loaded files
files: usersfile = "/usr/local/etc/raddb/users"
files: acctusersfile = "/usr/local/etc/raddb/acct_users"
files: preproxy_usersfile = "/usr/local/etc/raddb/preproxy_users"
files: compat = "no"
Module: Instantiated files (files)
Module: Loaded Acct-Unique-Session-Id
acct_unique: key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port-Id"
Module: Instantiated acct_unique (acct_unique)
Module: Loaded detail
detail: detailfile = "/usr/local/var/log/radius/radacct/%{Client-IP-Address}/detail-%Y%m%d"
detail: detailperm = 384
detail: dirperm = 493
detail: locking = no
Module: Instantiated detail (detail)
Module: Loaded radutmp
radutmp: filename = "/usr/local/var/log/radius/radutmp"
radutmp: username = "%{User-Name}"
radutmp: case_sensitive = yes
radutmp: check_with_nas = yes
radutmp: perm = 384
radutmp: callerid = yes
Module: Instantiated radutmp (radutmp)
Listening on IP address *, ports 1812/udp and 1813/udp, with proxy on 1814/udp.
Ready to process requests.