FreeRADIUS InkBridge

Startup text

We start the server with -X. This option gives us the best combination of useful output, and readable output. Adding more -x gives more complex output, not more useful output.

$ radiusd -X 2>&1 | tee debugfile

The server prints out the version number, copyright, and license information:

Copyright 1999-2026 The FreeRADIUS server project and contributors
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE
You may redistribute copies of FreeRADIUS under the terms of the
GNU General Public License
For more information about these matters, see the file named COPYRIGHT

Next, it prints out messages relating to debuggers (e.g. gdb). These messages are intended for developers, and can generally be ignored by everyone else.

Getting debug state failed: ptrace capability not set.  If debugger detection is required run as root or: setcap cap_sys_ptrace+ep <path_to_binary>

Read the configuration files

The next block of messages is about the configuration files. The server prints out the name of each configuration file it loads.

This output lets you check that the server is loading the files which you think it’s loading. One common issue is that people install multiple versions of the server, and then edit one file while the server is loading a different one. Reading the debug output will let you verify that you’re editing the right file.

Starting - reading configuration files ...

It first loads the main radiusd.conf file, and some associated ones like clients.conf.

including configuration file /etc/freeradius/radiusd.conf
Including files in directory "/etc/freeradius/template.d/"
including configuration file /etc/freeradius/template.d/default
including configuration file /etc/freeradius/clients.conf
Including files in directory "/etc/freeradius/global.d/"
including configuration file /etc/freeradius/global.d/ldap
including configuration file /etc/freeradius/global.d/python

It now loads the configuration for all of the modules. These is usually stored in mods-enabled/, with one module configuration per file in that directory.

Sometimes the module you’re using does not seem to be loaded or used. In that case, you should check this section to see that the file is loaded.

Including files in directory "/etc/freeradius/mods-enabled/"
including configuration file /etc/freeradius/mods-enabled/always
including configuration file /etc/freeradius/mods-enabled/attr_filter
including configuration file /etc/freeradius/mods-enabled/cache_eap
More
including configuration file /etc/freeradius/mods-enabled/chap
including configuration file /etc/freeradius/mods-enabled/client
including configuration file /etc/freeradius/mods-enabled/delay
including configuration file /etc/freeradius/mods-enabled/detail
including configuration file /etc/freeradius/mods-enabled/detail.log
including configuration file /etc/freeradius/mods-enabled/digest
including configuration file /etc/freeradius/mods-enabled/eap
including configuration file /etc/freeradius/mods-enabled/eap_inner
including configuration file /etc/freeradius/mods-enabled/echo
including configuration file /etc/freeradius/mods-enabled/exec
including configuration file /etc/freeradius/mods-enabled/files
including configuration file /etc/freeradius/mods-enabled/linelog
including configuration file /etc/freeradius/mods-enabled/mschap
including configuration file /etc/freeradius/mods-enabled/ntlm_auth
including configuration file /etc/freeradius/mods-enabled/pam
including configuration file /etc/freeradius/mods-enabled/pap
including configuration file /etc/freeradius/mods-enabled/passwd
including configuration file /etc/freeradius/mods-enabled/stats
including configuration file /etc/freeradius/mods-enabled/unix
including configuration file /etc/freeradius/mods-enabled/unpack
including configuration file /etc/freeradius/mods-enabled/utf8

Some policies are loaded next. These policies are ones which the server uses (for example) to canonicalize user names, and to do things like attribute re-writes, sanity checks, etc.

Including files in directory "/etc/freeradius/policy.d/"
including configuration file /etc/freeradius/policy.d/accounting
including configuration file /etc/freeradius/policy.d/canonicalisation
More
including configuration file /etc/freeradius/policy.d/control
including configuration file /etc/freeradius/policy.d/cui
including configuration file /etc/freeradius/policy.d/debug
including configuration file /etc/freeradius/policy.d/dhcp
including configuration file /etc/freeradius/policy.d/eap
including configuration file /etc/freeradius/policy.d/filter
including configuration file /etc/freeradius/policy.d/operator-name
including configuration file /etc/freeradius/policy.d/time
including configuration file /etc/freeradius/policy.d/vendor

Virtual Server configuration

The server now reads the virtual server configuration.

Including files in directory "/etc/freeradius/sites-enabled/"
including configuration file /etc/freeradius/sites-enabled/default
Loaded module process_radius
including configuration file /etc/freeradius/sites-enabled/inner-tunnel
including configuration file /etc/freeradius/sites-enabled/proxy
Parsing initial logging configuration.

Once all of the configuration files are loaded, the server prints out the configuration it is parsing. Note that it only prints out what it is using. I.e. you can put foo = bar into radiusd.conf, and the server will load it, but will not print it out in the debug output.

The result is that if you set a configuration item, it will be printed out in the debug output. You should verify that this is the case, especially if it looks like the server is not using the setting you edited. If the configuration item does not appear in the debug output, then the server is not using it.

To begin with, logging and security configuration is read:

Parsing initial logging configuration.
main {
  prefix = /usr
  log {
    destination = file
    syslog_facility = daemon
    local_state_dir = "/usr/var"
More
    logdir = "/usr/var/log"
    file = /var/log/freeradius/radius.log
    suppress_secrets = yes
  }
}
Parsing security rules to bootstrap UID / GID / etc.
main {
  log {
  }
  security {
    user = freerad
    group = freerad
    allow_core_dumps = yes
    openssl_fips_mode = no
    limit {
      files {
        allow = /var/log/freeradius
        allow = /var/log/freeradius/radacct
      }
      exec {
        allow = "/bin"
        allow = "/usr/bin"
      }
    }
  }
  name = freeradius
  local_state_dir = "/usr/var"
  run_dir = /var/run/freeradius
}
Core dumps are enabled

Virtual Servers

Then virtual servers commence being set up. Some protocol modules are loaded as they are needed by the configuration.

Parsing main configuration
main {
  server default {
    namespace = radius
    radius {
      Access-Request {
        session {
          timeout = 15
More
          max = 4096
          max_rounds = 50
        }
      }
    }
Loaded module proto_radius
    listen authentication {
      type = Access-Request
      type = Status-Server
      transport = udp
Loaded module proto_radius_udp
      udp {
        ipaddr = *
        port = 1812
        networks {
          allow = 127/8
          allow = 192.0.2/24
        }
        max_packet_size = 4096
        max_attributes = 255
      }
      limit {
        cleanup_delay = 5.0
        idle_timeout = 60.0
        dynamic_timeout = 600.0
        nak_lifetime = 30.0
        max_connections = 256
        max_clients = 256
        max_pending_packets = 256
      }
      priority {
        Access-Request = high
        Accounting-Request = low
        CoA-Request = normal
        Disconnect-Request = low
        Status-Server = now
      }
      log {
        ignored_clients = yes
      }
      require_message_authenticator = auto
      limit_proxy_state = auto
    }
    listen authentication {
      type = Access-Request
      type = Status-Server
      transport = tcp
Loaded module proto_radius_tcp
      tcp {
        ipaddr = *
        port = 1812
        networks {
          allow = 127/8
          allow = 192.0.2/24
        }
        max_packet_size = 4096
        max_attributes = 255
      }
      limit {
        cleanup_delay = 5.0
        idle_timeout = 30.0
        dynamic_timeout = 600.0
        nak_lifetime = 30.0
        max_connections = 1024
        max_clients = 256
        max_pending_packets = 256
      }
      priority {
        Access-Request = high
        Accounting-Request = low
        CoA-Request = normal
        Disconnect-Request = low
        Status-Server = now
      }
      log {
        ignored_clients = yes
      }
      require_message_authenticator = no
      limit_proxy_state = auto
    }
    listen accounting {
      type = Accounting-Request
      transport = udp
      udp {
        ipaddr = *
        port = 1813
        networks {
        }
        max_packet_size = 4096
        max_attributes = 255
      }
      limit {
        cleanup_delay = 5.0
        idle_timeout = 30.0
        dynamic_timeout = 600.0
        nak_lifetime = 30.0
        max_connections = 1024
        max_clients = 256
        max_pending_packets = 256
      }
      priority {
        Access-Request = high
        Accounting-Request = low
        CoA-Request = normal
        Disconnect-Request = low
        Status-Server = now
      }
      log {
        ignored_clients = yes
      }
      require_message_authenticator = no
      limit_proxy_state = auto
    }
  }

The default configuration includes the inner-tunnel virtual server for EAP protocols.

  server inner-tunnel {
    namespace = radius
    radius {
      Access-Request {
More
      session {
        timeout = 15
        max = 4096
        max_rounds = 50
      }
    }
  }
  listen innertunnel {
    type = Access-Request
    transport = udp
    udp {
      ipaddr = 127.0.0.1
      port = 18120
      networks {
      }
      max_packet_size = 4096
      max_attributes = 255
    }
    limit {
      cleanup_delay = 5.0
      idle_timeout = 30.0
      dynamic_timeout = 600.0
      nak_lifetime = 30.0
      max_connections = 1024
      max_clients = 256
      max_pending_packets = 256
    }
    priority {
      Access-Request = high
      Accounting-Request = low
      CoA-Request = normal
      Disconnect-Request = low
      Status-Server = now
    }
    log {
      ignored_clients = yes
    }
    require_message_authenticator = no
    limit_proxy_state = auto
  }
}
server proxy {
  namespace = radius
  radius {
    Access-Request {
      session {
        timeout = 15
        max = 4096
        max_rounds = 50
      }
    }
  }
}

After the virtual servers we have the "main" server configuration, which includes the directories that the server is using, as well as other generic configuration settings that don’t belong anywhere else.

  log {
    colourise = yes
  }
  security {
    limit {
      files {
      }
      exec {
      }
    }
  }
  sbin_dir = "/usr/sbin"
  logdir = /var/log/freeradius
  radacctdir = /var/log/freeradius/radacct
  reverse_lookups = no
More
  hostname_lookups = yes
  pidfile = /var/run/freeradius/freeradius.pid
  debug_level = 0
  request {
    max = 16384
    timeout = 30
    reuse {
      min = 10
      max = 100
      cleanup_interval = 30s
    }
  }
  resources {
  }
  thread pool {
    num_networks = 1
Dynamically determined thread.workers = 7
    num_workers = 7
    openssl_async_pool_init = 64
    openssl_async_pool_max = 1024
  }
  migrate {
  }
  interpret {
  }
}
Switching to configured log settings
  log debug {
    destination = null
    timestamp = yes
    colourise = no
  }

Clients

The individual RADIUS client definitions are now loaded.

freeradius: #### Loading Clients ####
  client localhost {
    ipaddr = 127.0.0.1
    secret = <<< secret >>>
    require_message_authenticator = auto
    limit_proxy_state = auto
    proto = *
    limit {
      max_connections = 16
      lifetime = 0
      idle_timeout = 30
    }
  }
More
client localhost_ipv6 {
  ipv6addr = ::1
  secret = <<< secret >>>
  require_message_authenticator = no
  limit_proxy_state = auto
  limit {
    max_connections = 16
    lifetime = 0
    idle_timeout = 30s
  }
}

Auth-Type

The server then creates Auth-Type, as set in the virtual servers. These Auth-Type names and values are used by the modules, so they need to be created now.

#### Instantiating libraries ####
#### Bootstrapping process modules ####
Bootstrapping process_radius "default"
Creating Auth-Type = pap
Creating Auth-Type = chap
Creating Auth-Type = mschap
More
Creating Auth-Type = digest
Creating Auth-Type = ldap
Creating Auth-Type = eap
Bootstrapping process_radius "inner-tunnel"
Bootstrapping process_radius "proxy"
Creating Auth-Type = proxy

Modules

The server now reads the module configuration files from mods-enabled. This causes it to load the dynamic library which reads that configuration, which in turn parses the configuration to determine what to do with it.

Each module will print out it’s configuration, along with any errors or warnings it sees when it is loading itself.

#### Bootstrapping protocol modules ####
#### Instantiating libraries ####
#### Bootstrapping static modules ####
 modules {
    static {

Here it loads the pap module. There are multiple lines being printed at each stage of the process.

First, it discovers it has to load the pap module, and decides to do that. The configuration file location is shown at the top of the output, seen above.

Loaded module rlm_pap

Second, it tells you the configuration that is used by the pap module.

 pap {
   normalise = yes
 }

When you are editing a module configuration, it is good to check the debug output for that module, to see:

  • Was the module loaded?

  • Is it using the file you edited?

  • Are the configuration changes you made showing up in the debug output?

Some modules like digest do not have any configuration items, and therefore don’t print out any configuration when they are loaded.

Loaded module rlm_digest

The rlm_files module loads the users file (which these days is a symlink to mods-config/files/authorize).

Loaded module rlm_files
    files {
      filename = /etc/freeradius/mods-config/files/authorize
      lookup_type = auto
    }
    files files_accounting {
      filename = /etc/freeradius/mods-config/files/accounting
      lookup_type = auto
    }

The server loads a large number of modules, so we will omit them here.

Finally, it is done loading all modules, and calls the boostrapping procedure for each of them.

    } # static
#### Bootstrapping rlm modules ####
Bootstrapping rlm_cache "cache_eap"
Bootstrapping rlm_chap "chap"
Bootstrapping rlm_delay "delay"
Bootstrapping rlm_delay "delay_reject"
More
Bootstrapping rlm_always "disallow"
Bootstrapping rlm_exec "echo"
Bootstrapping rlm_exec "exec"
Bootstrapping rlm_always "fail"
Bootstrapping rlm_always "handled"
Bootstrapping rlm_always "invalid"
Bootstrapping rlm_linelog "linelog"
Bootstrapping rlm_linelog "log_accounting"
Bootstrapping rlm_linelog "log_auth_access_accept"
Bootstrapping rlm_linelog "log_auth_access_reject"
Bootstrapping rlm_linelog "log_auth_authentication_fail"
Bootstrapping rlm_linelog "log_auth_authentication_pass"
Bootstrapping rlm_mschap "mschap"
Bootstrapping rlm_always "noop"
Bootstrapping rlm_always "notfound"
Bootstrapping rlm_exec "ntlm_auth"
Bootstrapping rlm_always "ok"
Bootstrapping rlm_always "reject"
Bootstrapping rlm_unix "unix"
Bootstrapping rlm_always "updated"

It then reads the dictionaries. It does not print out the name of every dictionary file it reads, as there are over 100 files, but they are nevertheless still loaded.

Including dictionary file "/etc/freeradius/dictionary"

At this point, the server is well on it’s way to running. The server will now compile the unlang policies ready for use.

#### Instantiating listeners ####
Compiling policies in server default { ... }
Compiling policies in - recv Access-Request {...}
Reading file /etc/freeradius/mods-config/files/authorize
WARN  : /etc/freeradius/policy.d/time[13]: Skipping remaining instructions due to 'return'
WARN  : /etc/freeradius/policy.d/time[18]: Please use the 'filter' keyword for attribute filtering
Compiling policies in - send Access-Accept {...}
More
Compiling policies in - send Access-Challenge {...}
Compiling policies in - send Access-Reject {...}
Compiling policies in - recv Accounting-Request {...}
Reading file /etc/freeradius/mods-config/files/accounting
Compiling policies in - send Accounting-Response {...}
Compiling policies in - recv Status-Server {...}
Compiling policies in - authenticate pap {...}
Compiling policies in - authenticate chap {...}
Compiling policies in - authenticate mschap {...}
...
Compiling policies in - authenticate proxy {...}
Compiling policies in - finally  {...}

Initialising protocol modules and proxying

Process modules are initialised. This includes proto_radius, used for RADIUS proxying. (This replaces the previous proxy configuration from version 3.)

#### Instantiating process modules ####
Instantiating process_radius "default"
Instantiating process_radius "inner-tunnel"
Instantiating process_radius "proxy"
#### Instantiating protocol modules ####
Instantiating proto_radius ".accounting.udp"
Instantiating proto_radius_udp ".accounting.udp.udp"
    client localhost {
      ipaddr = 192.0.2.1
      secret = <<< secret >>>
More
      shortname = sample
      require_message_authenticator = no
      limit_proxy_state = auto
      limit {
        max_connections = 16
        lifetime = 0
        idle_timeout = 30s
      }
    }
Instantiating proto_radius ".authentication.tcp"
Instantiating proto_radius_tcp ".authentication.tcp.tcp"
Instantiating proto_radius ".authentication.udp"
Instantiating proto_radius_udp ".authentication.udp.udp"
Instantiating proto_radius ".innertunnel.udp"
Instantiating proto_radius_udp ".innertunnel.udp.udp"

Module instantiation

Dynamic modules may have one or more instance, for example rlm_linelog may be configured twice, each writing to a different log destination. All of these instances are now created and the configuration is shown.

#### Instantiating rlm modules ####
Instantiating rlm_attr_filter "attr_filter.access_challenge"
Reading file /etc/freeradius/mods-config/attr_filter/access_challenge
Instantiating rlm_attr_filter "attr_filter.access_reject"
Reading file /etc/freeradius/mods-config/attr_filter/access_reject
Instantiating rlm_attr_filter "attr_filter.accounting_response"
Reading file /etc/freeradius/mods-config/attr_filter/accounting_response
Instantiating rlm_attr_filter "attr_filter.post-proxy"
Reading file /etc/freeradius/mods-config/attr_filter/post-proxy
Instantiating rlm_attr_filter "attr_filter.pre-proxy"
Reading file /etc/freeradius/mods-config/attr_filter/pre-proxy
Instantiating rlm_detail "auth_log"
Instantiating rlm_cache "cache_eap"
...

Some modules have a fair amount of configuration, such as the EAP modules.

Instantiating rlm_eap_mschapv2 "eap.mschapv2"
Instantiating rlm_eap_peap "eap.peap"
      tls {
        chain rsa {
          format = pem
          certificate_file = /etc/freeradius/certs/rsa/server.pem
          private_key_password = <<< secret >>>
          private_key_file = /etc/freeradius/certs/rsa/server.key
          ca_file = /etc/freeradius/certs/rsa/ca.pem
More
          verify_mode = hard
          include_root_ca = no
        }
        verify_depth = 0
        ca_path = /etc/freeradius/certs
        ca_file = /etc/freeradius/certs/rsa/ca.pem
        fragment_size = 1024
        cipher_list = "DEFAULT"
        cipher_server_preference = yes
        allow_renegotiation = no
        ecdh_curve = prime256v1
        tls_min_version = 1.2
        session {
          mode = auto
WARN  : tls - A virtual_server must be provided for stateful caching. cache.mode = "auto" rewritten to cache.mode = "stateless"
          name = "%{EAP-Type}%interpreter('server')"
          lifetime = 1d
          require_extended_master_secret = yes
          require_perfect_forward_secrecy = no
        }
        verify {
          mode = all
          attribute_mode = client-and-issuer
        }
      }
Instantiating rlm_eap_pwd "eap.pwd"

Listen sections

After loading all of the configuration, it then opens the various network sockets used to read and write packets.

#### Opening listener interfaces ####
Listening on radius_udp server * port 1812 bound to virtual server default
Listening on radius_tcp server * port 1812 bound to virtual server default
Listening on radius_udp server * port 1813 bound to virtual server default
Listening on radius_udp server 127.0.0.1 port 18120 bound to virtual server inner-tunnel
post-suid-down capabilities: =

And we finally get to this line.

Ready to process requests

Once this has been printed, the debug output changes to packet processing.

Note that if nothing is ever printed after this line, then the server is not receiving any packets. No amount of changing the server configuration will solve that problem. Instead, you must fix the firewall, SELinux configuration, network routing, etc. so that the OS delivers RADIUS packets to the server.