### listen { ... }
+```
+listen {
+ ipaddr = *
+ port = 2083
+ type = auth
+ proto = tcp
+```
## tls { ... }
+```
+ tls {
+```
NOTE: Moonshot tends to distribute certs separate from keys.
+```
+ chain {
+ certificate_file = ${certdir}/server.pem
+ private_key_file = ${certdir}/server.key
+ private_key_password = whatever
+ }
+ ca_file = ${cadir}/ca.pem
+ dh_file = ${certdir}/dh
+ fragment_size = 8192
+ ca_path = ${cadir}
+ cipher_list = "DEFAULT"
+ cache {
+ enable = no
+ lifetime = 24 # hours
+ max_entries = 255
+ }
+ require_client_cert = yes
+ verify {
+ }
+ psk_query = %psksql("select hex(key) from psk_keys where keyid = '%{TLS-PSK-Identity}'")
+ }
+```
.Please see the `sites-availables/abfab-idp` file.
+```
+ virtual_server = abfab-idp
+```
.Reference to the next `clients {...}` section.
+```
+ clients = radsec-abfab
+}
+```
### clients { ... }
established via the trustrouter. In general additional client
stanzas are also required for local services.
+```
+clients radsec-abfab {
+```
.Allow all clients, but require TLS.
+```
+ client default {
+ ipaddr = 0.0.0.0/0
+ proto = tls
+ }
+```
.An example local service.
+```
+ client service_1 {
+```
ipaddr::
+```
+# ipaddr = 192.0.2.20
+```
gss_acceptor_host_name::
If set, the RADIUS server will confirm that all requests have this value for the
acceptor host name.
+```
+# gss_acceptor_host_name = "server.example.com"
+```
gss_acceptor_realm_name:: Foreign realms will typically reject a request
if this is not properly set.
+```
+# gss_acceptor_realm_name = "example.com"
+```
trust_router_coi:: Override the `default_community` in the realm module.
+```
+# trust_router_coi = "community1.example.net"
+```
IMPORTANT: In production deployments it is important to set up certificate
verification so that even if clients spoof IP addresses, one client cannot
impersonate another.
+```
+ }
+}
+```
== Default Configuration
```
-listen {
- ipaddr = *
- port = 2083
- type = auth
- proto = tcp
- tls {
- chain {
- certificate_file = ${certdir}/server.pem
- private_key_file = ${certdir}/server.key
- private_key_password = whatever
- }
- ca_file = ${cadir}/ca.pem
- dh_file = ${certdir}/dh
- fragment_size = 8192
- ca_path = ${cadir}
- cipher_list = "DEFAULT"
- cache {
- enable = no
- lifetime = 24 # hours
- max_entries = 255
- }
- require_client_cert = yes
- verify {
- }
- psk_query = %psksql("select hex(key) from psk_keys where keyid = '%{TLS-PSK-Identity}'")
- }
- virtual_server = abfab-idp
- clients = radsec-abfab
-}
-clients radsec-abfab {
- client default {
- ipaddr = 0.0.0.0/0
- proto = tls
- }
- client service_1 {
-# ipaddr = 192.0.2.20
-# gss_acceptor_host_name = "server.example.com"
-# gss_acceptor_realm_name = "example.com"
-# trust_router_coi = "community1.example.net"
- }
-}
```
## server { ... }
+```
+server abfab-idp {
+```
### recv Access-Request
Run these rules when receiving an `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]`
+```
+ recv Access-Request {
+```
.Please see the `policy.d/abfab-tr` for full documentation.
+```
+ abfab_psk_authorize
+ abfab_client_check
+```
.Please see the `policy.d/filter` for full documentation.
+```
+ filter_username
+```
If you intend to use CUI and you require that the `Operator-Name`
be set for CUI generation and you want to generate CUI also
For EAP requests.
+```
+ eap {
+ ok = return
+ }
+```
-.Please see the link:../../../../../../mods-available/expiration.adoc[mods-available/expiration] for full documentation.
+.Please see the xref:reference:raddb/mods-available/expiration.adoc[mods-available/expiration] for full documentation.
+```
+ expiration
+ }
+```
EAP authentication.
+```
+ authenticate eap {
+```
Allow EAP authentication.
+```
+ eap
+ }
+```
### send Access-Accept
Run these rules when sending an `link:https://freeradius.org/rfc/rfc2865.html#Access-Accept[Access-Accept]`
+```
+ send Access-Accept {
+```
For `EAP-TTLS` and `PEAP`, add the cached attributes to the reply.
The `session-state` attributes are automatically cached when
The `session-state` attributes are automatically deleted after
an `link:https://freeradius.org/rfc/rfc2865.html#Access-Reject[Access-Reject]` or `link:https://freeradius.org/rfc/rfc2865.html#Access-Accept[Access-Accept]` is sent.
+```
+ &reply += &session-state
+```
Create the `CUI` value and add the attribute to `link:https://freeradius.org/rfc/rfc2865.html#Access-Accept[Access-Accept]`.
Uncomment the line below if *returning* the CUI.
+```
+# cui
+```
If you want to have a log of authentication replies, uncomment the
following line, and enable the `detail reply_log` module.
+```
+# reply_log
+```
After authenticating the user, do another SQL query.
See "Authentication Logging Queries" in mods-available/sql
+```
+ -sql
+```
Instead of sending the query to the SQL server,
write it into a log file.
+```
+# sql_log
+```
Uncomment the following if you want to modify the user's object
in LDAP after a successful login.
+```
+# ldap
+```
.Please see the `exec` for full documentation.
+```
+ exec
+```
Remove reply message if the response contains an `link:https://freeradius.org/rfc/rfc2869.html#EAP-Message[EAP-Message]`.
.Please see the `policy.d/eap` for full documentation.
+```
+ remove_reply_message_if_eap
+ }
+```
### send Access-Reject
NOTE: if you have set `edir = yes` in the `ldap` module configuration,
please remember to add the ldap module name (or instance).
+```
+ send Access-Reject {
+```
.Log failed authentications in SQL, too.
+```
+ -sql
+```
.Please see the `attr_filter` for full documentation.
+```
+ attr_filter.access_reject
+```
NOTE: Insert `EAP-Failure` message if the request was rejected by policy instead of
because of an authentication failure And already has an `EAP` message For non-ABFAB,
we insert the failure all the time, but for ABFAB It's more desirable to preserve
`link:https://freeradius.org/rfc/rfc2865.html#Reply-Message[Reply-Message]` when we can.
+```
+ if (&reply.Eap-Message) {
+ eap
+ }
+```
.Remove reply message if the response contains an `link:https://freeradius.org/rfc/rfc2869.html#EAP-Message[EAP-Message]`.
-
-== Default Configuration
-
```
-server abfab-idp {
- recv Access-Request {
- abfab_psk_authorize
- abfab_client_check
- filter_username
- eap {
- ok = return
- }
- expiration
- }
- authenticate eap {
- eap
- }
- send Access-Accept {
- &reply += &session-state
-# cui
-# reply_log
- -sql
-# sql_log
-# ldap
- exec
- remove_reply_message_if_eap
- }
- send Access-Reject {
- -sql
- attr_filter.access_reject
- if (&reply.Eap-Message) {
- eap
- }
remove_reply_message_if_eap
}
}
```
+
+== Default Configuration
+
+```
+```
This is the `arp` virtual server.
+```
+server arp {
+```
namespace::
All of the "listen" sections in this virtual server will
only accept packets for that protocol.
+```
+ namespace = arp
+```
### The listen section
order to make FreeRADIUS more flexible, and to make the
configuration simpler and more consistent.
+```
+ listen {
+```
interface:: The name of the interface.
+```
+ interface = en0
+```
filter:: An optional PCAP filter.
`(arp[6] == 0) and (arp[7] == 1)`
+```
+# filter = "host 192.0.2.1"
+```
active:: Whether or not we response to ARP requests
When `active = no`, the virtual server will NEVER
send an ARP reply.
+```
+# active = no
+ }
+```
### Process an ARP request
+```
+recv Request {
+ ok
+}
+```
### Process an ARP reply before sending it
-
-== Default Configuration
-
```
-server arp {
- namespace = arp
- listen {
- interface = en0
-# filter = "host 192.0.2.1"
-# active = no
- }
-recv Request {
- ok
-}
send Reply {
ok
}
}
```
+
+== Default Configuration
+
+```
+```
The virtual server which manages BFD.
+```
+server main {
+```
namespace::
The Bidirectional Forwarding Detection (BFD) protocol.
+```
+ namespace = bfd
+```
Common configuration for the BFD state machine.
For now, unused.
+```
+ bfd {
+ }
+```
### listen { ... }
+```
+ listen {
+```
Only IP transport is supported for BFD.
There is no ethernet type for BFD.
+```
+ transport = udp
+```
+```
+ udp {
+```
ipaddr::
IP address, or IPv6 address as with other
+```
+ ipaddr = 192.0.2.1
+```
port:: Port as normal.
+```
+ port = 3784
+```
only_state_changes::
this value to "false" if you want every received and every sent packet to be
processed through this virtual server.
+```
+ only_state_changes = true
+ }
+ }
+```
peer:: BFD peer
The peer definition is based on the `client` definition. The standard client configuration items will work
here.
+```
+peer other {
+```
ipaddr:: address of the peer
+```
+ ipaddr = 192.0.2.2
+```
port:: the peers port where we send packets
+```
+ port = 3784
+```
src_ipaddr:: Source address used when sending packets to this peer.
If the source IP address does not match any listener, then the peer will be ignored.
+```
+# src_ipaddr = 192.0.2.1
+```
auth_type:: BFD Authentication method.
NOTE: The other side of the BFD connection has to have the same
kind of authentication set.
+```
+ auth_type = none
+```
secret:: The secret key used for authentication.
If it starts with "0x", then it is treated as a hex string. This is recommended
for security. The secrets should be no more than 16 octets long, and random.
+```
+# secret = "hello"
+```
min_transmit_interval:: Minimum time interval to transmit.
+```
+ min_transmit_interval = 250ms
+```
min_receive_interval:: Minimum time interval to receive.
+```
+ min_receive_interval = 250ms
+```
max_timeouts:: Max number of timeouts before the session is declared dead.
+```
+ max_timeouts = 3
+```
demand:: BFD Demand mode.
allowed values: {no, yes}
+```
+ demand = no
+}
+```
## Packet Processing sections
### Receive "Admin-Down" packets from the peer.
+```
+recv Admin-Down {
+ ok
+}
+```
### Receive "Down" packets from the peer.
+```
+recv Down {
+ ok
+}
+```
### Receive "Init" packets from the peer.
+```
+recv Init {
+ ok
+}
+```
### Receive "Up" packets from the peer.
+```
+recv Up {
+ ok
+}
+```
### Send "Admin-Down" packets to the peer.
+```
+send Admin-Down {
+ ok
+}
+```
### Send "Down" packets to the peer.
+```
+send Down {
+ ok
+}
+```
### Send "Init" packets to the peer.
+```
+send Init {
+ ok
+}
+```
### Send "Up" packets to the peer.
+```
+send Up {
+# octets more-data
+ ok
+```
Sneak in more data after a BFD packet!
-
-
-== Default Configuration
-
```
-server main {
- namespace = bfd
- bfd {
- }
- listen {
- transport = udp
- udp {
- ipaddr = 192.0.2.1
- port = 3784
- only_state_changes = true
- }
- }
-peer other {
- ipaddr = 192.0.2.2
- port = 3784
-# src_ipaddr = 192.0.2.1
- auth_type = none
-# secret = "hello"
- min_transmit_interval = 250ms
- min_receive_interval = 250ms
- max_timeouts = 3
- demand = no
-}
-recv Admin-Down {
- ok
-}
-recv Down {
- ok
-}
-recv Init {
- ok
-}
-recv Up {
- ok
-}
-send Admin-Down {
- ok
-}
-send Down {
- ok
-}
-send Init {
- ok
-}
-send Up {
-# octets more-data
- ok
# &reply.Additional-Data := {
# &more-data := 0xabcdef
# }
}
+
}
```
+
+== Default Configuration
+
+```
+```
### server bfd { ... }
+```
+server other {
+ namespace = bfd
+```
Common configuration for the BFD state machine.
+```
+ bfd {
+ }
+```
#### listen { ... }
+```
+ listen {
+ transport = udp
+ udp {
+```
ipaddr: IP address, or IPv6 address as normal.
+```
+ ipaddr = ${bfd_other}
+```
port:: Port as normal.
+```
+ port = 3784
+ only_state_changes = true
+ }
+ }
+peer main {
+ ipaddr = ${bfd_main}
+ port = 3784
+```
auth_type:: BFD Authentication method.
NOTE: The other side of the BFD connection has to have the same
kind of authentication set.
+```
+ auth_type = ${bfd_auth_type}
+```
secret:: The secret key used for authentication.
If it starts with "0x", then it is treated as a hex string. This is recommended
for security. The secrets should be `~16` octets long, and random.
+```
+ secret = "hello"
+```
min_transmit_interval:: Minimum time interval to transmit.
+```
+ min_transmit_interval = 250ms
+```
min_receive_interval:: Minimum time interval to receive.
+```
+ min_receive_interval = 250ms
+```
max_timeouts:: Max number of timeouts before the session is declared dead.
+```
+ max_timeouts = 3
+```
demand:: BFD Demand mode.
allowed values: {no, yes}
-
-
-
-
-
-
-== Default Configuration
-
```
-server other {
- namespace = bfd
- bfd {
- }
- listen {
- transport = udp
- udp {
- ipaddr = ${bfd_other}
- port = 3784
- only_state_changes = true
- }
- }
-peer main {
- ipaddr = ${bfd_main}
- port = 3784
- auth_type = ${bfd_auth_type}
- secret = "hello"
- min_transmit_interval = 250ms
- min_receive_interval = 250ms
- max_timeouts = 3
demand = no
}
+
recv Admin-Down {
ok
}
+
recv Down {
ok
}
+
recv Init {
ok
}
+
recv Up {
ok
}
+
}
```
+
+== Default Configuration
+
+```
+```
## server buffered-sql { ... }
+```
+server buffered-sql {
+```
### listen { ... }
+```
+ listen {
+```
type:: It should be `detail`.
+```
+ type = detail
+```
filename:: The location where the detail file is located.
one large file. File globbing also means that with a common naming scheme for
detail files, then you can have many detail file writers, and only one reader.
+```
+ filename = "${radacctdir}/detail-*"
+```
load_factor::
allowed values: `1 to 100`
+```
+ load_factor = 10
+```
poll_interval:: Interval for polling the detail file.
Useful range of values: `1 to 60`
+```
+ poll_interval = 1
+```
retry_interval:: Set the retry interval for when the home server does not respond.
Useful range of values: `5 to 30`
+```
+ retry_interval = 30
+```
track:: Track progress through the detail file.
The default is `no`.
+```
+# track = yes
+```
one_shot::
The default is `no`.
+```
+# one_shot = no
+ }
+```
### recv Accounting-Request
Pre-accounting. Decide which accounting type to use.
+```
+ recv Accounting-Request {
+```
Ensure that we have a semi-unique identifier for every request, and many NAS
boxes are broken.
+```
+ acct_unique
+```
Read the `acct_users` file. This isn't always necessary, and can be deleted
if you do not use it.
+```
+ files
+ }
+```
### send Accounting-Response
Accounting. Log the accounting data.
+```
+ send Accounting-Response {
+```
Log traffic to an SQL database.
See `Accounting queries` in `mods-config/sql/main/$driver/queries.conf`
+```
+# sql
+```
Cisco VoIP specific bulk accounting.
-
-== Default Configuration
-
```
-server buffered-sql {
- listen {
- type = detail
- filename = "${radacctdir}/detail-*"
- load_factor = 10
- poll_interval = 1
- retry_interval = 30
-# track = yes
-# one_shot = no
- }
- recv Accounting-Request {
- acct_unique
- files
- }
- send Accounting-Response {
-# sql
# pgsql-voip
}
}
```
+
+== Default Configuration
+
+```
+```
-
-
-
-
-
-
-
-
-If there's no State attribute, then this is the request from
-the user.
-
-
-Do authentication for step 2.
-Set the "known good" password to the number
-saved in the session-state list.
-
-
-If the password doesn't match, the user is rejected
-immediately.
-
-
-Set the random number to save.
-
-
-
-Send an Access-Challenge.
-See raddb/policy.d/control for the definition
-of "challenge"
-
-
-
-Do PAP authentication with the password.
-
-
-== Default Configuration
-
```
# This file gives an example of using Challenge-Response
+```
+
+```
# In this example, the user logs in with a password, which has
# to be "hello". The server will send them a challenge
# consisting of a random number 0..9. The user has to respond
# with that number.
+```
+
+```
server challenge {
namespace = radius
+
dictionary {
uint32 challenge-string
}
+
listen {
type = Access-Request
transport = udp
+
udp {
ipaddr = *
port = 2000
}
}
+
recv Access-Request {
+
+```
+
+If there's no State attribute, then this is the request from
+the user.
+
+```
if (!&State) {
&control.Auth-Type := ::Step1
&control.Password.Cleartext := "hello"
}
else {
+```
+
+Do authentication for step 2.
+Set the "known good" password to the number
+saved in the session-state list.
+
+```
&control.Auth-Type := ::Step2
&control.Password.Cleartext := &session-state.challenge-string
}
}
+
authenticate step1 {
+```
+If the password doesn't match, the user is rejected
+immediately.
+```
pap
+
+```
+
+Set the random number to save.
+
+```
&session-state.challenge-string := "%randstr(n)"
&reply.Reply-Message := "Please enter %{session-state.challenge-string}: "
+
+```
+
+Send an Access-Challenge.
+See raddb/policy.d/control for the definition
+of "challenge"
+
+```
challenge
}
+
authenticate step2 {
+```
+
+Do PAP authentication with the password.
+
+```
pap
}
}
```
+
+== Default Configuration
+
+```
+```
A virtual server which is used to validate channel-bindings.
+```
+server channel_bindings {
+```
-Only the "authorize" section is needed.
+Only the "recv Access-Request" section is needed.
+```
+ recv Access-Request {
+```
In general this section should include a policy for each type
of channel binding that may be in use. For example each lower
layer such as GSS-EAP (https://tools.ietf.org/html/rfc7055[RFC 7055]) or IEEE 802.11I is likely to
need a separate channel binding policy.
-
-== Default Configuration
-
```
-server channel_bindings {
- recv Access-Request {
abfab_channel_bindings
}
}
```
+
+== Default Configuration
+
+```
+```
+++ /dev/null
-
-
-This virtual server allows EAP-TLS to reject access requests
-based on some attributes of the certificates involved.
-
-To use this virtual server, you must enable it in the tls
-section of mods-enabled/eap as well as adding a link to this
-file in sites-enabled/.
-
-
-Value-pairs that are available for checking include these
-attributes in the session-state list:
-
- TLS-Client-Cert-Subject
- TLS-Client-Cert-Issuer
- TLS-Client-Cert-Common-Name
- TLS-Client-Cert-Subject-Alt-Name-Email
-
-To see a full list of attributes, run the server in debug mode
-with this virtual server configured, and look at the attributes
-passed in to this virtual server.
-
-
-This virtual server is also useful when using EAP-TLS as it is
-only called once, just before the final Accept is about to be
-returned from eap, whereas the outer authorize section is called
-multiple times for each challenge / response. For this reason,
-here may be a good location to put authentication logging, and
-modules that check for further authorization, especially if they
-hit external services such as sql or ldap.
-
-
-
-Authorize - this is the only section required.
-
-To accept the access request, set Auth-Type = ::Accept, otherwise
-set it to Reject.
-
-
-
-By default, we just accept the request:
-
-
-
-Check the client certificate matches a string, and reject otherwise
-
-
-
-
-Check the client certificate common name against the supplied User-Name
-
-
-
-This is a convenient place to call LDAP, for example, when using
-EAP-TLS, as it will only be called once, after all certificates as
-part of the EAP-TLS challenge process have been verified.
-
-An example could be to use LDAP to check that the connecting host, as
-well as presenting a valid certificate, is also in a group based on
-the User-Name (assuming this contains the service principal name).
-Settings such as the following could be used in the ldap module
-configuration:
-
-basedn = "dc=example, dc=com"
-filter = "(servicePrincipalName=%{User-Name})"
-base_filter = "(objectClass=computer)"
-groupname_attribute = cn
-groupmembership_filter = "(&(objectClass=group)(member=%{control.Ldap-UserDn}))"
-
-
-
-
-Now let's test membership of an LDAP group (the ldap bind user will
-need permission to read this group membership):
-
-
-
-or, to be more specific, you could use the group's full DN:
-if (!(Ldap-Group == "CN=Permitted-Laptops,OU=Groups,DC=example,DC=org")) {
-
-
-This may be a better place to call the files modules when using
-EAP-TLS, as it will only be called once, after the challenge-response
-iteration has completed.
-
-
-
-
-Log all request attributes, plus TLS certificate details, to the
-auth_log file. Again, this is just once per connection request, so
-may be preferable than in the outer authorize section. It is
-suggested that 'auth_log' also be in the outer post-auth and
-Post-Auth REJECT sections to log reply packet details, too.
-
-
-
-
-== Default Configuration
-
-```
-server check-eap-tls {
-recv Access-Request {
- &control.Auth-Type := ::Accept
-# if ("%{session-state.TLS-Client-Cert-Common-Name}" == 'client.example.com') {
-# &control.Auth-Type := ::Accept
-# }
-# else {
-# &control.Auth-Type := ::Reject
-# &reply.Reply-Message := "Your certificate is not valid."
-# }
-# if (&User-Name == "host/%{session-state.TLS-Client-Cert-Common-Name}") {
-# &control.Auth-Type := ::Accept
-# }
-# else {
-# &control.Auth-Type := ::Reject
-# }
-# ldap
-# if (!(Ldap-Group == "Permitted-Laptops")) {
-# &control.Auth-Type := ::Reject
-# }
-# files
- auth_log
-}
-}
-```
client module must be created for each NAS, for example:
radius radius-originate-coa-192.0.2.1 {
+```
+# type = CoA-Request
+# type = Disconnect-Request
+# transport = udp
+# udp {
+# ipaddr = 192.0.2.1
+# port = 1700
+# secret = "testing123"
+# }
+```
+```
+# # We are "originating" these packets since including Proxy-State
+# # may confuse the NAS
+# originate = yes
+```
+```
+# # Uncomment this to fire and forget, rather than wait and retry
+# # replicate = yes
+```
}
Refer to `mods-enabled/radius` as a detailed reference for configuring
client access to each NAS.
+```
+server coa {
+ namespace = radius
+```
Listen on a local CoA port.
This uses the normal set of clients, with the same secret as for
authentication and accounting.
+```
+ listen {
+ type = CoA-Request
+ type = Disconnect-Request
+ transport = udp
+ udp {
+ ipaddr = 127.0.0.1
+ port = 3799
+ }
+ }
+ dictionary {
+ uint32 sent-counter
+ string user-session
+ }
+```
Receive a CoA request
+```
+ recv CoA-Request {
+```
Lookup all active sessions matching User-Name and/or
Acct-Session-Id and send updates for each session
Example MySQL lookup
+```
+# &control.user-session := %sql("SELECT IFNULL(GROUP_CONCAT(CONCAT(nasipaddress,'#',acctsessionid) separator '|'),'') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
+```
Example PostgreSQL lookup
+```
+# &control.user-session := %sql("SELECT STRING_AGG(CONCAT(nasipaddress,'#',acctsessionid),'|') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
+```
Keep a count of what we send.
+```
+ &control.sent-counter := 0
+```
Split the string and split into pieces.
+```
+ if ("%explode(&control.user-session, '|')") {
+ foreach &control.user-session {
+```
Send an update for each session we find.
+```
+ if ("%{Foreach-Variable-0}" =~ /([^#]*)#(.*)/) {
+```
NAS-IP-Address
+```
+ &control.NAS-IP-Address := "%{1}"
+```
Acct-Session-Id
+```
+ &control.Acct-Session-Id := "%{2}"
+ subrequest CoA-Request {
+```
The subrequest begins empty, so initially copy all attributes
from the incoming request.
+```
+ &request := &parent.request
+```
Add/override the session identification attributes looked up
+```
+ &request.Acct-Session-Id := &parent.control.Acct-Session-Id
+```
Some NASs want these, others don't
+```
+ &request.Event-Timestamp := "%l"
+ &request.Message-Authenticator := 0x00
+```
Remove attributes which will confuse the NAS
SQL-User-Name is a side-effect of the xlat
+```
+ &request -= &SQL-User-Name[*]
+```
Those attributes should be listed here
+```
+ &request -= &Acct-Delay-Time[*]
+ &request -= &Proxy-State[*]
+```
Uncomment if the NAS does not expect User-Name
Call the radius client module instance for the NAS-IP-Address
+```
+ switch &parent.control.NAS-IP-Address {
+```
Repeat this block for each NAS
+```
+ case "192.0.2.1" {
+```
Increment count of sent updates
+```
+ &parent.control.sent-counter += 1
+ radius-originate-coa-192.0.2.1
+ }
+```
Likely a missing "case" block if we can't map NAS-IP-Address to a module
-
-
-
-
-
-Report what we did
-
-
-
-
-
-
-Receive a Disconnect request
-
-
-Populate this section as above, but use "subrequest Disconnect-Request"
-
-
-
-
-== Default Configuration
-
```
-# type = CoA-Request
-# type = Disconnect-Request
-# transport = udp
-# udp {
-# ipaddr = 192.0.2.1
-# port = 1700
-# secret = "testing123"
-# }
-# # We are "originating" these packets since including Proxy-State
-# # may confuse the NAS
-# originate = yes
-# # Uncomment this to fire and forget, rather than wait and retry
-# # replicate = yes
-server coa {
- namespace = radius
- listen {
- type = CoA-Request
- type = Disconnect-Request
- transport = udp
- udp {
- ipaddr = 127.0.0.1
- port = 3799
- }
- }
- dictionary {
- uint32 sent-counter
- string user-session
- }
- recv CoA-Request {
-# &control.user-session := %sql("SELECT IFNULL(GROUP_CONCAT(CONCAT(nasipaddress,'#',acctsessionid) separator '|'),'') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
-# &control.user-session := %sql("SELECT STRING_AGG(CONCAT(nasipaddress,'#',acctsessionid),'|') FROM (SELECT * FROM radacct WHERE ('%{User-Name}'='' OR UserName='%{User-Name}') AND ('%{Acct-Session-Id}'='' OR acctsessionid = '%{Acct-Session-Id}') AND AcctStopTime IS NULL) a")
- &control.sent-counter := 0
- if ("%explode(&control.user-session, '|')") {
- foreach &control.user-session {
- if ("%{Foreach-Variable-0}" =~ /([^#]*)#(.*)/) {
- &control.NAS-IP-Address := "%{1}"
- &control.Acct-Session-Id := "%{2}"
- subrequest CoA-Request {
- &request := &parent.request
- &request.Acct-Session-Id := &parent.control.Acct-Session-Id
- &request.Event-Timestamp := "%l"
- &request.Message-Authenticator := 0x00
- &request -= &SQL-User-Name[*]
- &request -= &Acct-Delay-Time[*]
- &request -= &Proxy-State[*]
- switch &parent.control.NAS-IP-Address {
- case "192.0.2.1" {
- &parent.control.sent-counter += 1
- radius-originate-coa-192.0.2.1
- }
default {
&parent.control += {
&Reply-Message = "Missing map for NAS: %{parent.control.NAS-IP-Address}"
}
}
+
} # subrequest
+
}
+
}
} # foreach session
}
+
+```
+
+Report what we did
+
+```
if (&control.sent-counter) {
&reply += {
&Reply-Message = "Sent updates for %{control.sent-counter} active sessions"
}
+
ok
} else {
&reply += {
&Reply-Message = "No active sessions found"
}
+
reject
}
+
}
+
+```
+
+Receive a Disconnect request
+
+```
recv Disconnect-Request {
+```
+
+Populate this section as above, but use "subrequest Disconnect-Request"
+
+```
}
+
}
+
+```
+
+== Default Configuration
+
+```
```
Sample virtual server for receiving a CoA or Disconnect-Request packet.
+```
+server coa {
+ namespace = radius
+```
Listen on the CoA port.
This uses the normal set of clients, with the same secret as for
authentication and accounting.
+```
+ listen {
+ type = CoA-Request
+ type = Disconnect-Request
+ transport = udp
+ udp {
+ ipaddr = *
+ port = 3799
+ }
+ }
+```
Receive a CoA request
+```
+ recv CoA-Request {
+```
Insert your own policies here.
+```
+ ok
+ }
+```
Send a CoA ACK
+```
+ send CoA-ACK {
+```
Sample module.
+```
+ ok
+ }
+```
Send a CoA NAK
+```
+ send CoA-NAK {
+```
Sample module.
+```
+ ok
+ }
+```
Receive a Disconnect request
+```
+ recv Disconnect-Request {
+```
Insert your own policies here.
+```
+ ok
+ }
+```
Send a Disconnect ACK
+```
+ send Disconnect-ACK {
+```
Sample module.
+```
+ ok
+ }
+```
Send a Disconnect NAK
-Sample module.
-
-== Default Configuration
-
```
-server coa {
- namespace = radius
- listen {
- type = CoA-Request
- type = Disconnect-Request
- transport = udp
- udp {
- ipaddr = *
- port = 3799
- }
- }
- recv CoA-Request {
- ok
- }
- send CoA-ACK {
- ok
- }
- send CoA-NAK {
- ok
- }
- recv Disconnect-Request {
- ok
- }
- send Disconnect-ACK {
- ok
- }
send Disconnect-NAK {
+```
+Sample module.
+```
ok
}
}
```
+
+== Default Configuration
+
+```
+```
= Control socket interface.
+```
+# In the future, we will add username/password checking for
+# connections to the control socket. We will also add
+# command authorization, where the commands entered by the
+# administrator are run through a virtual server before
+# they are executed.
+```
+```
+# For now, anyone who has permission to connect to the socket
+# has nearly complete control over the server. Be warned!
+```
+```
+# NOTE: This functionality is NOT enabled by default.
+```
+```
+# See also the "radmin" program, which is used to communicate
+# with the server over the control socket.
+```
+```
+server control-socket-server {
+```
namespace:: Determine the current scope as a control service.
+```
+ namespace = control
+```
All configuration related to the control interface.
+```
+ listen {
+```
transport:: Define which communication channel.
+```
+ transport = unix
+```
UNIX socket-file as communication channel.
+```
+ unix {
+```
filename:: Socket location.
if it doesn't exist and set the appropriate ownership and
permissions.
+```
+ filename = ${run_dir}/control/${name}.sock
+```
uid:: Name of user who owns the control socket.
Note that the control socket cannot have uid of 0.
+```
+# uid = radius
+```
gid:: Name of group which owns the control socket.
Note that the control socket cannot have gid of 0.
+```
+# gid = radius
+```
mode:: Access mode.
ro = read only access (default)
rw = read/write access.
+```
+ mode = rw
+```
As an additional check, the connecting process can be limited to a certain UID and
GID. Either or both can be set. If one is set, it is checked and enforced.
-
-
-== Default Configuration
-
```
-# In the future, we will add username/password checking for
-# connections to the control socket. We will also add
-# command authorization, where the commands entered by the
-# administrator are run through a virtual server before
-# they are executed.
-# For now, anyone who has permission to connect to the socket
-# has nearly complete control over the server. Be warned!
-# NOTE: This functionality is NOT enabled by default.
-# See also the "radmin" program, which is used to communicate
-# with the server over the control socket.
-server control-socket-server {
- namespace = control
- listen {
- transport = unix
- unix {
- filename = ${run_dir}/control/${name}.sock
-# uid = radius
-# gid = radius
- mode = rw
peercred {
# uid = something
# gid = something
}
+
}
}
}
```
+
+== Default Configuration
+
+```
+```
= Control socket interface.
+```
+# In the future, we will add username/password checking for
+# connections to the control socket. We will also add
+# command authorization, where the commands entered by the
+# administrator are run through a virtual server before
+# they are executed.
+```
+```
+# For now, anyone who has permission to connect to the socket
+# has nearly complete control over the server. Be warned!
+```
+```
+# NOTE: This functionality is NOT enabled by default.
+```
+```
+# See also the "radmin" program, which is used to communicate
+# with the server over the control socket.
+```
+```
+server control {
+```
namespace:: Determine the current scope as a control service.
+```
+ namespace = control
+```
All configuration related to the control interface.
+```
+ listen {
+```
transport:: Define which communication channel.
+```
+ transport = unix
+```
UNIX socket-file as communication channel.
+```
+ unix {
+```
filename:: Socket location.
if it doesn't exist and set the appropriate ownership and
permissions.
+```
+ filename = ${run_dir}/control/${name}.sock
+```
peercred:: It is enabled by default, and offers an additional layer
of security. When enabled FreeRADIUS will check the euid and
control socket authorization via group membership, you should set
`peercred = no`, and rely on filesystem permissions for enforcement.
+```
+# peercred = no
+```
uid:: Name of user who is allowed to connect to the control socket.
+```
+# uid = radius
+```
gid:: Name of group that is allowed to connect to the control socket.
+```
+# gid = radius
+```
mode:: Access mode.
ro = read only access (default)
rw = read/write access.
+```
+ mode = rw
+ }
+```
@todo - add "limit" section
+```
+ }
+```
These don't do anything for now
-
-
-== Default Configuration
-
```
-# In the future, we will add username/password checking for
-# connections to the control socket. We will also add
-# command authorization, where the commands entered by the
-# administrator are run through a virtual server before
-# they are executed.
-# For now, anyone who has permission to connect to the socket
-# has nearly complete control over the server. Be warned!
-# NOTE: This functionality is NOT enabled by default.
-# See also the "radmin" program, which is used to communicate
-# with the server over the control socket.
-server control {
- namespace = control
- listen {
- transport = unix
- unix {
- filename = ${run_dir}/control/${name}.sock
-# peercred = no
-# uid = radius
-# gid = radius
- mode = rw
- }
- }
recv {
ok
}
+
send {
ok
}
}
```
+
+== Default Configuration
+
+```
+```
+```
+***************
+*** 83,94 ****
+```
uid:: Name of user who is allowed to connect to the control socket.
+```
+- # uid = radius
+```
gid:: Name of group that is allowed to connect to the control socket.
+```
+- # gid = radius
+```
Access mode.
+```
+--- 83,94 ----
+```
uid:: Name of user who is allowed to connect to the control socket.
+```
++ # uid = freerad
+```
gid:: Name of group that is allowed to connect to the control socket.
+```
++ # gid = freerad
+```
Access mode.
+```
== Default Configuration
```
-***************
-*** 83,94 ****
-- # uid = radius
-- # gid = radius
---- 83,94 ----
-+ # uid = freerad
-+ # gid = freerad
```
WARNING: This configuration file has not been updated for v4,
and therefore WILL NOT WORK. Please do not use it.
+```
+# In 2.0.0, radrelay functionality is integrated into the
+# server core. This virtual server gives an example of
+# using radrelay functionality inside of the server.
+```
+```
+# In this example, the detail file is read, and the packets
+# are proxied to a home server. You will have to configure
+# realms, home_server_pool, and home_server in proxy.conf
+# for this to work.
+```
+```
+# The purpose of this virtual server is to enable duplication
+# of information across a load-balanced, or fail-over set of
+# servers. For example, if a group of clients lists two
+# home servers (primary, secondary), then RADIUS accounting
+# messages will go only to one server at a time. This file
+# configures a server (primary, secondary) to send copies of
+# the accounting information to each other.
+```
+```
+# That way, each server has the same set of information, and
+# can make the same decision about the user.
+```
+```
+server copy-acct-to-home-server {
+ listen {
+ type = detail
+```
See sites-available/buffered-sql for more details on
all the options available for the detail reader.
a common naming scheme for detail files, then you can
have many detail file writers, and only one reader.
+```
+ filename = ${radacctdir}/detail
+```
The server can read accounting packets from the
detail file much more quickly than those packets
will read packets as fast as it can, usually
causing databases to go into overload.
+```
+ load_factor = 10
+```
Track progress through the detail file. When the detail
file is large, and the server is restarted, it will
track = yes
+```
+ }
+```
Pre-accounting. Decide which accounting type to use.
+```
+ recv Accounting-Request {
+```
Read the 'acct_users' file. This isn't always
necessary, and can be deleted if you do not use it.
+```
+ files
+ }
+```
Accounting. Log the accounting data.
+```
+ send Accounting-Response {
+```
Since we're proxying, we don't log anything
locally. Ensure that the accounting section
"succeeds" by forcing an "ok" return.
+```
+ ok
+ }
+```
When the server decides to proxy a request to a home server,
the proxied request is first passed through the pre-proxy
Only a few modules currently have this method.
+```
+ pre-proxy {
+```
If you want to have a log of packets proxied to a home
server, uncomment the following line, and the
'detail pre_proxy_log' section in radiusd.conf.
pre_proxy_log
+```
+ }
+```
When the server receives a reply to a request it proxied
to a home server, the request may be massaged here, in the
post-proxy stage.
+```
+ post-proxy {
+```
If you want to have a log of replies from a home
defined in the 'attrs' file.
attr_filter
+```
+ }
+}
+```
== Default Configuration
```
-# In 2.0.0, radrelay functionality is integrated into the
-# server core. This virtual server gives an example of
-# using radrelay functionality inside of the server.
-# In this example, the detail file is read, and the packets
-# are proxied to a home server. You will have to configure
-# realms, home_server_pool, and home_server in proxy.conf
-# for this to work.
-# The purpose of this virtual server is to enable duplication
-# of information across a load-balanced, or fail-over set of
-# servers. For example, if a group of clients lists two
-# home servers (primary, secondary), then RADIUS accounting
-# messages will go only to one server at a time. This file
-# configures a server (primary, secondary) to send copies of
-# the accounting information to each other.
-# That way, each server has the same set of information, and
-# can make the same decision about the user.
-server copy-acct-to-home-server {
- listen {
- type = detail
- filename = ${radacctdir}/detail
- load_factor = 10
- }
- recv Accounting-Request {
- files
- }
- send Accounting-Response {
- ok
- }
- pre-proxy {
- }
- post-proxy {
- }
-}
```
-
-== Default Configuration
-
```
&Filter-Id := "db.findAndModify({ \
'query': { \
'upsert': 2 1 1 true \
})"
```
+
+== Default Configuration
+
+```
+```
This is the `cron` virtual server.
+```
+server cron {
+```
namespace:: The protocol / dictionary to use.
The `cron` functionality can be used with any protocol.
+```
+ namespace = radius
+```
You can have a `radius` subsection here. See the `default`
virtual server for documentation.
Create a `cron` listener. Note that leaving off the `cron` name
will result in the protocol trying to open a socket!
+```
+ listen cron {
+```
type:: What type of packet is being processed.
The `type` should be a valid name for the protocol.
+```
+ type = Access-Request
+```
transport: What kind of cron functionality we are using.
For now, only `crontab` is supported.
+```
+ transport = crontab
+```
crontab:: Run `crontab` style jobs.
+```
+ crontab {
+```
timespec:: the `crontab` style time specification.
Steps can be given for ranges:
* 1-20/4
+```
+ timespec = "* * * * *"
+```
filename:: The file which is read, cached, and processed
`cron` is done inside of the processing
sections.
-
-
-
-
-
-== Default Configuration
-
```
-server cron {
- namespace = radius
- listen cron {
- type = Access-Request
- transport = crontab
- crontab {
- timespec = "* * * * *"
filename = /Users/alandekok/git/wrapper/freeradius-server/user_password
}
}
+
recv Access-Request {
ok
}
+
send Access-Accept {
ok
}
+
send Access-Reject {
ok
}
+
send Do-Not-Respond {
ok
}
}
```
+
+== Default Configuration
+
+```
+```
+```
+# This is a sample configuration for "decoupled" accounting.
+# "Decoupled" accounting is where the accounting packets are
+# NOT written "live" to the back-end database. This method
+# can only be used if you are not interested in "live"
+# accounting. i.e. Where you can tolerate delays that may be
+# a few seconds, before accounting packets get written to
+# the DB.
+```
+```
+# Oddly enough, this method can speed up the processing of
+# accounting packets, as all database activity is serialized.
+```
+```
+# This file is NOT meant to be used as-is. It needs to be
+# edited to match your local configuration.
+```
Define a virtual server to write the accounting packets.
Any "listen" section that listens on an accounting port should
set "virtual_server = write-detail.example.com
+```
+server write_detail.example.com {
+ recv Accounting-Request {
+```
Write the "detail" files.
See raddb/modules/detail.example.com for more info.
+```
+ detail.example.com
+ }
+```
That's it!
+```
+}
+```
Define a virtual server to process the accounting packets.
+```
+server read-detail.example.com {
+```
Read accounting packets from the detail file(s) for
the home server.
+```
+ listen {
+ type = detail
+ filename = "${radacctdir}/detail.example.com/detail-*:*"
+ load_factor = 10
+ track = yes
+ }
+```
All packets read from the detail file are processed through
the preacct && accounting sections.
Pre-accounting. Decide which accounting type to use.
+```
+recv Accounting-Request {
+```
Ensure that we have a semi-unique identifier for every
request, and many NAS boxes are broken.
+```
+ acct_unique
+```
Read the 'acct_users' file
+```
+ files
+}
+```
Accounting. Log the accounting data.
+```
+send Accounting-Response {
+```
Create a 'detail'ed log of the packets.
Note that accounting requests which are proxied
are also logged in the detail file.
+```
+ detail
+# daily
-For Simultaneous-Use tracking.
-
-Due to packet losses in the network, the data here
-may be incorrect. There is little we can do about it.
-
+```
Return an address to the IP Pool when we see a stop record.
Ensure that &control.IP-Pool.Name is set to determine which
+```
+ # pool of IPs are used.
+```
+```
+ sqlippool
+```
Log traffic to an SQL database.
through this virtual server!
See "Accounting queries" in `mods-config/sql/main/$driver/queries.conf`
+```
+# sql
+```
Instead of sending the query to the SQL server,
write it into a log file.
+```
+# sql_log
+```
Cisco VoIP specific bulk accounting
+```
+# pgsql-voip
+```
Filter attributes from the accounting response.
+```
+ attr_filter.accounting_response
+```
See "Autz-Type Status-Server" for how this works.
-
-
-== Default Configuration
-
```
-# This is a sample configuration for "decoupled" accounting.
-# "Decoupled" accounting is where the accounting packets are
-# NOT written "live" to the back-end database. This method
-# can only be used if you are not interested in "live"
-# accounting. i.e. Where you can tolerate delays that may be
-# a few seconds, before accounting packets get written to
-# the DB.
-# Oddly enough, this method can speed up the processing of
-# accounting packets, as all database activity is serialized.
-# This file is NOT meant to be used as-is. It needs to be
-# edited to match your local configuration.
-server write_detail.example.com {
- recv Accounting-Request {
- detail.example.com
- }
-}
-server read-detail.example.com {
- listen {
- type = detail
- filename = "${radacctdir}/detail.example.com/detail-*:*"
- load_factor = 10
- track = yes
- }
-recv Accounting-Request {
- acct_unique
- files
-}
-send Accounting-Response {
- detail
-# daily
- unix
- # pool of IPs are used.
- sqlippool
-# sql
-# sql_log
-# pgsql-voip
- attr_filter.accounting_response
# Acct-Type Status-Server {
+```
+
+```
# }
}
}
```
+
+== Default Configuration
+
+```
+```
configurations These references serve as place-holders, and as
documentation. If you need the functionality of that module, then:
- * configure the module in link:../../../../../../mods-available/index.adoc[mods-available/]
+ * configure the module in xref:reference:raddb/mods-available/index.adoc[mods-available/]
* enable the module in `mods-enabled`. e.g. for LDAP, do: `cd mods-enabled;ln -s ../mods-available/ldap`
* uncomment the references to it in this file.
This is the `default` virtual server.
+```
+server default {
+```
-namespace::
+namespace:: The protocol namespace (i.e. dictionary) to use.
In v4, all "server" sections MUST start with a "namespace"
parameter. This tells the server which protocol is being used.
All of the "listen" sections in this virtual server will
only accept packets for that protocol.
+```
+ namespace = radius
+
+```
+
+log:: The name of the logging section to use.
+The top configuration section can contain multiple section "log foo { ... }".
+Each of those sections is a different named logging destination.
+
+This configuration item allows setting a different logging destination for an
+individual virtual server.
+
+There are some limitations.
+
+ * this logging is in _addition_ to the default logging to "log { .... }".
+ * it is not currently possible to _replace_ the default logging destination
+ * the name given here _must_ be a fixed string, and is not dynamically expanded.
+
+```
+# log = some_other_logging_destination
+
+```
### RADIUS Configuration
All of the configuration for processing RADIUS packets goes here.
+```
+ radius {
+```
#### Access-Request subsection
packets. At this time, there is no configuration
needed for other packet types.
+```
+ Access-Request {
+```
session:: Controls how ongoing
(multi-round) sessions are handled
authentication attempts that can occur
concurrently.
+```
+ session {
+```
max:: The maximum number of ongoing sessions
+```
+# max = 4096
+```
timeout:: How long to wait before expiring a
session.
containing the previously sent
state value is received.
+```
+# timeout = 15
+ }
+ }
+```
There is currently no configuration for other packet types.
+```
+ }
+```
### Local Dictionaries
In all other aspects, the attributes defined here are just the same
as if they had been assigned in a dictionary file.
+```
+ dictionary {
+```
The syntax is _<type>_ followed by _<name>_.
The _<name>_ MUST NOT exist in the `namespace` dictionary.
+```
+# uint32 foo
+```
tlv:: Define a TLV variable using _tlv <name> { ...}_.
The contents of the `tlv` subsection are more variable
definitions, including child `tlv`s.
+```
+# tlv bar {
+# uint32 baz
+# string arg
+# }
+```
values:: Define a set of values for attribute _<name>_.
The contents of the `values` section are a list of names and
values.
+```
+# values foo {
+```
_<name>_ = _<value>_
The _<value>_ is parsed according to the data type of
the attribute.
+```
+# bar = 1
+# baz = 2
+# }
+ }
+```
### The listen section
order to make FreeRADIUS more flexible, and to make the
configuration simpler and more consistent.
+```
+ listen {
+```
type:: The type of packet to accept.
configuration was awkward and potentially
confusing.
+```
+ type = Access-Request
+ type = Status-Server
+```
transport:: The transport protocol.
"inner tunnel" portion of PEAP and TTLS. But it
does not accept those packets from the network.
+```
+ transport = udp
+```
require_message_authenticator::Require Message-Authenticator
in Access-Requests.
The default is "no".
+```
+ require_message_authenticator = auto
+```
limit_proxy_state:: Control whether Proxy-State is allowed in
packets from this client which do not have a Message-Authenticator.
The default is "auto".
+```
+ limit_proxy_state = auto
+```
limit:: limits for this socket.
Limits are used to prevent "run-away" problems.
+```
+ limit {
+```
max_clients:: The maximum number of dynamic
clients which can be defined for this
(e.g. NAS, AP, etc.) which will be sending
packets to FreeRADIUS.
+```
+ max_clients = 256
+```
max_connections:: The maximum number of
connected sockets which will be accepted
sockets (e.g. TCP), then this configuration
item is ignored.
+```
+ max_connections = 256
+```
idle_timeout:: Time after which idle
connections or dynamic clients are deleted.
Useful range of values: 5 to 600
+```
+ idle_timeout = 60.0
+```
nak_lifetime:: Time for which blocked
clients are placed into a NAK cache.
Useful range of values: 1 to 600
+```
+ nak_lifetime = 30.0
+```
cleanup_delay:: The time to wait (in
seconds) before cleaning up a reply to an
Useful range of values: 2 to 30
+```
+ cleanup_delay = 5.0
+ }
+```
#### UDP Transport
subsection contains all of the configuration for
the UDP transport.
+```
+ udp {
+```
ipaddr:: The IP address where FreeRADIUS
accepts packets.
The same as `ipaddr`, but will only use
IPv6 addresses.
+```
+ ipaddr = *
+```
port:: the UDP where FreeRADIUS accepts
packets.
The default port for Access-Accept packets
is `1812`.
+```
+ port = 1812
+```
dynamic_clients:: Whether or not we allow
dynamic clients.
for more information about how dynamic
clients work.
+```
+# dynamic_clients = true
+```
networks:: The list of networks which are
allowed to send packets to FreeRADIUS for
could trigger dynamic clients, then the
server would be subject to a DoS attack.
+```
+ networks {
+```
allow:: Allow packets from these
networks to define dynamic clients.
There is no limit to the number of
networks which can be listed here.
+```
+ allow = 127/8
+ allow = 192.0.2/24
+```
deny:: deny some networks.
they appear in the configuration
file does not matter.
+```
+# deny = 127.0.0/24
+ }
+ }
+```
#### TCP Transport
Since UDP and TCP are similar, the majority of the
configuration items are the same for both of them.
+```
+ tcp {
+```
ipaddr:: The IP address where FreeRADIUS
accepts packets.
It has the same definition and meaning as
the UDP `ipaddr` configuration above.
+```
+ ipaddr = *
+```
NOTE: As with v3, `ipaddr`, `ipv4addr`, and `ipv6addr`
are all allowed.
The default port for Access-Accept packets
is `1812`.
+```
+ port = 1812
+```
dynamic_clients:: Whether or not we allow dynamic clients.
subsection below. See that section for
more information.
+```
+# dynamic_clients = true
+```
networks { ... }::
If dynamic clients are not allowed, then
this section is ignored.
+```
+ networks {
+```
allow:: Allow packets from a network.
address. The order of the items given here
does not matter.
+```
+ allow = 127/8
+ allow = 192.0.2/24
+# deny = 127.0.0/24
+ }
+ }
+ }
+ listen tcp_auth {
+ type = Access-Request
+ type = Status-Server
+ transport = tcp
+ tcp {
+```
As with v3, "ipaddr", "ipv4addr", and "ipv6addr"
are all allowed.
+```
+ ipaddr = *
+ port = 1812
+```
Whether or not we allow dynamic clients.
subsection below. See that section for
more information.
+```
+# dynamic_clients = true
+```
If dynamic clients are allowed, then limit
them to only a small set of source
If dynamic clients are not allowed, then
this section is ignored.
+```
+ networks {
+```
Allow packets from these networks
to define dynamic clients.
There is no limit to the number of
networks which can be listed here.
+```
+ allow = 127/8
+ allow = 192.0.2/24
+# deny = 127.0.0/24
+ }
+ }
+ }
+```
### Listen for Accounting-Request packets
+```
+ listen udp_acct {
+ type = Accounting-Request
+ transport = udp
+ udp {
+ ipaddr = *
+ port = 1813
+ }
+ }
+```
### Local Clients
The clients listed here take precedence over the global
clients.
+```
+ client localhost {
+ shortname = sample
+ ipaddr = 192.0.2.1
+ secret = testing123
+```
The other "client" configuration items can be added
here, too.
+```
+ }
+```
## Packet Processing sections
### Receive Access-Request packets
+```
+recv Access-Request {
+```
Take a `link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]`, and perform some checks on it, for
spaces and other invalid characters. If the `link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]`
See policy.d/filter for the definition of the
filter_username policy.
+```
+ filter_username
+```
Some broken equipment sends passwords with embedded
zeros, i.e. the debug output will show:
This policy will fix the password to just be "password".
+```
+# filter_password
+```
If you intend to use CUI and you require that the
Operator-Name be set for CUI generation and you want to
operator-name below and set the operator-name for
your clients in clients.conf.
+```
+# operator-name
+```
Proxying example
The following example will proxy the request if the
username ends in example.com.
+```
+# if (&User-Name =~ /@example\.com$/) {
+# &control.Auth-Type := "proxy-example.com"
+# }
+```
If you want to generate CUI for some clients that do
not send proper CUI requests, then uncomment cui below
and set "add_cui = yes" for these clients in
clients.conf.
+```
+# cui
+```
The `auth_log` module will write all `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packets to a file.
Uncomment the next bit in order to have a log of
authentication requests. For more information, see
-link:../../../../../../mods-available/detail.log.adoc[mods-available/detail.log].
+xref:reference:raddb/mods-available/detail.log.adoc[mods-available/detail.log].
+```
+# auth_log
+```
The `chap` module will set `Auth-Type := ::CHAP` if the
packet contains a `link:https://freeradius.org/rfc/rfc2865.html#CHAP-Challenge[CHAP-Challenge]` attribute. The module
does this only if the `Auth-Type` attribute has not already
been set.
+```
+ chap
+```
The `mschap` module will set `Auth-Type := ::mschap` if the
packet contains an `link:https://freeradius.org/rfc/rfc2548.html#MS-CHAP-Challenge[MS-CHAP-Challenge]` attribute. The
module does this only if the `Auth-Type` attribute has not
already been set.
+```
+ mschap
+```
The `digest` module implements the SIP Digest
authentication method.
"Digest"` if we are handling a SIP Digest request and the
`Auth-Type` has not already been set.
+```
+ digest
+```
The `wimax` module fixes up various WiMAX-specific stupidities.
`link:https://freeradius.org/rfc/rfc2865.html#Calling-Station-Id[Calling-Station-Id]` attribute to the normal format as
specified in https://tools.ietf.org/html/rfc3580#section-3.21.[RFC 3580 Section 3.21.]
+```
+# wimax
+```
The `eap` module takes care of all EAP authentication,
including EAP-MD5, EAP-TLS, PEAP and EAP-TTLS.
The module also sets the EAP-Type attribute in the request
list, to the incoming EAP type.
-The `eap` module returns `ok` if it is not yet ready to
+The `eap` module returns `ok` or `updated` if it is not yet ready to
authenticate the user. The configuration below checks for
that return value, and if so, stops processing the current
section.
We also recommend doing user lookups in the `inner-tunnel`
virtual server.
+```
+ eap {
+ ok = return
+ updated = return
+ }
+```
The `unix` module will obtain passwords from `/etc/passwd`
or `/etc/shadow`. It does this via the system API's, which
are not thread-safe. We do not recommend using the `unix` module.
+```
+# unix
+```
Read what used to be the `users` file. Since v3, this file
is located in `mods-config/files/authorize`.
+```
+ files
+```
Look in an SQL database. The schema of the database is
meant to mirror the `users` file. For a full description
of the module behavior, please see
https://wiki.freeradius.org/modules/Rlm_sql
+```
+ -sql
+```
If you are using /etc/smbpasswd, and are also doing mschap
authentication, the uncomment this line, configure the
module.
+```
+# smbpasswd
+```
The `ldap` module reads passwords and other attributes from
an LDAP database.
For a full description of the module behavior, please see
https://wiki.freeradius.org/modules/Rlm_ldap
+```
+ -ldap
+```
Enforce daily limits on time spent logged in. This module
is a variant of the `counter` module.
+```
+# dailycounter
+```
See if the account has expired: check the time in the
`Expiration` attribute and reject if we are past it.
If the account has not expired, set `link:https://freeradius.org/rfc/rfc2865.html#Session-Timeout[Session-Timeout]`.
+```
+ expiration
+```
The `pap` module will set `Auth-Type := ::PAP` if the
packet contains a `link:https://freeradius.org/rfc/rfc2865.html#User-Password[User-Password]` attribute. The module
This module should be listed last, so that the other
modules get a chance to set Auth-Type for themselves.
+```
+ pap
+}
+```
### Receive Status-Server packets
This section is processed when the server receives a `Status-Server`
packet.
+```
+recv Status-Server {
+```
We are still here and responding.
+```
+ ok
+}
+```
## Authentication Sections
good" password for the user. The password can be clear-text, or
encrypted via `crypt`, `bcrypt`, or other hashing.
+```
+authenticate pap {
+ pap
+}
+```
### CHAP Authentication
listed in the "recv Access-Request" section MUST supply a
Password.Cleartext attribute. Encrypted passwords won't work.
+```
+authenticate chap {
+ chap
+}
+```
### MS-CHAP authentication
either a Password.Cleartext attribute, or a Password.NT
attribute. Encrypted passwords won't work.
+```
+authenticate mschap {
+ mschap
+}
+```
### SIP Digest Authentication
The `digest` line in the `recv Access-Request` section should also
be uncommented.
+```
+authenticate digest {
+ digest
+}
+```
## PAM (Pluggable Authentication Modules) Authentication
that anything that can be done in PAM can be done easier in
FreeRADIUS.
+```
+#authenticate pam {
+# pam
+#}
+```
### LDAP Authentication
section. And, ensuring that the account used by FreeRADIUS has
read permission on all of the users, groups, and passwords.
+```
+authenticate ldap {
+ -ldap
+}
+```
EAP Authentication
For EAP-MD5, EAP-MSCHAP, EAP-TLS, EAP-TTLS, EAP-PEAP, EAP-PWD, etc.
+```
+authenticate eap {
+ eap
+}
+```
### Proxying
The following example shows how proxying to three remote servers
can be configured.
-The `Auth-Type` attribute would need to be set to
-`proxy-example.com`. The home servers MUST be defined in
-link:../../../../../../mods-available/radius.adoc[mods-available/radius].
+Proxying will be done by setting `Auth-Type := example.com`, and
+defining the home servers in xref:reference:raddb/mods-available/radius.adoc[mods-available/radius].
+```
+#authenticate example.com {
+# #
+# # Log the request before proxying.
+# #
+# pre_proxy_log
+```
+```
+# #
+# # Send the request to remote RADIUS servers, with
+# # fail-over from one to the other if there's no response.
+# #
+# redundant {
+# radius1.example.com
+# radius2.example.com
+# radius3.example.com
+# }
+```
+```
+# #
+# # Log the reply after proxying.
+# #
+# post_proxy_log.post-proxy
+#}
+```
## Send replies to Access-Request packets
response. It is configured to filter out all attributes that should
not be in the packet.
+```
+send Access-Challenge {
+ attr_filter.access_challenge
+ handled
+}
+```
### send Access-Accept packets
Once we know that the user has been authenticated successfully,
there are additional things that can be done.
+```
+send Access-Accept {
+```
If you need to have a State attribute, you can add it
here. e.g. for later CoA-Request with State, and
Service-Type = ::Authorize-Only.
+```
+# if (!&reply.State) {
+# &reply.State := "0x%randstr(16h)"
+# }
+```
For EAP-TTLS and PEAP, add any cached attributes to the
reply. The "session-state" attributes are automatically
The `session-state` attributes are deleted after an
`link:https://freeradius.org/rfc/rfc2865.html#Access-Reject[Access-Reject]` or `link:https://freeradius.org/rfc/rfc2865.html#Access-Accept[Access-Accept]` packet has been sent.
+```
+ &reply += &session-state
+```
For EAP, ensure that the Access-Accept contains a User-Name
attribute.
+```
+ eap
+```
Get an address from the IP Pool.
+```
+# sqlippool
+```
Create the CUI value and add the attribute to
Access-Accept. Uncomment the line below if
*returning* the CUI to the NAS.
+```
+# cui
+```
If you want to have a log of authentication replies,
uncomment the following line. This is defined in
-link:../../../../../../mods-available/detail.log.adoc[mods-available/detail.log].
+xref:reference:raddb/mods-available/detail.log.adoc[mods-available/detail.log].
+```
+# reply_log
+```
After authenticating the user, do another SQL query.
+```
+ -sql
+```
Uncomment the following if you want to modify the
user's object in LDAP after a successful login.
+```
+# ldap
+```
Calculate the various WiMAX keys. In order for this to
work, you will need to define the WiMAX NAI, usually
via:
+```
+# &request.WiMAX-MN-NAI = "%{User-Name}"
+```
If you want various keys to be calculated, you will
need to update the reply with "template" values. The
module will see this, and replace the template values
with the correct ones taken from the cryptographic
calculations, e.g.
+```
+# &reply += {
+# &Vendor-Specific.WiMAX = {
+# &FA-RK-Key = 0x00
+# &MSK = &reply.EAP-MSK
+# }
+# }
+```
You may want to delete the `MS-MPPE-*-Keys` from the
reply, as some WiMAX clients behave badly when those
attributes are included. See the configuration entry
-`delete_mppe_keys` in link:../../../../../../mods-available/wimax.adoc[mods-available/wimax] for
+`delete_mppe_keys` in xref:reference:raddb/mods-available/wimax.adoc[mods-available/wimax] for
more information.
+```
+# wimax
+```
If there is a client certificate (EAP-TLS, and very
occasionally PEAP and EAP-TTLS), then some attributes
contains information about the client certificate (if
available).
+```
+# &reply += {
+# &Reply-Message = "%{session-state.TLS-Certificate.Serial}"
+# &Reply-Message = "%{session-state.TLS-Certificate.Not-After}"
+# &Reply-Message = "%{session-state.TLS-Certificate.Subject}"
+# &Reply-Message = "%{session-state.TLS-Certificate.Issuer}"
+# &Reply-Message = "%{session-state.TLS-Certificate.Common-Name}"
+# &Reply-Message = "%{session-state.TLS-Certificate.Subject-Alt-Name-Email}"
+# }
+```
Insert the `link:https://freeradius.org/rfc/rfc2865.html#Class[Class]` attribute with a unique value into the
response, which aids matching auth and acct records and
supports long Class attributes. Many older or cheap
NASes only support 16-octet Class attributes.
+```
+# insert_acct_class
+```
MacSEC requires the use of `EAP-Key-Name`. However, we
don't want to send it for all EAP sessions. Therefore, the
Uncomment the next few lines to copy the required data
into the EAP-Key-Name attribute.
+```
+# if (&reply.EAP-Session-Id) {
+# &reply.EAP-Key-Name := &reply.EAP-Session-Id
+# }
+```
Call an instance of `linelog` to log the authentication success
- equivalent to the previous log `auth = yes` option in v3.
See `mods-enabled/linelog` for message formats and destinations.
+```
+# log_auth_access_accept
+```
Remove `link:https://freeradius.org/rfc/rfc2865.html#Reply-Message[Reply-Message]` if the response contains an
`link:https://freeradius.org/rfc/rfc2869.html#EAP-Message[EAP-Message]` attribute. Some NAS equipment will
notification" packet, which will cause end-user machines to
drop the network connection.
+```
+ remove_reply_message_if_eap
+}
+```
### send Access-Reject packets
processed. But all of the attributes in that list are discarded as
soon as the section is finished.
+```
+send Access-Reject {
+```
Log failed authentications in SQL, too.
+```
+ -sql
+```
Filter out attributes that should not be in
Access-Reject packets.
+```
+ attr_filter.access_reject
+```
Insert an EAP-Failure message if the request was rejected by
policy, instead of from an authentication failure.
+```
+ eap
+```
Call an instance of `linelog` to log the authentication failure
- equivalent to the previous log `auth = yes` option in v3.
See `mods-enabled/linelog` for message formats and destinations.
+```
+# log_auth_access_reject
+```
Remove `link:https://freeradius.org/rfc/rfc2865.html#Reply-Message[Reply-Message]` if the response contains an
`link:https://freeradius.org/rfc/rfc2869.html#EAP-Message[EAP-Message]` attribute. Some NAS equipment will
notification" packet, which will cause end-user machines to
drop the network connection.
+```
+ remove_reply_message_if_eap
+```
Delay sending the `link:https://freeradius.org/rfc/rfc2865.html#Access-Reject[Access-Reject]` packet. This is no
longer automatic as it was in version 3.
+```
+ delay_reject
+}
+```
Accounting
An Accounting-Request packet has been received. Decide which
accounting type to use.
+```
+recv Accounting-Request {
+```
Merge Acct-[Input|Output]-Gigawords and
Acct-[Input-Output]-Octets into a single 64-bit
counter, Acct-[Input|Output]-Octets64.
+```
+# acct_counters64
+```
Ensure that we have a semi-unique identifier for every
request, as many NAS boxes are broken.
+```
+ acct_unique
+```
Read the 'accounting' file.
+```
+ files_accounting
+}
+```
Version 4 allows for sections specific to Acct-Status-Type.
Session start
+```
+accounting Start {
+```
Log traffic to an SQL database.
-See "Accounting Queries" in link:../../../../../../mods-available/sql.adoc[mods-available/sql].
+See "Accounting Queries" in xref:reference:raddb/mods-available/sql.adoc[mods-available/sql].
+```
+ -sql
+```
Refresh leases when we see a start.
pool of IPs are used. Set this in `recv Accounting-Request` so
it is available for all the accounting sections.
+```
+# sqlippool
+}
+```
Session stop
+```
+accounting Stop {
+```
Log traffic to an SQL database.
+```
+ -sql
+```
If you receive stop packets with zero session length,
they will NOT be logged in the database. The SQL
respond to the accounting request, and the NAS will
retransmit.
+```
+# if (noop) {
+# ok
+# }
+```
Return an address to the IP Pool when we see a stop record.
+```
+# sqlippool
+}
+```
Session is still alive
+```
+accounting Interim-Update {
+```
Log traffic to an SQL database.
+```
+ -sql
+```
Refresh leases when we see an alive.
+```
+# sqlippool
+}
+```
The NAS has just booted up.
+```
+accounting Accounting-On {
+```
Record that the NAS has booted to an SQL database
+```
+ -sql
+```
Return all addresses related to this NAS to the IP Pool
+```
+# sqlippool
+}
+```
The NAS is about to go down
+```
+accounting Accounting-Off {
+```
Record that the NAS is shutting down to an SQL database
+```
+ -sql
+```
Return all addresses related to this NAS to the IP Pool
+```
+# sqlippool
+}
+```
Session failed to do something
+```
+accounting Failed {
+}
+```
There are many other values for `link:https://freeradius.org/rfc/rfc2866.html#Acct-Status-Type[Acct-Status-Type]` such as:
the reply will not be sent, which means the NAS will send the
request again.
+```
+send Accounting-Response {
+```
Add the CUI attribute from the corresponding
Access-Accept to the Accounting-Response.
Use it only if your NAS boxes do not support CUI
themselves.
+```
+# cui
+```
Create a 'detail'ed log of the packets. Note that
accounting requests which are proxied are also logged
in the detail file.
+```
+ detail
+```
Update counters for daily usage calculations.
+```
+# daily
-
-For Simultaneous-Use tracking.
-
-Due to packet losses in the network, the data here may
-be incorrect. There is little we can do about it.
-
-
+```
Cisco VoIP specific bulk accounting.
+```
+# pgsql-voip
+```
Filter attributes from the accounting response.
-
-== Default Configuration
-
```
-server default {
- namespace = radius
- radius {
- Access-Request {
- session {
-# max = 4096
-# timeout = 15
- }
- }
- }
- dictionary {
-# uint32 foo
-# tlv bar {
-# uint32 baz
-# string arg
-# }
-# values foo {
-# bar = 1
-# baz = 2
-# }
- }
- listen {
- type = Access-Request
- type = Status-Server
- transport = udp
- require_message_authenticator = auto
- limit_proxy_state = auto
- limit {
- max_clients = 256
- max_connections = 256
- idle_timeout = 60.0
- nak_lifetime = 30.0
- cleanup_delay = 5.0
- }
- udp {
- ipaddr = *
- port = 1812
-# dynamic_clients = true
- networks {
- allow = 127/8
- allow = 192.0.2/24
-# deny = 127.0.0/24
- }
- }
- tcp {
- ipaddr = *
- port = 1812
-# dynamic_clients = true
- networks {
- allow = 127/8
- allow = 192.0.2/24
-# deny = 127.0.0/24
- }
- }
- }
- listen tcp_auth {
- type = Access-Request
- type = Status-Server
- transport = tcp
- tcp {
- ipaddr = *
- port = 1812
-# dynamic_clients = true
- networks {
- allow = 127/8
- allow = 192.0.2/24
-# deny = 127.0.0/24
- }
- }
- }
- listen udp_acct {
- type = Accounting-Request
- transport = udp
- udp {
- ipaddr = *
- port = 1813
- }
- }
- client localhost {
- shortname = sample
- ipaddr = 192.0.2.1
- secret = testing123
- }
-recv Access-Request {
- filter_username
-# filter_password
-# operator-name
-# if (&User-Name =~ /@example\.com$/) {
-# &control.Auth-Type := "proxy-example.com"
-# }
-# cui
-# auth_log
- chap
- mschap
- digest
-# wimax
- eap {
- ok = return
- }
-# unix
- files
- -sql
-# smbpasswd
- -ldap
-# dailycounter
- expiration
- pap
-}
-recv Status-Server {
- ok
-}
-authenticate pap {
- pap
-}
-authenticate chap {
- chap
-}
-authenticate mschap {
- mschap
-}
-authenticate digest {
- digest
-}
-#authenticate pam {
-# pam
-#}
-authenticate ldap {
- -ldap
-}
-authenticate eap {
- eap
-}
-#authenticate proxy-example.com {
-# #
-# # Log the request before proxying.
-# #
-# pre_proxy_log
-# #
-# # Send the request to remote RADIUS servers, with
-# # fail-over from one to the other if there's no response.
-# #
-# redundant {
-# radius1.example.com
-# radius2.example.com
-# radius3.example.com
-# }
-# #
-# # Log the reply after proxying.
-# #
-# post_proxy_log.post-proxy
-#}
-send Access-Challenge {
- attr_filter.access_challenge
- handled
-}
-send Access-Accept {
-# if (!&reply.State) {
-# &reply.State := "0x%randstr(16h)"
-# }
- &reply += &session-state
- eap
-# sqlippool
-# cui
-# reply_log
- -sql
-# ldap
-# &request.WiMAX-MN-NAI = "%{User-Name}"
-# &reply += {
-# &Vendor-Specific.WiMAX = {
-# &FA-RK-Key = 0x00
-# &MSK = &reply.EAP-MSK
-# }
-# }
-# wimax
-# &reply += {
-# &Reply-Message = "%{session-state.TLS-Certificate.Serial}"
-# &Reply-Message = "%{session-state.TLS-Certificate.Not-After}"
-# &Reply-Message = "%{session-state.TLS-Certificate.Subject}"
-# &Reply-Message = "%{session-state.TLS-Certificate.Issuer}"
-# &Reply-Message = "%{session-state.TLS-Certificate.Common-Name}"
-# &Reply-Message = "%{session-state.TLS-Certificate.Subject-Alt-Name-Email}"
-# }
-# insert_acct_class
-# if (&reply.EAP-Session-Id) {
-# &reply.EAP-Key-Name := &reply.EAP-Session-Id
-# }
-# log_auth_access_accept
- remove_reply_message_if_eap
-}
-send Access-Reject {
- -sql
- attr_filter.access_reject
- eap
-# log_auth_access_reject
- remove_reply_message_if_eap
- delay_reject
-}
-recv Accounting-Request {
-# acct_counters64
- acct_unique
- files_accounting
-}
-accounting Start {
- -sql
-# sqlippool
-}
-accounting Stop {
- -sql
-# if (noop) {
-# ok
-# }
-# sqlippool
-}
-accounting Interim-Update {
- -sql
-# sqlippool
-}
-accounting Accounting-On {
- -sql
-# sqlippool
-}
-accounting Accounting-Off {
- -sql
-# sqlippool
-}
-accounting Failed {
-}
-send Accounting-Response {
-# cui
- detail
-# daily
-# unix
-# pgsql-voip
attr_filter.accounting_response
}
}
```
+
+== Default Configuration
+
+```
+```
configurations These references serve as place-holders, and as
documentation. If you need the functionality of that module, then:
- * configure the module in link:../../../../../../mods-available/index.adoc[mods-available/]
+ * configure the module in xref:reference:raddb/mods-available/index.adoc[mods-available/]
* enable the module in `mods-enabled`. e.g. for LDAP, do: `cd mods-enabled;ln -s ../mods-available/ldap`
* un-comment the references to it in this file.
This is the `default` virtual server.
+```
+server default {
+```
namespace::
All of the "listen" sections in this virtual server will
only accept packets for that protocol.
+```
+ namespace = radius
+```
### The listen section
order to make FreeRADIUS more flexible, and to make the
configuration simpler and more consistent.
+```
+ listen {
+```
type:: The type of packet to accept.
configuration was awkward and potentially
confusing.
+```
+ type = Access-Request
+ type = Status-Server
+```
transport:: The transport protocol.
"inner tunnel" portion of PEAP and TTLS. But it
does not accept those packets from the network.
+```
+ transport = udp
+```
limit:: limits for this socket.
Limits are used to prevent "run-away" problems.
+```
+ limit {
+```
max_clients:: The maximum number of dynamic
clients which can be defined for this
(e.g. NAS, AP, etc.) which will be sending
packets to FreeRADIUS.
+```
+ max_clients = 256
+```
max_connections:: The maximum number of
connected sockets which will be accepted
sockets (e.g. TCP), then this configuration
item is ignored.
+```
+ max_connections = 256
+```
idle_timeout:: Time after which idle
connections or dynamic clients are deleted.
Useful range of values: 5 to 600
+```
+ idle_timeout = 60.0
+```
nak_lifetime:: Time for which blacklisted
clients are placed into a NAK cache.
Useful range of values: 1 to 600
+```
+ nak_lifetime = 30.0
+```
cleanup_delay:: The time to wait (in
seconds) before cleaning up a reply to an
Useful range of values: 2 to 30
+```
+ cleanup_delay = 5.0
+ }
+```
#### UDP Transport
subsection contains all of the configuration for
the UDP transport.
+```
+ udp {
+```
ipaddr:: The IP address where FreeRADIUS
accepts packets.
The same as `ipaddr`, but will only use
IPv6 addresses.
+```
+ ipaddr = *
+```
port:: the UDP where FreeRADIUS accepts
packets.
The default port for Access-Accept packets
is `1812`.
+```
+ port = 1812
+```
dynamic_clients:: Whether or not we allow
dynamic clients.
for more information about how dynamic
clients work.
+```
+# dynamic_clients = true
+```
networks:: The list of networks which are
allowed to send packets to FreeRADIUS for
could trigger dynamic clients, then the
server would be subject to a DoS attack.
+```
+ networks {
+```
allow:: Allow packets from these
networks to define dynamic clients.
There is no limit to the number of
networks which can be listed here.
+```
+ allow = 127/8
+ allow = 192.0.2/24
+```
deny:: deny some networks.
they appear in the configuration
file does not matter.
+```
+# deny = 127.0.0/24
+ }
+ }
+```
#### TCP Transport
Since UDP and TCP are similar, the majority of the
configuration items are the same for both of them.
+```
+ tcp {
+```
NOTE: As with v3, `ipaddr`, `ipv4addr`, and `ipv6addr`
are all allowed.
ipaddr::
+```
+ ipaddr = *
+```
port:: the TCP where FreeRADIUS accepts
packets.
The default port for Access-Accept packets
is `1812`.
+```
+ port = 1812
+```
dynamic_clients:: Whether or not we allow dynamic clients.
subsection below. See that section for
more information.
+```
+# dynamic_clients = true
+```
networks { ... }::
If dynamic clients are not allowed, then
this section is ignored.
+```
+ networks {
+```
allow::
deny::
There is no limit to the number of
networks which can be listed here.
+```
+ allow = 127/8
+ allow = 192.0.2/24
+# deny = 127.0.0/24
+ }
+ }
+```
#### Access-Request subsection
packets. At this time, there is no configuration
needed for other packet types.
+```
+ Access-Request {
+```
log:: Logging configuration for `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packets
The extra configuration in v4 allows for
increased flexibility.
+```
+ log {
+```
stripped_names:: Log the full
`link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]` attribute, as it was
allowed values: {no, yes}
+```
+ stripped_names = no
+```
auth:: Log authentication requests
to the log file.
allowed values: {no, yes}
+```
+ auth = no
+```
auth_goodpass:: Log "good"
passwords with the authentication
allowed values: {no, yes}
+```
+ auth_goodpass = no
+```
auth_badpass:: Log "bad"
passwords with the authentication
allowed values: {no, yes}
+```
+ auth_badpass = no
+```
msg_goodpass::
msg_badpass::
this expansion can be slow, and can negatively impact server
performance.
+```
+# msg_goodpass = ""
+# msg_badpass = ""
+```
msg_denied::
The message when the user exceeds the Simultaneous-Use limit.
+```
+ msg_denied = "You are already logged in - access denied"
+ }
+```
session:: Controls how ongoing
(multi-round) sessions are handled
authentication attempts that can occur
concurrently.
+```
+ session {
+```
max:: The maximum number of ongoing sessions
+```
+# max = 4096
+```
timeout:: How long to wait before expiring a
session.
containing the previously sent
state value is received.
+```
+# timeout = 15
+ }
+ }
+ }
+ listen {
+ type = Access-Request
+ type = Status-Server
+ transport = tcp
+ tcp {
+```
As with v3, "ipaddr", "ipv4addr", and "ipv6addr"
are all allowed.
+```
+ ipaddr = *
+ port = 1812
+```
Whether or not we allow dynamic clients.
subsection below. See that section for
more information.
+```
+# dynamic_clients = true
+```
If dynamic clients are allowed, then limit
them to only a small set of source
If dynamic clients are not allowed, then
this section is ignored.
+```
+ networks {
+```
Allow packets from these networks
to define dynamic clients.
There is no limit to the number of
networks which can be listed here.
+```
+ allow = 127/8
+ allow = 192.0.2/24
+# deny = 127.0.0/24
+ }
+ }
+```
#### Access-Request subsection
packets. At this time, there is no configuration
needed for other packet types.
+```
+ Access-Request {
+```
log:: Logging configuration for `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packets
The extra configuration in v4 allows for
increased flexibility.
+```
+ log {
+```
stripped_names:: Log the full
`link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]` attribute, as it was
found in the request.
allowed values: {no, yes}
+```
+ stripped_names = no
+```
auth:: Log authentication requests
to the log file.
allowed values: {no, yes}
+```
+ auth = no
+```
auth_goodpass:: Log "good"
passwords with the authentication
requests.
allowed values: {no, yes}
+```
+ auth_badpass = no
+```
auth_badpass:: Log "bad"
passwords with the authentication
requests.
allowed values: {no, yes}
+```
+ auth_goodpass = no
+```
Log additional text at the end of the "Login OK" messages.
for these to work, the "auth" and "auth_goodpass" or "auth_badpass"
configurations above have to be set to "yes".
this expansion can be slow, and can negatively impact server
performance.
+```
+# msg_goodpass = ""
+# msg_badpass = ""
+```
The message when the user exceeds the Simultaneous-Use limit.
+```
+ msg_denied = "You are already logged in - access denied"
+ }
+```
session:: Controls how ongoing
(multi-round) sessions are handled
authentication attempts that can occur
concurrently.
+```
+ session {
+```
max:: The maximum number of ongoing sessions
+```
+# max = 4096
+```
timeout:: How long to wait before expiring a
session.
containing the previously sent
state value is received.
+```
+# timeout = 15
+ }
+ }
+ }
+```
### Listen for Accounting-Request packets
+```
+ listen {
+ type = Accounting-Request
+ transport = udp
+ udp {
+ ipaddr = *
+ port = 1813
+ }
+ }
+```
### Local Clients
The clients listed here take precedence over the global
clients.
+```
+ client localhost {
+ shortname = sample
+ ipaddr = 192.0.2.1
+ secret = testing123
+```
The other "client" configuration items can be added
here, too.
+```
+ }
+```
## Packet Processing sections
### Receive Access-Request packets
+```
+recv Access-Request {
+```
+```
+ map csv "%{User-Name}" {
+ &reply:Filter-Id := field3
+ &reply:Reply-Message := field4
+ }
+```
Take a `link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]`, and perform some checks on it, for
spaces and other invalid characters. If the `link:https://freeradius.org/rfc/rfc2865.html#User-Name[User-Name]`
See policy.d/filter for the definition of the
filter_username policy.
+```
+ filter_username
+```
Some broken equipment sends passwords with embedded
zeros, i.e. the debug output will show:
This policy will fix the password to just be "password".
+```
+# filter_password
+```
If you intend to use CUI and you require that the
Operator-Name be set for CUI generation and you want to
operator-name below and set the operator-name for
your clients in clients.conf.
+```
+# operator-name
+```
Proxying example
The following example will proxy the request if the
username ends in example.com.
+```
+# if (&User-Name =~ /@example\.com$/) {
+# update control {
+# &Auth-Type := "proxy-example.com"
+# }
+# }
+```
If you want to generate CUI for some clients that do
not send proper CUI requests, then uncomment cui below
and set "add_cui = yes" for these clients in
clients.conf.
+```
+# cui
+```
The `auth_log` module will write all `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packets to a file.
Uncomment the next bit in order to have a log of
authentication requests. For more information, see
-link:../../../../../../mods-available/detail.log.adoc[mods-available/detail.log].
+xref:reference:raddb/mods-available/detail.log.adoc[mods-available/detail.log].
+```
+# auth_log
+```
The `chap` module will set `Auth-Type := CHAP` if the
packet contains a `link:https://freeradius.org/rfc/rfc2865.html#CHAP-Challenge[CHAP-Challenge]` attribute. The module
does this only if the `Auth-Type` attribute has not already
been set.
+```
+ chap
+```
The `mschap` module will set `Auth-Type := mschap` if the
packet contains an `link:https://freeradius.org/rfc/rfc2548.html#MS-CHAP-Challenge[MS-CHAP-Challenge]` attribute. The
module does this only if the `Auth-Type` attribute has not
already been set.
+```
+ mschap
+```
The `digest` module implements the SIP Digest
authentication method.
"Digest"` if we are handling an SIP Digest request and the
`Auth-Type` has not already been set.
+```
+ digest
+```
The `wimax` module fixes up various WiMAX-specific stupidities.
`link:https://freeradius.org/rfc/rfc2865.html#Calling-Station-Id[Calling-Station-Id]` attribute to the normal format as
specified in https://tools.ietf.org/html/rfc3580#section-3.21.[RFC 3580 Section 3.21.]
+```
+# wimax
+```
The `eap` module takes care of all EAP authentication,
including EAP-MD5, EAP-TLS, PEAP and EAP-TTLS.
We also recommend doing user lookups in the `inner-tunnel`
virtual server.
+```
+ eap {
+ ok = return
+ }
+```
The `unix` module will obtain passwords from `/etc/passwd`
or `/etc/shadow`. It does this via the system API's, which
are not thread-safe. We do not recommend using the `unix` module.
+```
+# unix
+```
Read what used to be the `users` file. Since v3, this file
is located in `mods-config/files/authorize`.
+```
+ files
+```
Look in an SQL database. The schema of the database is
meant to mirror the `users` file. For a full description
of the module behavior, please see
https://wiki.freeradius.org/modules/Rlm_sql
+```
+ -sql
+```
If you are using /etc/smbpasswd, and are also doing mschap
authentication, the un-comment this line, configure the
module.
-
+```
+# smbpasswd
+
+```
The `ldap` module reads passwords and other attributes from
an LDAP database.
For a full description of the module behavior, please see
https://wiki.freeradius.org/modules/Rlm_ldap
+```
+ -ldap
+```
Enforce daily limits on time spent logged in. This module
is a variant of the the `counter` module.
+```
+# daily
+```
See if the account has expired: check the time in the
`Expiration` attribute and reject if we are past it.
If the account has not expired, set `link:https://freeradius.org/rfc/rfc2865.html#Session-Timeout[Session-Timeout]`.
+```
+ expiration
+```
Look at the `Login-Time` attribute and reject if the user
is not allowed access at the present time. Otherwise,
set `link:https://freeradius.org/rfc/rfc2865.html#Session-Timeout[Session-Timeout]` to the end of the permitted time span.
+```
+ logintime
+```
The `pap` module will set `Auth-Type := PAP` if the
packet contains a `link:https://freeradius.org/rfc/rfc2865.html#User-Password[User-Password]` attribute. The module
This module should be listed last, so that the other
modules get a chance to set Auth-Type for themselves.
+```
+ pap
+}
+```
### Receive Status-Server packets
This section is processed when the server receives a `Status-Server`
packet.
+```
+recv Status-Server {
+```
We are still here and responding.
+```
+ ok
+}
+```
## Authentication Sections
good" password for the user. The password can be clear-text, or
encrypted via `crypt`, `bcrypt`, or other hashing.
+```
+authenticate pap {
+ pap
+}
+```
### CHAP Authentication
listed in the "recv Access-Request" section MUST supply a
Cleartext-Password attribute. Encrypted passwords won't work.
+```
+authenticate chap {
+ chap
+}
+```
### MS-CHAP authentication
either a Cleartext-Password attribute, or an NT-Password
attribute. Encrypted passwords won't work.
+```
+authenticate mschap {
+ mschap
+}
+```
### SIP Digest Authentication
The `digest` line in the `recv Access-Request` section should also
be uncommented.
+```
+authenticate digest {
+ digest
+}
+```
## PAM (Pluggable Authentication Modules) Authentication
that anything that can be done in PAM can be done easier in
FreeRADIUS.
+```
+#authenticate pam {
+# pam
+#}
+```
### LDAP Authentication
section. And, ensuring that the account used by FreeRADIUS has
read permission on all of the users, groups, and passwords.
+```
+authenticate ldap {
+ -ldap
+}
+```
EAP Authentication
For EAP-MD5, EAP-MSCHAP, EAP-TLS, EAP-TTLS, EAP-PEAP, EAP-PWD, etc.
+```
+authenticate eap {
+ eap
+}
+```
### Proxying
The `Auth-Type` attribute would need to be set to
`proxy-example.com`. The home servers MUST be defined in
-link:../../../../../../mods-available/radius.adoc[mods-available/radius].
+xref:reference:raddb/mods-available/radius.adoc[mods-available/radius].
+```
+#authenticate proxy-example.com {
+# #
+# # Log the request before proxying.
+# #
+# pre_proxy_log
+```
+```
+# #
+# # Send the request to remote RADIUS servers, with
+# # fail-over from one to the other if there's no response.
+# #
+# redundant {
+# radius1.example.com
+# radius2.example.com
+# radius3.example.com
+# }
+```
+```
+# #
+# # Log the reply after proxying.
+# #
+# post_proxy_log.post-proxy
+#}
+```
## Send replies to Access-Request packets
response. It is configured to filter out all attributes that should
not be in the packet.
+```
+send Access-Challenge {
+ attr_filter.access_challenge.post-auth
+ handled
+}
+```
### send Access-Accept packets
Once we know that the user has been authenticated successfully,
there are additional things that can be done.
+```
+send Access-Accept {
+```
If you need to have a State attribute, you can add it
here. e.g. for later CoA-Request with State, and
Service-Type = Authorize-Only.
+```
+# if (!&reply:State) {
+# update reply {
+# &State := "0x%{randstr:16h}"
+# }
+# }
+```
For EAP-TTLS and PEAP, add any cached attributes to the
reply. The "session-state" attributes are automatically
The `session-state` attributes are deleted after an
`link:https://freeradius.org/rfc/rfc2865.html#Access-Reject[Access-Reject]` or `link:https://freeradius.org/rfc/rfc2865.html#Access-Accept[Access-Accept]` packet has been sent.
+```
+ update {
+ &reply: += &session-state:
+ }
+```
For EAP, ensure that the Access-Accept contains a User-Name
attribute.
+```
+ eap
+```
Get an address from the IP Pool.
+```
+# main_pool
+```
Create the CUI value and add the attribute to
Access-Accept. Uncomment the line below if
*returning* the CUI to the NAS.
+```
+# cui
+```
If you want to have a log of authentication replies,
un-comment the following line. This is defined in
-link:../../../../../../mods-available/detail.log.adoc[mods-available/detail.log].
+xref:reference:raddb/mods-available/detail.log.adoc[mods-available/detail.log].
+```
+# reply_log
+```
After authenticating the user, do another SQL query.
+```
+ -sql
+```
Instead of sending the query to the SQL server in
real-time, write it into a log file to be picked up and
sent to the database later.
+```
+# sql_log
+```
Un-comment the following if you want to modify the
user's object in LDAP after a successful login.
+```
+# ldap
+```
Calculate the various WiMAX keys. In order for this to
work, you will need to define the WiMAX NAI, usually
via:
+```
+# update request {
+# WiMAX-MN-NAI = "%{User-Name}"
+# }
+```
If you want various keys to be calculated, you will
need to update the reply with "template" values. The
module will see this, and replace the template values
with the correct ones taken from the cryptographic
calculations, e.g.
+```
+# update reply {
+# WiMAX-FA-RK-Key = 0x00
+# WiMAX-MSK = "%{EAP-MSK}"
+# }
+```
You may want to delete the `MS-MPPE-*-Keys` from the
reply, as some WiMAX clients behave badly when those
attributes are included. See the configuration entry
-`delete_mppe_keys` in link:../../../../../../mods-available/wimax.adoc[mods-available/wimax] for
+`delete_mppe_keys` in xref:reference:raddb/mods-available/wimax.adoc[mods-available/wimax] for
more information.
+```
+# wimax
+```
If there is a client certificate (EAP-TLS, and very
occasionally PEAP and EAP-TTLS), then some attributes
contains information about the client certificate (if
available).
+```
+# update reply {
+# &Reply-Message += "%{session-state:TLS-Cert-Serial}"
+# &Reply-Message += "%{session-state:TLS-Cert-Expiration}"
+# &Reply-Message += "%{session-state:TLS-Cert-Subject}"
+# &Reply-Message += "%{session-state:TLS-Cert-Issuer}"
+# &Reply-Message += "%{session-state:TLS-Cert-Common-Name}"
+# &Reply-Message += "%{session-state:TLS-Cert-Subject-Alt-Name-Email}"
+```
+```
+# &Reply-Message += "%{session-state:TLS-Client-Cert-Serial}"
+# &Reply-Message += "%{session-state:TLS-Client-Cert-Expiration}"
+# &Reply-Message += "%{session-state:TLS-Client-Cert-Subject}"
+# &Reply-Message += "%{session-state:TLS-Client-Cert-Issuer}"
+# &Reply-Message += "%{session-state:TLS-Client-Cert-Common-Name}"
+# &Reply-Message += "%{session-state:TLS-Client-Cert-Subject-Alt-Name-Email}"
+# }
+```
Insert the `link:https://freeradius.org/rfc/rfc2865.html#Class[Class]` attribute with a unique value into the
response, which aids matching auth and acct records and
supports long Class attributes. Many older or cheap
NASes only support 16-octet Class attributes.
+```
+# insert_acct_class
+```
MacSEC requires the use of `EAP-Key-Name`. However, we
don't want to send it for all EAP sessions. Therefore, the
Uncomment the next few lines to copy the required data
into the EAP-Key-Name attribute.
+```
+# if (&reply:EAP-Session-Id) {
+# update reply {
+# &EAP-Key-Name := &reply:EAP-Session-Id
+# }
+# }
+```
Remove `link:https://freeradius.org/rfc/rfc2865.html#Reply-Message[Reply-Message]` if the response contains an
`link:https://freeradius.org/rfc/rfc2869.html#EAP-Message[EAP-Message]` attribute. Some NAS equipment will
notification" packet, which will cause end-user machines to
drop the network connection.
+```
+ remove_reply_message_if_eap
+}
+```
### send Access-Reject packets
processed. But all of the attributes in that list are discarded as
soon as the section is finished.
+```
+send Access-Reject {
+```
Log failed authentications in SQL, too.
+```
+ -sql
+```
Filter out attributes that should not be in
Access-Reject packets.
+```
+ attr_filter.access_reject
+```
Insert an EAP-Failure message if the request was rejected by
policy, instead of from an authentication failure.
+```
+ eap
+```
Remove `link:https://freeradius.org/rfc/rfc2865.html#Reply-Message[Reply-Message]` if the response contains an
`link:https://freeradius.org/rfc/rfc2869.html#EAP-Message[EAP-Message]` attribute. Some NAS equipment will
notification" packet, which will cause end-user machines to
drop the network connection.
+```
+ remove_reply_message_if_eap
+```
Delay sending the `link:https://freeradius.org/rfc/rfc2865.html#Access-Reject[Access-Reject]` packet. This is no
longer automatic as it was in version 3.
+```
+ delay_reject
+}
+```
Accounting
An Accounting-Request packet has been received. Decide which
accounting type to use.
+```
+recv Accounting-Request {
+```
Merge Acct-[Input|Output]-Gigawords and
Acct-[Input-Output]-Octets into a single 64-bit
counter, Acct-[Input|Output]-Octets64.
+```
+# acct_counters64
+```
Session start times are *implied* in RADIUS. The NAS
never sends a "start time". Instead, it sends a start
The start time is: NOW - delay - session_length
+```
+# update request {
+# &FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}"
+# }
+```
Ensure that we have a semi-unique identifier for every
request, as many NAS boxes are broken.
+```
+ acct_unique
+```
Read the 'acct_users' file.
+```
+ files
+}
+```
Version 4 allows for sections specific to Acct-Status-Type.
Session start
+```
+accounting Start {
+}
+```
Session stop
+```
+accounting Stop {
+}
+```
Session is still alive
+```
+accounting Alive {
+}
+```
The NAS has just booted up.
+```
+accounting Accounting-On {
+}
+```
The NAS is about to go down
+```
+accounting Accounting-Off {
+}
+```
Session failed to do something
+```
+accounting Failed {
+}
+```
There are many other values for `link:https://freeradius.org/rfc/rfc2866.html#Acct-Status-Type[Acct-Status-Type]` such as:
the reply will not be sent, which means the NAS will send the
request again.
+```
+send Accounting-Response {
+```
Add the CUI attribute from the corresponding
Access-Accept to the Accouning-Response.
Use it only if your NAS boxes do not support CUI
themselves.
+```
+# cui
+```
Create a 'detail'ed log of the packets. Note that
accounting requests which are proxied are also logged
in the detail file.
+```
+ detail
+```
Update counters for daily usage calculations.
+```
+# daily
+```
Update the wtmp file.
If you don't use "radlast", you can delete this line.
+```
+ unix
+```
For Simultaneous-Use tracking.
Due to packet losses in the network, the data here may
be incorrect. There is little we can do about it.
+```
+# radutmp
+# sradutmp
+```
Return an address to the IP Pool when we see a stop
record.
+```
+# main_pool
+
+```
-
Log traffic to an SQL database.
-See "Accounting Queries" in link:../../../../../../mods-available/sql.adoc[mods-available/sql].
+See "Accounting Queries" in xref:reference:raddb/mods-available/sql.adoc[mods-available/sql].
+```
+ -sql
+```
If you receive stop packets with zero session length,
they will NOT be logged in the database. The SQL
respond to the accounting request, and the NAS will
retransmit.
+```
+# if (noop) {
+# ok
+# }
+```
Instead of sending the query to the SQL server in
real-time, write it into a log file to be picked up and
sent to the database later.
+```
+# sql_log
+```
Cisco VoIP specific bulk accounting.
+```
+# pgsql-voip
+```
Filter attributes from the accounting response.
-
-== Default Configuration
-
```
-server default {
- namespace = radius
- listen {
- type = Access-Request
- type = Status-Server
- transport = udp
- limit {
- max_clients = 256
- max_connections = 256
- idle_timeout = 60.0
- nak_lifetime = 30.0
- cleanup_delay = 5.0
- }
- udp {
- ipaddr = *
- port = 1812
-# dynamic_clients = true
- networks {
- allow = 127/8
- allow = 192.0.2/24
-# deny = 127.0.0/24
- }
- }
- tcp {
- ipaddr = *
- port = 1812
-# dynamic_clients = true
- networks {
- allow = 127/8
- allow = 192.0.2/24
-# deny = 127.0.0/24
- }
- }
- Access-Request {
- log {
- stripped_names = no
- auth = no
- auth_goodpass = no
- auth_badpass = no
-# msg_goodpass = ""
-# msg_badpass = ""
- msg_denied = "You are already logged in - access denied"
- }
- session {
-# max = 4096
-# timeout = 15
- }
- }
- }
- listen {
- type = Access-Request
- type = Status-Server
- transport = tcp
- tcp {
- ipaddr = *
- port = 1812
-# dynamic_clients = true
- networks {
- allow = 127/8
- allow = 192.0.2/24
-# deny = 127.0.0/24
- }
- }
- Access-Request {
- log {
- stripped_names = no
- auth = no
- auth_badpass = no
- auth_goodpass = no
-# msg_goodpass = ""
-# msg_badpass = ""
- msg_denied = "You are already logged in - access denied"
- }
- session {
-# max = 4096
-# timeout = 15
- }
- }
- }
- listen {
- type = Accounting-Request
- transport = udp
- udp {
- ipaddr = *
- port = 1813
- }
- }
- client localhost {
- shortname = sample
- ipaddr = 192.0.2.1
- secret = testing123
- }
-recv Access-Request {
- map csv "%{User-Name}" {
- &reply:Filter-Id := field3
- &reply:Reply-Message := field4
- }
- filter_username
-# filter_password
-# operator-name
-# if (&User-Name =~ /@example\.com$/) {
-# update control {
-# &Auth-Type := "proxy-example.com"
-# }
-# }
-# cui
-# auth_log
- chap
- mschap
- digest
-# wimax
- eap {
- ok = return
- }
-# unix
- files
- -sql
-# smbpasswd
- -ldap
-# daily
- expiration
- logintime
- pap
-}
-recv Status-Server {
- ok
-}
-authenticate pap {
- pap
-}
-authenticate chap {
- chap
-}
-authenticate mschap {
- mschap
-}
-authenticate digest {
- digest
-}
-#authenticate pam {
-# pam
-#}
-authenticate ldap {
- -ldap
-}
-authenticate eap {
- eap
-}
-#authenticate proxy-example.com {
-# #
-# # Log the request before proxying.
-# #
-# pre_proxy_log
-# #
-# # Send the request to remote RADIUS servers, with
-# # fail-over from one to the other if there's no response.
-# #
-# redundant {
-# radius1.example.com
-# radius2.example.com
-# radius3.example.com
-# }
-# #
-# # Log the reply after proxying.
-# #
-# post_proxy_log.post-proxy
-#}
-send Access-Challenge {
- attr_filter.access_challenge.post-auth
- handled
-}
-send Access-Accept {
-# if (!&reply:State) {
-# update reply {
-# &State := "0x%{randstr:16h}"
-# }
-# }
- update {
- &reply: += &session-state:
- }
- eap
-# main_pool
-# cui
-# reply_log
- -sql
-# sql_log
-# ldap
-# update request {
-# WiMAX-MN-NAI = "%{User-Name}"
-# }
-# update reply {
-# WiMAX-FA-RK-Key = 0x00
-# WiMAX-MSK = "%{EAP-MSK}"
-# }
-# wimax
-# update reply {
-# &Reply-Message += "%{session-state:TLS-Cert-Serial}"
-# &Reply-Message += "%{session-state:TLS-Cert-Expiration}"
-# &Reply-Message += "%{session-state:TLS-Cert-Subject}"
-# &Reply-Message += "%{session-state:TLS-Cert-Issuer}"
-# &Reply-Message += "%{session-state:TLS-Cert-Common-Name}"
-# &Reply-Message += "%{session-state:TLS-Cert-Subject-Alt-Name-Email}"
-# &Reply-Message += "%{session-state:TLS-Client-Cert-Serial}"
-# &Reply-Message += "%{session-state:TLS-Client-Cert-Expiration}"
-# &Reply-Message += "%{session-state:TLS-Client-Cert-Subject}"
-# &Reply-Message += "%{session-state:TLS-Client-Cert-Issuer}"
-# &Reply-Message += "%{session-state:TLS-Client-Cert-Common-Name}"
-# &Reply-Message += "%{session-state:TLS-Client-Cert-Subject-Alt-Name-Email}"
-# }
-# insert_acct_class
-# if (&reply:EAP-Session-Id) {
-# update reply {
-# &EAP-Key-Name := &reply:EAP-Session-Id
-# }
-# }
- remove_reply_message_if_eap
-}
-send Access-Reject {
- -sql
- attr_filter.access_reject
- eap
- remove_reply_message_if_eap
- delay_reject
-}
-recv Accounting-Request {
-# acct_counters64
-# update request {
-# &FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}"
-# }
- acct_unique
- files
-}
-accounting Start {
-}
-accounting Stop {
-}
-accounting Alive {
-}
-accounting Accounting-On {
-}
-accounting Accounting-Off {
-}
-accounting Failed {
-}
-send Accounting-Response {
-# cui
- detail
-# daily
- unix
-# radutmp
-# sradutmp
-# main_pool
- -sql
-# if (noop) {
-# ok
-# }
-# sql_log
-# pgsql-voip
attr_filter.accounting_response
}
}
```
+
+== Default Configuration
+
+```
+```
-
-
-
-
-If no other module has claimed responsibility for
-authentication, then try to use PAP. This allows the
-
-
-If no other module has claimed responsibility for
-authentication, then try to use PAP. This allows the
-in the 'authorize' section supplies a password. The
-password can be clear-text, or encrypted.
-
-
-in the 'authorize' section supplies a password. The
-password can be clear-text, or encrypted.
-
-
-
-== Default Configuration
-
```
***************
*** 86,91 ****
port = 1812
}
}
+
--- 86,92 ----
udp {
ipaddr = *
+ cleanup_delay = 30
}
}
+
***************
*** 227,232 ****
expiration
logintime
+
+```
+
+If no other module has claimed responsibility for
+authentication, then try to use PAP. This allows the
+```
--- 228,237 ----
expiration
logintime
+
+ update control {
+ Cleartext-Password := "bob"
+ }
+
+```
+
+If no other module has claimed responsibility for
+authentication, then try to use PAP. This allows the
+```
***************
*** 277,283 ****
+```
+in the 'authorize' section supplies a password. The
+password can be clear-text, or encrypted.
+```
authenticate pap {
- pap
}
+
+```
+
+```
--- 282,308 ----
+```
+in the 'authorize' section supplies a password. The
+password can be clear-text, or encrypted.
+```
authenticate pap {
+ if (!Proxy-State) {
+ fork Access-Request {
+ # do_not_respond
+ }
}
+
+```
+
+```
+
+== Default Configuration
+
+```
```
}
```
+
+== Default Configuration
+
+```
+```
+```
+# This virtual server gives an example of reading the detail
+# file for the v4 configuration.
+```
+```
+server detail {
+```
In v4, all "server" sections MUST start with a "namespace"
parameter. This tells the server which protocol is being used.
RADIUS, or DHCPv4, or any other protocol supported by the server.
+```
+ namespace = radius
+```
This virtual server will read detail files from the
following directory.
+```
+ directory = ${radacctdir}/detail
+```
The "listen" section MUST have a second name here, which
says "load the detail file processor, and not the typical
RADIUS UDP / TCP socket IO.
+```
+ listen detail {
+```
Overrides the default transport prefix set by
namespace and loads the detail reader code.
+```
+ proto = detail
+```
Types of packets we are reading.
+```
+ type = Accounting-Request
+```
There is no need to specify a transport.
The default is `file`, which is the only
Setting it to "65536" means "higher priority than
Access-Request packet"
+```
+# priority = 1
+```
Check for the existence of detail files.
You MUST also configure a "work" subsection below.
+```
+ file {
+```
The wildcard to use for finding detail files
+```
+ filename = "${...directory}/detail-*"
+```
If there are no detail files in the directory,
the listener will periodically wake up to check
a non-zero value.
Allowed values: 0 to 3600
+```
+ poll_interval = 5
+ }
+```
Configuration related to processing the
"detail.work" file.
This MUST also be specified, along with the "file"
subsection above.
+```
+ work {
+```
The name of the current working file. If
omitted, it is the directory from the
The best way to enforce that is to give the
the files different prefixes.
+```
+ filename = "${...directory}/detail.work"
+```
Track progress through the detail file. When the detail
file is large, and the server is restarted, it will
Setting `track = yes` means it will skip packets which
have already been processed. The default is `no`.
+```
+ track = yes
+```
The maximum size (in bytes) of one entry in
the detail file. If this setting is too
low, then the "too large" entries in the
detail file will be ignored.
+```
+ max_entry_size = 65536
+```
Whether or not the detail.work file reader
retransmits packets which have failed.
default = yes
+```
+ retransmit = yes
+```
Limits for the files, retransmissions, etc.
+```
+ limit {
+```
Number of simultaneous packets it
will read from the file and feed
into the server core.
Useful values: 1..256
+```
+ max_outstanding = 1
+```
Initial retransmit time: 1..60
If there is no response within this time,
the module will retransmit the packet.
+```
+ initial_rtx_time = 1
+```
Maximum Retransmit Time: 5..30
The maximum time between retransmissions.
+```
+ max_rtx_time = 30
+```
The following are maximums that *all* apply.
i.e. if any one of the limits is hit, the
A special value of "0" means "retransmit forever".
+```
+ max_rtx_count = 6
+```
Maximum Retransmit Duration: 0..600
A special value of "0" means "retransmit forever".
+```
+ max_rtx_duration = 40
+ }
+ }
+ }
+```
The detail file reader runs the normal RADIUS / DHCP / etc. processing sections.
+```
+recv Accounting-Request {
+```
If there's an Acct-Delay-Time, increase its value based on the
difference between when the packet was written, and the current time.
Note that we do NOT rely on any Event-Timestamp in the original packet,
it could be wrong.
+```
+ if (&Acct-Delay-Time) {
+ &Acct-Delay-Time += %l - &Packet-Original-Timestamp
+ }
+ if (!&Event-Timestamp) {
+ &Event-Timestamp := &Packet-Original-Timestamp
+ }
+```
We handled the packet successfully. Run the "send ok" section.
+```
+ ok
+```
If the "recv" section returns "ok" or "updated", it
will run the "send ok" section to send the reply.
All other return codes (e.g. "fail") will cause it to run
the "send fail" section.
+```
+}
+```
If the listener is configured with 'track = yes', then the entry in
the detail file is marked up as being "done". Subsequent re-reads
of the same detail file (e.g. on server restart) will skip the
"done" entries.
+```
+send Accounting-Response {
+ ok
+}
+```
All failed packets sent by the detail listener should be processed
through the 'send Do-Not-Respond' section.
returns "success". See the "limit" subsection above for retransmission
configuration.
-
-== Default Configuration
-
```
-# This virtual server gives an example of reading the detail
-# file for the v4 configuration.
-server detail {
- namespace = radius
- directory = ${radacctdir}/detail
- listen detail {
- proto = detail
- type = Accounting-Request
-# priority = 1
- file {
- filename = "${...directory}/detail-*"
- poll_interval = 5
- }
- work {
- filename = "${...directory}/detail.work"
- track = yes
- max_entry_size = 65536
- retransmit = yes
- limit {
- max_outstanding = 1
- initial_rtx_time = 1
- max_rtx_time = 30
- max_rtx_count = 6
- max_rtx_duration = 40
- }
- }
- }
-recv Accounting-Request {
- if (&Acct-Delay-Time) {
- &Acct-Delay-Time += %l - &Packet-Original-Timestamp
- }
- if (!&Event-Timestamp) {
- &Event-Timestamp := &Packet-Original-Timestamp
- }
- ok
-}
-send Accounting-Response {
- ok
-}
send Do-Not-Respond {
ok
}
} # virtual server "detail"
```
+
+== Default Configuration
+
+```
+```
+```
+# This is a virtual server that handles DHCP.
+```
See raddb/mods-available/sqlippool for the IP Pool configuration.
The DHCP functionality goes into a virtual server.
+```
+server dhcp {
+ namespace = dhcpv4
+```
Define a DHCP socket.
The default port below is 6700, so you don't break your network.
listen section to an interface. You will also need one listen
section per interface.
+```
+listen {
+ type = Discover
+ type = Request
+ type = Inform
+ type = Release
+ type = Decline
+ transport = udp
+ udp {
+```
IP address to listen on. Will usually be the IP of the
interface, or 0.0.0.0
+```
+ ipaddr = 127.0.0.1
+```
The port should be 67 for a production network. Don't set
it to 67 on a production network unless you really know
what you're doing. Even if nothing is configured below, the
server may still NAK legitimate responses from clients.
This is also the destination port when sending to a giaddr.
+```
+ port = 6700
+```
The port to which server -> client messages should be sent.
This should be 68 on a production network, though other ports
can be useful for testing.
If this is not set then server -> client replies will be sent
to the source port of the client -> server request.
+```
+ client_port = 68
+```
Interface name we are listening on. See comments above.
+```
+# interface = lo0
+```
source IP address for unicast packets sent by the
DHCP server.
ipaddr
reply.Server-Identifier
+```
+# src_ipaddr = 127.0.0.1
+```
The DHCP server defaults to allowing broadcast packets.
Set this to "no" only when the server receives *all* packets
from a relay agent. i.e. when *no* clients are on the same
It's set to "no" here for testing. It will usually want to
be "yes" in production, unless you are only dealing with
relayed packets.
+```
+ broadcast = no
+```
On Linux if you're running the server as non-root, you
will need to do:
This will allow the server to set ARP table entries
for newly allocated IPs
+```
+ }
+}
+```
If there is no `client` entry in a DHCPv4 virtual server, it will
automatically create and use a "0/0" client.
user machines, along with all DHCPv4 gateways that send packets to
the server.
+```
+#client private {
+```
ipaddr = 192.168.0.0/16
+```
+#}
+```
Packets received on the socket will be processed through one
of the following sections, named after the DHCP packet type.
See dictionary.dhcpv4 for the packet types.
At least one of these attributes should be set at the end of each
section for a response to be sent.
+```
+recv Discover {
+```
The DHCP Server Identifier is set here since it is returned in OFFERs
+```
+ &control.Server-Identifier = 192.0.2.1
+```
Call a policy (defined in policy.d/dhcp) to set common reply attributes
+```
+ dhcp_common
+```
Do a simple mapping of MAC to assigned IP.
See below for the definition of the "mac2ip"
module.
+```
+# mac2ip
+```
If the MAC wasn't found in that list, do something else.
You could call a Perl, Python, or Java script here.
Or, allocate IPs from the DHCP pool in SQL. You may need to
set the pool name here if you haven't set it elsewhere.
+```
+# &control.IP-Pool.Name := "local"
+# sqlippool
+```
Set the type of packet to send in reply.
The server will look at the Message-Type attribute to
server will fall back to determining the type of reply
based on the rcode of this section.
+```
+# &reply.Message-Type = Offer
+```
If Message-Type is not set, returning "ok" or
"updated" from this section will respond with a Offer
message.
Other rcodes will tell the server to not return any response.
+```
+# ok
+}
+recv Request {
+ files_dhcp
+```
The DHCP Server Identifier is set here since it is returned in OFFERs
+```
+ &control.Server-Identifier = 192.0.2.1
+```
If the request is not for this server then silently discard it
+```
+ if (&request.Server-Identifier && \
+ &request.Server-Identifier != &control.Server-Identifier) {
+ do_not_respond
+ }
+```
Response packet type. See Discover section above.
+```
+# &reply.Message-Type = Ack
+```
Call a policy (defined in policy.d/dhcp) to set common reply attributes
+```
+ dhcp_common
+```
Do a simple mapping of MAC to assigned IP.
See below for the definition of the "mac2ip"
module.
+```
+# mac2ip
+```
If the MAC wasn't found in that list, do something else.
You could call a Perl, Python, or Java script here.
Or, allocate IPs from the DHCP pool in SQL. You may need to
set the pool name here if you haven't set it elsewhere.
+```
+# &control.IP-Pool.Name := "local"
+# sqlippool
+ if (ok) {
+ &reply.Your-IP-Address := "%{&request.Requested-IP-Address || &request.Client-IP-Address}"
+ }
+```
If Message-Type is not set, returning "ok" or
"updated" from this section will respond with a Ack
packet.
"handled" will not return a packet, all other rcodes will
send back a NAK.
+```
+# ok
+}
+```
Other DHCP packet types
By default this configuration will ignore them all. Any packet type
not defined here will be responded to with a NAK.
+```
+recv Decline {
+```
If using IPs from a DHCP pool in SQL then you may need to set the
pool name here if you haven't set it elsewhere and mark the IP as declined.
+```
+# &control.IP-Pool.Name := "local"
+# sqlippool
+ ok
+}
+```
A dummy config for Inform packets - this should match the
options set in the Request section above, except Inform replies
must not set Your-IP-Address or IP-Address-Lease-Time
+```
+recv Inform {
+```
Call a policy (defined in policy.d/dhcp) to set common reply attributes
+```
+ dhcp_common
+ ok
+}
+```
For Windows 7 boxes
+```
+#recv Inform {
+# &reply.Net.Dst.Port = 67
+# &reply.Message-Type = Ack
+# &reply.Server-Identifier = "%{Net.Dst.IP}"
+# &reply.Site-specific-28 = 0x0a00
+# ok
+#}
+recv Release {
+```
If using IPs from a DHCP pool in SQL then you may need to set the
pool name here if you haven't set it elsewhere and release the IP.
+```
+# &control.IP-Pool.Name := "local"
+# sqlippool
+ ok
+}
+recv Lease-Query {
+```
The thing being queried for is implicit
in the packets.
has MAC, asking for IP, etc.
+```
+ if (&Client-Hardware-Address) {
+```
look up MAC in database
+```
+ }
+```
has IP, asking for MAC, etc.
+```
+ elsif (&Your-IP-Address) {
+```
look up IP in database
+```
+ }
+```
has host name, asking for IP, MAC, etc.
+```
+ elsif (&Client-Identifier) {
+```
look up identifier in database
+```
+ }
+ else {
+ &reply.Message-Type = Lease-Unknown
+ ok
+```
stop processing
+```
+ return
+ }
+```
We presume that the database lookup returns "notfound"
if it can't find anything.
+```
+ if (notfound) {
+ &reply.Message-Type = Lease-Unknown
+ ok
+ return
+ }
+```
Add more logic here. Is the lease inactive?
If so, respond with Lease-Unassigned.
Lease-Active
Lease-Unassigned
+```
+ &reply.Message-Type = Lease-Unassigned
+}
+}
+```
This next section is a sample configuration for the "passwd"
module, that reads flat-text files. It should go into
The file is in the format <mac>,<ip>
+```
+# 00:01:02:03:04:05,192.0.2.100
+# 01:01:02:03:04:05,192.0.2.101
+# 02:01:02:03:04:05,192.0.2.102
+```
This lets you perform simple static IP assignment.
This is an example only - see mods-available/mac2ip instead; do
not uncomment these lines here.
-
-== Default Configuration
-
```
-# This is a virtual server that handles DHCP.
-server dhcp {
- namespace = dhcpv4
-listen {
- type = Discover
- type = Request
- type = Inform
- type = Release
- type = Decline
- transport = udp
- udp {
- ipaddr = 127.0.0.1
- port = 6700
- client_port = 68
-# interface = lo0
-# src_ipaddr = 127.0.0.1
- broadcast = no
- }
-}
-#client private {
-#}
-recv Discover {
- &control.Server-Identifier = 192.0.2.1
- dhcp_common
-# mac2ip
-# &control.IP-Pool.Name := "local"
-# sqlippool
-# &reply.Message-Type = Offer
-# ok
-}
-recv Request {
- files_dhcp
- &control.Server-Identifier = 192.0.2.1
- if (&request.Server-Identifier && \
- &request.Server-Identifier != &control.Server-Identifier) {
- do_not_respond
- }
-# &reply.Message-Type = Ack
- dhcp_common
-# mac2ip
-# &control.IP-Pool.Name := "local"
-# sqlippool
- if (ok) {
- &reply.Your-IP-Address := "%{&request.Requested-IP-Address || &request.Client-IP-Address}"
- }
-# ok
-}
-recv Decline {
-# &control.IP-Pool.Name := "local"
-# sqlippool
- ok
-}
-recv Inform {
- dhcp_common
- ok
-}
-#recv Inform {
-# &reply.Net.Dst.Port = 67
-# &reply.Message-Type = Ack
-# &reply.Server-Identifier = "%{Net.Dst.IP}"
-# &reply.Site-specific-28 = 0x0a00
-# ok
-#}
-recv Release {
-# &control.IP-Pool.Name := "local"
-# sqlippool
- ok
-}
-recv Lease-Query {
- if (&Client-Hardware-Address) {
- }
- elsif (&Your-IP-Address) {
- }
- elsif (&Client-Identifier) {
- }
- else {
- &reply.Message-Type = Lease-Unknown
- ok
- return
- }
- if (notfound) {
- &reply.Message-Type = Lease-Unknown
- ok
- return
- }
- &reply.Message-Type = Lease-Unassigned
-}
-}
-# 00:01:02:03:04:05,192.0.2.100
-# 01:01:02:03:04:05,192.0.2.101
-# 02:01:02:03:04:05,192.0.2.102
#passwd mac2ip {
# filename = ${confdir}/mac2ip
# format = "*Client-Hardware-Address:=Your-IP-Address"
# delimiter = ","
#}
```
+
+== Default Configuration
+
+```
+```
+```
+# This is a virtual server that handles DHCP.
+```
See raddb/mods-available/dhcp_sqlippool for the IP Pool configuration.
The DHCP functionality goes into a virtual server.
+```
+server dhcp {
+ namespace = dhcpv4
+```
Define a DHCP socket.
The default port below is 6700, so you don't break your network.
listen section to an interface. You will also need one listen
section per interface.
+```
+listen {
+ type = DHCP-Discover
+ type = DHCP-Request
+ type = DHCP-Inform
+ type = DHCP-Release
+ type = DHCP-Decline
+ type = DHCP-Lease-Query
+ transport = udp
+ udp {
+```
IP address to listen on. Will usually be the IP of the
interface, or 0.0.0.0
+```
+ ipaddr = 127.0.0.1
+```
The port should be 67 for a production network. Don't set
it to 67 on a production network unless you really know
what you're doing. Even if nothing is configured below, the
server may still NAK legitimate responses from clients.
+```
+ port = 6700
+```
Interface name we are listening on. See comments above.
+```
+# interface = lo0
+```
source IP address for unicast packets sent by the
DHCP server.
reply:DHCP-Server-IP-Address
reply:DHCP-DHCP-Server-Identifier
+```
+ src_ipaddr = 127.0.0.1
+```
The DHCP server defaults to allowing broadcast packets.
Set this to "no" only when the server receives *all* packets
from a relay agent. i.e. when *no* clients are on the same
It's set to "no" here for testing. It will usually want to
be "yes" in production, unless you are only dealing with
relayed packets.
+```
+ broadcast = no
+```
On Linux if you're running the server as non-root, you
will need to do:
This will allow the server to set ARP table entries
for newly allocated IPs
+```
+ }
+}
+```
If there is no `client` entry in a DHCPv4 virtual server, it will
automatically create and use a "0/0" client.
user machines, along with all DHCPv4 gateways that send packets to
the server.
+```
+#client private {
+```
ipaddr = 192.168.0.0/16
+```
+#}
+```
Packets received on the socket will be processed through one
of the following sections, named after the DHCP packet type.
See dictionary.dhcpv4 for the packet types.
At least one of these attributes should be set at the end of each
section for a response to be sent.
+```
+recv DHCP-Discover {
+```
Set the type of packet to send in reply.
The server will look at the DHCP-Message-Type attribute to
server will fall back to determining the type of reply
based on the rcode of this section.
+```
+ update reply {
+ &DHCP-Message-Type = DHCP-Offer
+ }
+```
The contents here are invented. Change them!
+```
+ update reply {
+ &DHCP-Domain-Name-Server = 127.0.0.1
+ &DHCP-Domain-Name-Server = 127.0.0.2
+ &DHCP-Subnet-Mask = 255.255.255.0
+ &DHCP-Router-Address = 192.0.2.1
+ &DHCP-IP-Address-Lease-Time = 86400
+ &DHCP-DHCP-Server-Identifier = 192.0.2.1
+ }
+```
Do a simple mapping of MAC to assigned IP.
See below for the definition of the "mac2ip"
Or, allocate IPs from the DHCP pool in SQL. You may need to
set the pool name here if you haven't set it elsewhere.
+```
+# update control {
+# &Pool-Name := "local"
+# }
+# dhcp_sqlippool
+```
If DHCP-Message-Type is not set, returning "ok" or
"updated" from this section will respond with a DHCP-Offer
message.
Other rcodes will tell the server to not return any response.
+```
+ ok
+}
+recv DHCP-Request {
+```
Response packet type. See DHCP-Discover section above.
+```
+ update reply {
+ &DHCP-Message-Type = DHCP-Ack
+ }
+```
The contents here are invented. Change them!
+```
+ update reply {
+ &DHCP-Domain-Name-Server = 127.0.0.1
+ &DHCP-Domain-Name-Server = 127.0.0.2
+ &DHCP-Subnet-Mask = 255.255.255.0
+ &DHCP-Router-Address = 192.0.2.1
+ &DHCP-IP-Address-Lease-Time = 86400
+ &DHCP-DHCP-Server-Identifier = 192.0.2.1
+ }
+```
Do a simple mapping of MAC to assigned IP.
See below for the definition of the "mac2ip"
Or, allocate IPs from the DHCP pool in SQL. You may need to
set the pool name here if you haven't set it elsewhere.
+```
+# update control {
+# &Pool-Name := "local"
+# }
+# dhcp_sqlippool
+```
If DHCP-Message-Type is not set, returning "ok" or
"updated" from this section will respond with a DHCP-Ack
packet.
"handled" will not return a packet, all other rcodes will
send back a DHCP-NAK.
+```
+ ok
+}
+```
Other DHCP packet types
By default this configuration will ignore them all. Any packet type
not defined here will be responded to with a DHCP-NAK.
+```
+recv DHCP-Decline {
+ update reply {
+ &DHCP-Message-Type = DHCP-Do-Not-Respond
+ }
+ reject
+}
+recv DHCP-Inform {
+ update reply {
+ &DHCP-Message-Type = DHCP-Do-Not-Respond
+ }
+ reject
+}
+```
For Windows 7 boxes
+```
+#recv DHCP-Inform {
+# update reply {
+# Packet-Dst-Port = 67
+# DHCP-Message-Type = DHCP-ACK
+# DHCP-DHCP-Server-Identifier = "%{Packet-Dst-IP-Address}"
+# DHCP-Site-specific-28 = 0x0a00
+# }
+# ok
+#}
+recv DHCP-Release {
+ update reply {
+ &DHCP-Message-Type = DHCP-Do-Not-Respond
+ }
+ reject
+}
+recv DHCP-Lease-Query {
+```
The thing being queried for is implicit
in the packets.
has MAC, asking for IP, etc.
+```
+ if (&DHCP-Client-Hardware-Address) {
+```
look up MAC in database
+```
+ }
+```
has IP, asking for MAC, etc.
+```
+ elsif (&DHCP-Your-IP-Address) {
+```
look up IP in database
+```
+ }
+```
has host name, asking for IP, MAC, etc.
+```
+ elsif (&DHCP-Client-Identifier) {
+```
look up identifier in database
+```
+ }
+ else {
+ update reply {
+ &DHCP-Message-Type = DHCP-Lease-Unknown
+ }
+ ok
+```
stop processing
+```
+ return
+ }
+```
We presume that the database lookup returns "notfound"
if it can't find anything.
+```
+ if (notfound) {
+ update reply {
+ &DHCP-Message-Type = DHCP-Lease-Unknown
+ }
+ ok
+ return
+ }
+```
Add more logic here. Is the lease inactive?
If so, respond with DHCP-Lease-Unassigned.
DHCP-Lease-Active
DHCP-Lease-Unassigned
+```
+ update reply {
+ &DHCP-Message-Type = DHCP-Lease-Unassigned
+ }
+}
+}
+```
This next section is a sample configuration for the "passwd"
module, that reads flat-text files. It should go into
The file is in the format <mac>,<ip>
+```
+# 00:01:02:03:04:05,192.0.2.100
+# 01:01:02:03:04:05,192.0.2.101
+# 02:01:02:03:04:05,192.0.2.102
+```
This lets you perform simple static IP assignment.
This is an example only - see mods-available/mac2ip instead; do
not uncomment these lines here.
-
-== Default Configuration
-
```
-# This is a virtual server that handles DHCP.
-server dhcp {
- namespace = dhcpv4
-listen {
- type = DHCP-Discover
- type = DHCP-Request
- type = DHCP-Inform
- type = DHCP-Release
- type = DHCP-Decline
- type = DHCP-Lease-Query
- transport = udp
- udp {
- ipaddr = 127.0.0.1
- port = 6700
-# interface = lo0
- src_ipaddr = 127.0.0.1
- broadcast = no
- }
-}
-#client private {
-#}
-recv DHCP-Discover {
- update reply {
- &DHCP-Message-Type = DHCP-Offer
- }
- update reply {
- &DHCP-Domain-Name-Server = 127.0.0.1
- &DHCP-Domain-Name-Server = 127.0.0.2
- &DHCP-Subnet-Mask = 255.255.255.0
- &DHCP-Router-Address = 192.0.2.1
- &DHCP-IP-Address-Lease-Time = 86400
- &DHCP-DHCP-Server-Identifier = 192.0.2.1
- }
-# update control {
-# &Pool-Name := "local"
-# }
-# dhcp_sqlippool
- ok
-}
-recv DHCP-Request {
- update reply {
- &DHCP-Message-Type = DHCP-Ack
- }
- update reply {
- &DHCP-Domain-Name-Server = 127.0.0.1
- &DHCP-Domain-Name-Server = 127.0.0.2
- &DHCP-Subnet-Mask = 255.255.255.0
- &DHCP-Router-Address = 192.0.2.1
- &DHCP-IP-Address-Lease-Time = 86400
- &DHCP-DHCP-Server-Identifier = 192.0.2.1
- }
-# update control {
-# &Pool-Name := "local"
-# }
-# dhcp_sqlippool
- ok
-}
-recv DHCP-Decline {
- update reply {
- &DHCP-Message-Type = DHCP-Do-Not-Respond
- }
- reject
-}
-recv DHCP-Inform {
- update reply {
- &DHCP-Message-Type = DHCP-Do-Not-Respond
- }
- reject
-}
-#recv DHCP-Inform {
-# update reply {
-# Packet-Dst-Port = 67
-# DHCP-Message-Type = DHCP-ACK
-# DHCP-DHCP-Server-Identifier = "%{Packet-Dst-IP-Address}"
-# DHCP-Site-specific-28 = 0x0a00
-# }
-# ok
-#}
-recv DHCP-Release {
- update reply {
- &DHCP-Message-Type = DHCP-Do-Not-Respond
- }
- reject
-}
-recv DHCP-Lease-Query {
- if (&DHCP-Client-Hardware-Address) {
- }
- elsif (&DHCP-Your-IP-Address) {
- }
- elsif (&DHCP-Client-Identifier) {
- }
- else {
- update reply {
- &DHCP-Message-Type = DHCP-Lease-Unknown
- }
- ok
- return
- }
- if (notfound) {
- update reply {
- &DHCP-Message-Type = DHCP-Lease-Unknown
- }
- ok
- return
- }
- update reply {
- &DHCP-Message-Type = DHCP-Lease-Unassigned
- }
-}
-}
-# 00:01:02:03:04:05,192.0.2.100
-# 01:01:02:03:04:05,192.0.2.101
-# 02:01:02:03:04:05,192.0.2.102
#passwd mac2ip {
# filename = ${confdir}/mac2ip
# format = "*DHCP-Client-Hardware-Address:=DHCP-Your-IP-Address"
# delimiter = ","
#}
```
+
+== Default Configuration
+
+```
+```
+```
+# This is a virtual server that handles DHCPv4 relaying
+```
+```
+# Only one server can listen on a socket, so you cannot
+# do DHCP relaying && run a DHCP server at the same time.
+```
+```
+# Configure an instance of the dhcpv4 module in order to use
+# this virtual server - that module provides DHCPv4 client
+# and relay functionality.
+```
+```
+server dhcp.eth1 {
+ namespace = dhcpv4
+listen {
+ type = Discover
+ type = Request
+ type = Inform
+ type = Release
+ type = Decline
+ transport = udp
+```
See sample dhcp virtual server for details of
these options.
+```
+ udp {
+ ipaddr = *
+ port = 67
+ interface = eth1
+ src_ip_addr = 127.0.0.1
+ broadcast = no
+ }
+}
+```
Packets received on the socket will be processed through one
of the following sections, named after the DHCP packet type.
See dictionary.dhcp for the packet types.
+```
+recv Discover {
+```
IP Address of the DHCP server
+```
+ &control.Net.Dst.IP := 192.0.2.2
+```
IP Address of the DHCP relay (where the reply should go to)
If requests are coming from an upstream relay, this will
already be set in the packet
+```
+ &request.Gateway-IP-Address := 192.0.2.1
+```
Call the dhcpv4 module to do the relay
+```
+ dhcpv4
+```
The DHCP Offer will come from the relay host
+```
+ do_not_respond
+}
+```
A repeat of the Discover section to handle Request packets
This can be repeated for Inform, Release and Decline as required.
-
-
-
-
-== Default Configuration
-
```
-# This is a virtual server that handles DHCPv4 relaying
-# Only one server can listen on a socket, so you cannot
-# do DHCP relaying && run a DHCP server at the same time.
-# Configure an instance of the dhcpv4 module in order to use
-# this virtual server - that module provides DHCPv4 client
-# and relay functionality.
-server dhcp.eth1 {
- namespace = dhcpv4
-listen {
- type = Discover
- type = Request
- type = Inform
- type = Release
- type = Decline
- transport = udp
- udp {
- ipaddr = *
- port = 67
- interface = eth1
- src_ip_addr = 127.0.0.1
- broadcast = no
- }
-}
-recv Discover {
- &control.Net.Dst.IP := 192.0.2.2
- &request.Gateway-IP-Address := 192.0.2.1
- dhcpv4
- do_not_respond
-}
recv Request {
&control.Net.Dst.IP := 192.0.2.2
+
&request.Gateway-IP-Address := 192.0.2.1
+
dhcpv4
+
do_not_respond
}
}
```
+
+== Default Configuration
+
+```
+```
+```
+# This is a virtual server that handles DHCPv6.
+```
## The Virtual Server
+```
+server dhcpv6 {
+```
namespace:: Needs to be "dhcpv6" for DHCPv6 functionality.
+```
+ namespace = dhcpv6
+```
all_dhcp_servers_and_relays:: Predefined multicast address
for DHCPv6 servers and relays.
each `listen` section below to use this definition, so that
those sections do not need to list magic numbers.
+```
+ all_dhcp_servers_and_relays = FF02::1:2
+```
interface:: Ethernet interface for DHCPv6.
use the same interface. So it is defined here once, and used
below.
+```
+ interface = en0
+```
port:: The port where we accept packets.
testing will not affect production systems. This value should
be changed to `547` for production use.
+```
+ port = 547
+```
### The listen section
suggestion is because all DHCPv6 listeners will receive all
DHCPv6 packets.
+```
+ listen all_dhcp_servers_and_relays {
+```
type:: The type of packet to accept.
All DHCPv6 request types are supported. Relaying
is not supported.
+```
+ type = Solicit
+ type = Request
+```
transport:: The transport protocol.
Only `udp` is allowed.
+```
+ transport = udp
+```
#### UDP Transport
subsection contains all of the configuration for
the UDP transport.
+```
+ udp {
+```
ipaddr:: The IP address where we accept
packets.
preferred. When there is no IPv6 address
for a host name, an error will occur.
+```
+ ipaddr = ${...all_dhcp_servers_and_relays}
+```
port:: The port where we accept packets.
is configured below, the server may still
NAK legitimate responses from clients.
+```
+ port = ${...port}
+```
interface:: Interface where we receive packets.
When a multicast address is used for `ipaddr` above,
and `interface` configuration MUST be given.
+```
+ interface = ${...interface}
+```
src_ipaddr:: The source IP address used for
unicast messages.
In most cases, you should not need to specify
`src_ipaddr`.
+```
+# src_ipaddr = ${ipaddr}
+ }
+ }
+```
### The listen section
suggestion is because all DHCPv6 listeners will receive all
DHCPv6 packets.
+```
+ listen local_network {
+```
type:: The type of packet to accept.
packets. Those packets MUST be sent to a multicast
address.
+```
+ type = Request
+ type = Information-Request
+```
transport:: The transport protocol.
Only `udp` is allowed.
+```
+ transport = udp
+```
#### UDP Transport
subsection contains all of the configuration for
the UDP transport.
+```
+ udp {
+```
ipaddr:: The IP address where we accept
packets.
"link local" address on that interface,
and use that as the value for `ipaddr`.
+```
+# ipaddr = 2001:db8::
+ port = ${...port}
+ interface = ${...interface}
+ }
+ }
+```
#### State machine configuration
+```
+ dhcpv6 {
+```
status_code_on_success:: Include a status-code
option in the packet even when the operation is
and count any status-code option as a failure
indication.
+```
+# status_code_on_success = no
+```
send_failure_message:: Concatenate the contents
of any Module-Failure-Message attribute in the
move_failure_message_to_parent where the upstream
relay is trusted and secure.
+```
+# send_failure_message = no
+```
move_failure_message_to_parent:: Move all
Module-Failure-Message attributes to the parent
of the Module-Failure-Message will not reach
the end DHCPv6 client.
+```
+# move_failure_message_to_parent = yes
+ }
+```
Receive a Solicit message
+```
+recv Solicit {
+ ok
+}
+```
Send an Advertise message
+```
+send Advertise {
+```
All replies MUST include a Server-ID option
+```
+ &reply.Server-ID.DUID = UUID
+ &reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
+}
+```
Receive a Solicit message
+```
+recv Request {
+ ok
+}
+send Offer {
+```
All replies MUST include a Server-ID option
+```
+ &reply.Server-ID.DUID = UUID
+ &reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
+}
+```
We also support recv / send for all normal DHCPv6 packet types.
packet type names.
-
-
-All replies MUST include a Server-ID option
-
-
-
-== Default Configuration
-
```
-# This is a virtual server that handles DHCPv6.
-server dhcpv6 {
- namespace = dhcpv6
- all_dhcp_servers_and_relays = FF02::1:2
- interface = en0
- port = 547
- listen all_dhcp_servers_and_relays {
- type = Solicit
- type = Request
- transport = udp
- udp {
- ipaddr = ${...all_dhcp_servers_and_relays}
- port = ${...port}
- interface = ${...interface}
-# src_ipaddr = ${ipaddr}
- }
- }
- listen local_network {
- type = Request
- type = Information-Request
- transport = udp
- udp {
-# ipaddr = 2001:db8::
- port = ${...port}
- interface = ${...interface}
- }
- }
- dhcpv6 {
-# status_code_on_success = no
-# send_failure_message = no
-# move_failure_message_to_parent = yes
- }
-recv Solicit {
- ok
-}
-send Advertise {
- &reply.Server-ID.DUID = UUID
- &reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
-}
-recv Request {
- ok
-}
-send Offer {
- &reply.Server-ID.DUID = UUID
- &reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
-}
recv Information-Request {
ok
}
+
send Reply {
+```
+
+All replies MUST include a Server-ID option
+
+```
&reply.Server-ID.DUID = UUID
&reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
}
+
}
```
+
+== Default Configuration
+
+```
+```
- A `send { ... }` section matching the opcode. e.g. `send Query-Response { ... }`. This can be
used for general massaging of the reply. Return codes are ignored.
+```
+server dns {
+```
namespace:: The protocol / dictionary to use.
+```
+ namespace = dns
+ listen {
+ type = Query
+ transport = udp
+```
Dont use "port = 53" unless you want to break things
-
-
-
-
-== Default Configuration
-
```
-server dns {
- namespace = dns
- listen {
- type = Query
- transport = udp
udp {
ipaddr = *
port = 53
}
}
+
recv Query {
if (&Question[0].Name == 'foo.example.com') {
&reply.Resource-Record := {
&Type.A.IP = 127.0.0.1
}
}
+
ok
}
+
send Query-Response {
ok
}
}
```
+
+== Default Configuration
+
+```
+```
+```
+# Sample configuration file for dynamically updating the list
+# of RADIUS clients at run time.
+```
+```
+# Everything is keyed off a client "network" (for example,
+# 192.168.0.2/24). This configuration lets the server know that
+# clients within that network are defined dynamically. The
+# network limitation also ensures that the server accepts
+# dynamic client requests from only a limited, "local" network.
+```
+```
+# When the server receives a packet from an unknown IP address
+# within that network, it tries to find a dynamic definition
+# for that client. If the definition is found, the IP address
+# (and other configuration) is added to the server's internal
+# cache of "known clients", with a configurable lifetime.
+```
+```
+# Further packets from that IP address result in the client
+# definition being found in the cache. Once the lifetime is
+# reached, the client definition is deleted, and any new
+# requests from that client are looked up as above.
+```
+```
+# If the dynamic definition is not found, then the request is
+# treated as if it came from an unknown client, i.e. it is
+# silently discarded.
+```
+```
+# The server has a negative cache for denied dynamic clients.
+# Once a client is denied, it is added to the negative cache,
+# and all packets from that source IP are rejected for 30s.
+```
virtual server in which they are defined. Unlike v3, you CANNOT
define a global client, and point it to a different virtual server,
+```
+server dynamic_clients {
+ namespace = radius
+```
See the "default" virtual server for examples of how to
configure a "listen" section. Only the "dynamic_clients"
changes are documented here.
+```
+ listen {
+ type = Access-Request
+ transport = udp
+```
Limits for this socket.
+```
+ limit {
+```
Limit the number of dynamic clients which
can be defined.
The special value of "0" means "no limit".
We do not recommend this.
+```
+ max_clients = 256
+```
Limit the total number of connections which
used. Each connection opens a new socket,
sockets, then this configuration item is
ignored.
+```
+ max_connections = 256
+```
Free a dynamic client, or close a
connection if it does not receive
Useful range of values: 5 to 600
+```
+ idle_timeout = 60.0
+```
nak_lifetime:: Time for which blocked
clients are placed into a NAK cache.
Useful range of values: 1 to 600
+```
+ nak_lifetime = 30.0
+```
cleanup_delay: The time to wait (in
seconds) before cleaning up a reply to an
Useful range of values: 2 to 10
+```
+ cleanup_delay = 5.0
+ }
+ udp {
+ ipaddr = 127.0.0.1
+ port = 2812
+```
Whether or not we allow dynamic clients.
subsection below. See that section for
more information.
+```
+ dynamic_clients = true
+```
If dynamic clients are allowed, then limit
them to only a small set of source
If dynamic clients are not allowed, then
this section is ignored.
+```
+ networks {
+```
Allow packets from these networks
to define dynamic clients.
trie, so lookups are fast and
efficient.
+```
+ allow = 127/8
+ allow = 192.0.2/24
+```
The default is to deny all networks
which are not in the "allow" list.
address cannot be used to define
a dynamic client.
+```
+ deny = 127.1/16
+ }
+ }
+ }
+```
When a request is received from an unknown client, it is
initially passed through this 'new client' section to
If this section returns `fail`, then the client is denied.
+```
+ new client {
+```
Put any modules you want here. SQL, LDAP, "exec",
Perl, etc. The only requirements is that the
Copy the IP address of the client from
the request just received
+```
+ &control += {
+ &FreeRADIUS-Client-IP-Address = "%{Net.Src.IP}"
+```
require_message_authenticator
+```
+ &FreeRADIUS-Client-Require-MA = no
+ &FreeRADIUS-Client-Limit-Proxy-State = "auto"
+ &FreeRADIUS-Client-Secret = "testing123"
+```
shortname
+```
+ &FreeRADIUS-Client-Shortname = "%{Net.Src.IP}"
+```
nas_type
+```
+ &FreeRADIUS-Client-NAS-Type = "other"
+ }
+ ok
+ }
+```
This subsection is called when the client was added.
If this section is empty, you can just delete it entirely.
+```
+ add client {
+ ok
+ }
+```
This subsection is called if the client was NOT added.
If this section is empty, you can just delete it entirely.
+```
+ deny client {
+ ok
+ }
+```
After client is added, the packet is run through the normal
processing sections
-
-== Default Configuration
-
```
-# Sample configuration file for dynamically updating the list
-# of RADIUS clients at run time.
-# Everything is keyed off a client "network" (for example,
-# 192.168.0.2/24). This configuration lets the server know that
-# clients within that network are defined dynamically. The
-# network limitation also ensures that the server accepts
-# dynamic client requests from only a limited, "local" network.
-# When the server receives a packet from an unknown IP address
-# within that network, it tries to find a dynamic definition
-# for that client. If the definition is found, the IP address
-# (and other configuration) is added to the server's internal
-# cache of "known clients", with a configurable lifetime.
-# Further packets from that IP address result in the client
-# definition being found in the cache. Once the lifetime is
-# reached, the client definition is deleted, and any new
-# requests from that client are looked up as above.
-# If the dynamic definition is not found, then the request is
-# treated as if it came from an unknown client, i.e. it is
-# silently discarded.
-# The server has a negative cache for denied dynamic clients.
-# Once a client is denied, it is added to the negative cache,
-# and all packets from that source IP are rejected for 30s.
-server dynamic_clients {
- namespace = radius
- listen {
- type = Access-Request
- transport = udp
- limit {
- max_clients = 256
- max_connections = 256
- idle_timeout = 60.0
- nak_lifetime = 30.0
- cleanup_delay = 5.0
- }
- udp {
- ipaddr = 127.0.0.1
- port = 2812
- dynamic_clients = true
- networks {
- allow = 127/8
- allow = 192.0.2/24
- deny = 127.1/16
- }
- }
- }
- new client {
- &control += {
- &FreeRADIUS-Client-IP-Address = "%{Net.Src.IP}"
- &FreeRADIUS-Client-Require-MA = no
- &FreeRADIUS-Client-Limit-Proxy-State = "auto"
- &FreeRADIUS-Client-Secret = "testing123"
- &FreeRADIUS-Client-Shortname = "%{Net.Src.IP}"
- &FreeRADIUS-Client-NAS-Type = "other"
- }
- ok
- }
- add client {
- ok
- }
- deny client {
- ok
- }
recv Access-Request {
accept
}
}
```
+
+== Default Configuration
+
+```
+```
- `send Failure-Notification` already rejecting the auth attempt.
- `recv Failure-Notification` already rejecting the auth attempt.
- `recv Success-Notification` sending failure after EAP-Response/
+```
+# Success Notification-ACK would
+# violate the standard.
+```
- `recv Authentication-Reject` already rejecting the auth attempt.
- `recv Client-Error` already rejecting the auth attempt.
- `clear pseudonym` nothing more we can do...
run the EAP-AKA state machine better than the EAP-AKA module).
+```
+server eap-aka-sim {
+```
This is a unified configuration example for EAP-SIM, EAP-AKA
and EAP-AKA-Prime. Many of the sections are identical between
The main differences are between EAP-SIM and EAP-AKA['] where
additional identity processing sections are used.
+```
+# namespace = eap-sim
+ namespace = eap-aka
+# namespace = eap-aka-prime
+# eap-sim {
+```
request_identity:: Send a SIM-Start message to Requests
an additional identity to the one from the EAP-Identity-Response.
identities can be requested by policy.
See sites-available/eap-aka-sim for details.
+```
+# request_identity = no
+```
ephemeral_id_length:: The length of any pseudonyms or
fastauth identities we generate (not including hint byte).
See sites-available/eap-aka-sim for details on how to trigger
the generation of pseudonym or fastauth identities.
+```
+# ephemeral_id_length = 14
+```
strip_permanent_identity_hint:: Strip the identity hint when
copying &EAP-Identity or &Identity to &Permanent-Identity.
to yes, and the hint byte matches what we'd expect for the
EAP-Method being executed.
+```
+# strip_permanent_identity_hint = yes
+```
protected_success:: Send a protected success message.
After the Notification is ACKed by the peer, we send
the final `EAP-Success` packet containing `MPPE` keys.
+```
+# protected_success = yes
+# }
+ eap-aka {
+```
request_identity:: Send a AKA-Identity message to request
an additional identity to the one from the EAP-Identity-Response.
identities can be requested by policy.
See sites-available/eap-aka-sim for details.
+```
+# request_identity = no
+```
ephemeral_id_length:: The length of any pseudonyms or
fastauth identities we generate (not including hint byte).
+```
+# ephemeral_id_length = 14
+```
strip_permanent_identity_hint:: Strip the identity hint when
copying &EAP-Identity or &Identity to &Permanent-Identity.
to yes, and the hint byte matches what we'd expect for the
EAP-Method being executed.
+```
+# strip_permanent_identity_hint = yes
+```
protected_success:: Send a protected success message.
After the Notification is ACKed by the peer, we send
the final `EAP-Success` packet containing `MPPE` keys.
+```
+# protected_success = yes
+ }
+# eap-aka-prime {
+```
network_name:: The default value used for AT_KDF_INPUT
How this value should be created and formatted is specified
in 3GPP.24.302.
+```
+# network_name = ""
+```
request_identity:: Send a AKA-Identity message to request
an additional identity to the one from the EAP-Identity-Response.
identities can be requested by policy.
See sites-available/eap-aka-sim for details.
+```
+# request_identity = no
+```
ephemeral_id_length:: The length of any pseudonyms or
fastauth identities we generate (not including hint byte).
See sites-available/eap-aka-sim for details on how to trigger
the generation of pseudonym or fastauth identities.
+```
+# ephemeral_id_length = 14
+```
strip_permanent_identity_hint:: Strip the identity hint when
copying &EAP-Identity or &Identity to &Permanent-Identity.
to yes, and the hint byte matches what we'd expect for the
EAP-Method being executed.
+```
+# strip_permanent_identity_hint = yes
+```
protected_success:: Send a protected success message.
After the Notification is ACKed by the peer, we send
the final `EAP-Success` packet containing `MPPE` keys.
+```
+# protected_success = yes
+# }
+```
### `recv Identity-Response { ... }` - Process an EAP-Identity-Response or AKA-Identity value
scheme described by 3GPP S3-170116 and the Wireless Broadband Allowance
document "IMSI PRIVACY PROTECTION FOR WI-FI".
+```
+ recv Identity-Response {
+ ok
+ }
+```
### `send Identity-Request { ... }` - Allow user massaging of Identity-Request
AKA-Identity { ... }` sections are provided, in which case they will
be used instead.
+```
+ send Identity-Request {
+ ok
+ }
+```
### `send Start-Request { ... }` - Allow specific policies to be applied to SIM start requests
EAP-SIM/EAP-AKA, the main difference being, Start messages also
allow the version of EAP-SIM to be negotiated.
+```
+# send Start-Request {
+# ok
+# }
+```
### `send Start-Request { ... }` - Allow specific policies to be applied to SIM start responses
EAP-SIM/EAP-AKA, the main difference being, Start messages also
allow the version of EAP-SIM to be negotiated.
+```
+# recv Start-Response {
+# ok
+# }
+```
### `send AKA-Identity-Request { ... }` - Allow specific policies to be applied to AKA identity requests
EAP-SIM/EAP-AKA, the main difference being, Start messages also
allow the version of EAP-SIM to be negotiated.
+```
+# send AKA-Identity-Request {
+# ok
+# }
+```
### `send Challenge-Request { ... }` - Acquire GSM triplets or UMTS quintuplets for the Challenge-Request
If you need to implement one of these identity privacy schemes, the
cryptographic identity can be specified with `&control.KDF-Identity`.
+```
+ send Challenge-Request {
+ ok
+ }
+```
### `recv Challenge-Response { ... }` - Allow additional authorization checks and logging
(General failure after authentication).
- Anything else Continue processing the request.
+```
+ recv Challenge-Response {
+ ok
+ }
+```
### `recv Reauthentication-Request { ... }` - Allow user massaging of a reauthentication request
supplicant may be tracked as they would if their permanent Id has been
used.
+```
+ send Reauthentication-Request {
+ ok
+ }
+```
### `recv Reauthentication-Response { ... }` - Allow additional authorization checks and logging
Will not allow a transition back to the challenge state, as it's
not clear that this is allowed by RFC4186/RFC4187.
+```
+ recv Reauthentication-Response {
+ ok
+ }
+```
### `recv Client-Error { ... }` - Log the fact that the supplicant has terminated authentication
After this section is run authentication fails immediately with no
EAP-Response/AKA-Notification round.
+```
+ recv Client-Error {
+ ok
+ }
+```
### `recv Authentication-Reject { ... }` - Log the fact that the supplicant failed to authenticate the AuC
After this section is run authentication fails immediately with no
EAP-Response/AKA-Notification round.
+```
+ recv Authentication-Reject {
+ ok
+ }
+```
### `recv Synchronization-Failure { ... }` - Allow resynchronisation of sequence numbers
NOTE: Only one Synchronisation attempt is permitted per
authentication attempt.
+```
+ recv Synchronization-Failure {
+ ok
+ }
+```
### `send Failure-Notification { ... }` - Allow massaging/logging of failure notifications
NOTE: The rcode returned from this section is ignored.
+```
+ send Failure-Notification {
+ ok
+ }
+```
### `send Failure-Notification { ... }` - Allow logging of failure notification acknowledgements
NOTE: The rcode returned from this section is ignored.
+```
+ recv Failure-Notification-ACK {
+ ok
+ }
+```
### `send Success-Notification { ... }` - Allow massaging/logging of success notifications
NOTE: Only entered if protected result indications are used.
+```
+ send Success-Notification {
+ ok
+ }
+```
### `send Success-Notification-Ack { ... }` - Allow logging of success notification acknowledgements
NOTE: The rcode returned from this section is ignored.
+```
+ recv Success-Notification-ACK {
+ ok
+ }
+```
### `send EAP-Success { ... }` - Allow massaging/logging of success notifications
a Success-Notification, otherwise the same rcode mappings as
`recv Challenge-Response { ... }` are used.
+```
+ send EAP-Success {
+ ok
+ }
+```
### `send EAP-Failure { ... }` - Allow logging of failure notification acknowledgements
NOTE: The rcode returned from this section is ignored.
+```
+ recv EAP-Failure {
+ ok
+ }
+```
### `store pseudonym { ... }`
need populate this section. You should however, provide a policy
for `load session { ... }`, and use that to decrypt the pseudonym.
+```
+ store pseudonym {
+ ok
+ }
+```
### `load pseudonym { ... }`
decrypt the pseudonym here, and store the decrypted value in
`&session-state.Permanent-Identity`.
+```
+ load pseudonym {
+ ok
+ }
+```
### `clear pseudonym { ... }`
You should remove any session information stored against
`&Next-Pseudonym-Id`.
+```
+ clear pseudonym {
+ ok
+ }
+```
### `store session { ... }`
cluster, you may wish to use the redis or memcached drivers to
provide a unified session store.
+```
+ store session {
+ ok
+ }
+```
### `load session { ... }`
- `updated` Continue with reauthentication.
- Anything else Fall back to full authentication.
+```
+ load session {
+ ok
+ }
+```
### `clear session { ... }`
You should remove any session information stored against `&request.Session-ID`.
-
-== Default Configuration
-
```
-# Success Notification-ACK would
-# violate the standard.
-server eap-aka-sim {
-# namespace = eap-sim
- namespace = eap-aka
-# namespace = eap-aka-prime
-# eap-sim {
-# request_identity = no
-# ephemeral_id_length = 14
-# strip_permanent_identity_hint = yes
-# protected_success = yes
-# }
- eap-aka {
-# request_identity = no
-# ephemeral_id_length = 14
-# strip_permanent_identity_hint = yes
-# protected_success = yes
- }
-# eap-aka-prime {
-# network_name = ""
-# request_identity = no
-# ephemeral_id_length = 14
-# strip_permanent_identity_hint = yes
-# protected_success = yes
-# }
- recv Identity-Response {
- ok
- }
- send Identity-Request {
- ok
- }
-# send Start-Request {
-# ok
-# }
-# recv Start-Response {
-# ok
-# }
-# send AKA-Identity-Request {
-# ok
-# }
- send Challenge-Request {
- ok
- }
- recv Challenge-Response {
- ok
- }
- send Reauthentication-Request {
- ok
- }
- recv Reauthentication-Response {
- ok
- }
- recv Client-Error {
- ok
- }
- recv Authentication-Reject {
- ok
- }
- recv Synchronization-Failure {
- ok
- }
- send Failure-Notification {
- ok
- }
- recv Failure-Notification-ACK {
- ok
- }
- send Success-Notification {
- ok
- }
- recv Success-Notification-ACK {
- ok
- }
- send EAP-Success {
- ok
- }
- recv EAP-Failure {
- ok
- }
- store pseudonym {
- ok
- }
- load pseudonym {
- ok
- }
- clear pseudonym {
- ok
- }
- store session {
- ok
- }
- load session {
- ok
- }
clear session {
ok
}
}
```
+
+== Default Configuration
+
+```
+```
+```
+# An example virtual server configuration.
+```
+```
+# This client will be available to any "listen" section that
+# are defined outside of a virtual server section. However,
+# when the server receives a packet from this client, the
+# request will be processed through the "example" virtual
+# server, as the "client" section contains a configuration item
+# to that effect.
+```
+```
+# Note that this client will be able to send requests to any
+# port defined in a global "listen" section. It will NOT,
+# however, be able to send requests to a port defined in a
+# "listen" section that is contained in a "server" section.
+```
+```
+# With careful matching of configurations, you should be able
+# to:
+```
+```
+# - Define one authentication port, but process each client
+# through a separate virtual server.
+```
+```
+# - define multiple authentication ports, each with a private
+# list of clients.
+```
+```
+# - define multiple authentication ports, each of which may
+# have the same client listed, but with different shared
+# secrets
+```
+```
+# FYI: We use an address in the 192.0.2.* space for this example,
+# as https://tools.ietf.org/html/rfc3330[RFC 3330] says that that /24 range is used for documentation
+# and examples, and should not appear on the net. You shouldn't
+# use it for anything, either.
+```
+```
+client 192.0.2.10 {
+ shortname = example-client
+ secret = testing123
+ virtual_server = example
+}
+```
+```
+# An example virtual server. It starts off with "server name {"
+# The "name" is used to reference this server from a "listen"
+# or "client" section.
+```
+```
+server example {
+```
Listen on 192.0.2.1:1812 for Access-Requests
When the server receives a packet, it is processed
-through the "authorize", etc. sections listed here,
+through the "recv ...", etc. sections listed here,
NOT the global ones the "default" site.
+```
+ listen {
+ ipaddr = 192.0.2.1
+ port = 1821
+ type = auth
+ }
+```
This client is listed within the "server" section,
and is therefore known ONLY to the socket defined
line here, as the client is encapsulated within
the "server" section.
+```
+ client 192.0.2.9 {
+ shortname = example-client
+ secret = testing123
+ }
+ recv Access-Request {
+```
Some example policies. See "man unlang" for more.
+```
+ if (&User-Name == "bob") {
+ &control.Password.Cleartext := "bob"
+ }
+```
And then reject the user. The next line requires
that the "always reject {}" section is defined in
the "modules" section of radiusd.conf.
-
-
-
-
-
-== Default Configuration
-
```
-# An example virtual server configuration.
-# This client will be available to any "listen" section that
-# are defined outside of a virtual server section. However,
-# when the server receives a packet from this client, the
-# request will be processed through the "example" virtual
-# server, as the "client" section contains a configuration item
-# to that effect.
-# Note that this client will be able to send requests to any
-# port defined in a global "listen" section. It will NOT,
-# however, be able to send requests to a port defined in a
-# "listen" section that is contained in a "server" section.
-# With careful matching of configurations, you should be able
-# to:
-# - Define one authentication port, but process each client
-# through a separate virtual server.
-# - define multiple authentication ports, each with a private
-# list of clients.
-# - define multiple authentication ports, each of which may
-# have the same client listed, but with different shared
-# secrets
-# FYI: We use an address in the 192.0.2.* space for this example,
-# as https://tools.ietf.org/html/rfc3330[RFC 3330] says that that /24 range is used for documentation
-# and examples, and should not appear on the net. You shouldn't
-# use it for anything, either.
-client 192.0.2.10 {
- shortname = example-client
- secret = testing123
- virtual_server = example
-}
-# An example virtual server. It starts off with "server name {"
-# The "name" is used to reference this server from a "listen"
-# or "client" section.
-server example {
- listen {
- ipaddr = 192.0.2.1
- port = 1821
- type = auth
- }
- client 192.0.2.9 {
- shortname = example-client
- secret = testing123
- }
- recv Access-Request {
- if (&User-Name == "bob") {
- &control.Password.Cleartext := "bob"
- }
reject
}
+
send Access-Accept {
+
}
+
send Access-Reject {
&reply.Reply-Message = "This is only an example."
}
+
}
```
+
+== Default Configuration
+
+```
+```
+++ /dev/null
-== Virtual Servers
-
-FreeRADIUS 4.0 supports virtual servers. This is probably the single
-largest change that is NOT backwards compatible with 1.x.
-
-The virtual servers do NOT have to be set up with the `sites-available`
-and `sites-enabled` directories. You can still have one "radiusd.conf"
-file, and put the server configuration there:
-
-```
-...
-server {
- recv Access-Request {
- ...
- }
- authenticate pap {
- ...
- }
- ...
-}
-...
-```
-
-The power of virtual servers lies in their ability to separate policies.
-A policy can be placed into a virtual server, where it is guaranteed to
-affect only the requests that are passed through that virtual server. In
-1.x, the policies were global, and it sometimes took much effort to
-write a policy so that it only applied in certain limited situations.
-
-=== What do we mean by "virtual server"?
-
-A virtual server is a (nearly complete) RADIUS server, just like a
-configuration for FreeRADIUS 1.x. However, FreeRADIUS can now run
-multiple virtual servers at the same time. The virtual servers can even
-proxy requests to each other!
-
-The simplest way to create a virtual server is to take the all of the
-request processing sections from radius.conf, ("authorize" ,
-"authenticate", etc.) and wrap them in a "server \{}" block, as
-above.
-
-You can create another virtual server by:
-
-* defining a new "server foo \{…}" section in `radiusd.conf`
-* Putting the normal "authorize", etc. sections inside of it
-* Adding a "listen" section _inside_ of the "server" section.
-
-e.g.
-
-```
-...
-server foo {
- listen {
- ipaddr = 127.0.0.1
- port = 2000
- type = auth
- }
-
- recv Access-Request {
- &control.Password.Cleartext := "bob"
- pap
- }
-
- authenticate pap {
- pap
- }
-}
-...
-```
-
-With that text added to `radiusd.conf`, run the server in debugging mode
-(`radiusd -X`), and in another terminal window, type:
-
-```
-$ radtest bob bob localhost:2000 0 testing123
-```
-
-You should see the server return an Access-Accept.
-
-=== Capabilities and limitations
-
-The only sub-sections that can appear in a virtual server section are:
-
-```
-listen
-client
-authorize
-authenticate
-post-auth
-pre-proxy
-post-proxy
-preacct
-accounting
-session
-```
-
-All other configuration parameters (modules, etc.) are global.
-
-Inside of a virtual server, the authorize, etc. sections have their
-normal meaning, and can contain anything that an authorize section could
-contain in 1.x.
-
-When a "listen" section is inside of a virtual server definition, it
-means that all requests sent to that IP/port will be processed through
-the virtual server. There cannot be two "listen" sections with the
-same IP address and port number.
-
-When a "client" section is inside of a virtual server definition, it
-means that that client is known only to the "listen" sections that are
-also inside of that virtual server. Not only is this client definition
-available only to this virtual server, but the details of the client
-configuration is also available only to this virtual server.
-
-i.e. Two virtual servers can listen on different IP address and ports,
-but both can have a client with IP address 127.0.0.1. The shared secret
-for that client can be different for each virtual server.
-
-=== More complex "listen" capabilities
-
-The "listen" sections have a few additional configuration items that
-were not in 1.x, and were not mentioned above. These configuration items
-enable almost any mapping of IP / port to clients to virtual servers.
-
-The configuration items are:
-
-```
-virtual_server = <name>
-
- If set, all requests sent to this IP / port are processed
- through the named virtual server.
-
- This directive can be used only for "listen" sections
- that are global. i.e. It CANNOT be used if the
- "listen" section is inside of a virtual server.
-
-clients = <name>
-
- If set, the "listen" section looks for a "clients" section:
-
- clients <name> {
- ...
- }
-
- It looks inside of that named "clients" section for
- "client" subsections, at least one of which must
- exist. Each client in that section is added to the
- list of known clients for this IP / port. No other
- clients are known.
-
- If it is set, it over-rides the list of clients (if
- any) in the same virtual server. Note that the
- clients are NOT additive!
-
- If it is not set, then the clients from the current
- virtual server (if any) are used. If there are no
- clients in this virtual server, then the global
- clients are used.
-
- i.e. The most specific directive is used:
- * configuration in this "listen" section
- * clients in the same virtual server
- * global clients
-
- The directives are also *exclusive*, not *additive*.
- If you have one client in a virtual server, and
- another client referenced from a "listen" section,
- then that "listen" section will ONLY use the second
- client. It will NOT use both clients.
-```
-
-=== More complex "client" capabilities
-
-The "client" sections have a few additional configuration items that
-were not in 1.x, and were not mentioned above. These configuration items
-enable almost any mapping of IP / port to clients to virtual servers.
-
-The configuration items are:
-
-```
-virtual_server = <name>
-
- If set, all requests from this client are processed
- through the named virtual server.
-
- This directive can be used only for "client" sections
- that are global. i.e. It CANNOT be used if the
- "client" section is inside of a virtual server.
-```
-
-If the "listen" section has a "server" entry, and a matching client
-is found ALSO with a "server" entry, then the clients server is used
-for that request.
-
-=== Worked examples
-
-Listening on one socket, and mapping requests from two clients to two
-different servers.
-
-```
-listen {
- ...
-}
-client one {
- ...
- virtual_server = server_one
-}
-client two {
- ...
- virtual_server = server_two
-}
-server server_one {
- recv Access-Request {
- ...
- }
- ...
-}
-server server_two {
- recv Access-Request {
- ...
- }
- ...
-}
-```
-
-This could also be done as:
-
-```
-listen {
- ...
- virtual_server = server_one
-}
-client one {
- ...
-}
-client two {
- ...
- virtual_server = server_two
-}
-server server_one {
- recv Access-Request {
- ...
- }
- ...
-}
-server server_two {
- recv Access-Request {
- ...
- }
- ...
-}
-```
-
-In this case, the default server for the socket is "server_one", so
-there is no need to set that in the client "one" configuration. The
-"server_two" configuration for client "two" over-rides the default
-setting for the socket.
-
-Note that the following configuration will NOT work:
-
-```
-listen {
- ...
- virtual_server = server_one
-}
-client one {
- ...
-}
-server server_one {
- recv Access-Request {
- ...
- }
- ...
-}
-server server_two {
- client two {
- ...
- }
- recv Access-Request {
- ...
- }
- ...
-}
-```
-
-In this example, client "two" is hidden inside of the virtual server,
-where the "listen" section cannot find it.
-
-=== Outlined examples
-
-This section outlines a number of examples, with alternatives.
-
-* one server, multiple sockets
-** multiple "listen" sections in a "server" section
-* one server per client
-** define multiple servers
-** have a global "listen" section
-** have multiple global "clients", each with "virtual_server = X"
-* two servers, each with their own sockets
-** define multiple servers
-** put "client" sections into each "server"
-** put a "listen" section into each "server"
-+
-Each server can list the same client IP, and the secret can be
-different.
-* two sockets, sharing a list of clients, but pointing to different
-servers
-** define global "listen" sections
-** in each, set "virtual_server = X"
-** in each, set "clients = Y"
-** define "clients Y" section, containing multiple clients.
-+
-This also means that you can have a third socket, which doesn’t share
-any of these clients.
-
-=== How to decide what to do
-
-If you want _completely_ separate policies for a socket or a client,
-then create a separate virtual server. Then, map the request to that
-server by setting configuration entries in a "listen" section or in a
-"client" section.
-
-Start off with the common cases first. If most of the clients and/or
-sockets get a particular policy, make that policy the default. Configure
-it without paying attention to the sockets or clients you want to add
-later, and without adding a second virtual server. Once it works, then
-add the second virtual server.
-
-If you want to reuse the previously defined sockets with the second
-virtual server, then you will need one or more global "client"
-sections. Those clients will contain a "virtual_server = …" entry that
-will direct requests from those clients to the appropriate virtual
-server.
-
-=== List of provided virtual servers
-
-* xref:raddb/sites-available/abfab-tls.adoc[abfab tls]
-* xref:raddb/sites-available/abfab-tr-idp.adoc[abfab tr idp]
-* xref:raddb/sites-available/arp.adoc[arp]
-* xref:raddb/sites-available/bfd.adoc[bfd]
-* xref:raddb/sites-available/buffered-sql.adoc[buffered sql]
-* xref:raddb/sites-available/challenge.adoc[challenge]
-* xref:raddb/sites-available/channel_bindings.adoc[channel_bindings]
-* xref:raddb/sites-available/check-eap-tls.adoc[check eap tls]
-* xref:raddb/sites-available/coa.adoc[coa]
-* xref:raddb/sites-available/control-socket.adoc[control socket]
-* xref:raddb/sites-available/copy-acct-to-home-server.adoc[copy acct to home server]
-* xref:raddb/sites-available/decoupled-accounting.adoc[decoupled accounting]
-* xref:raddb/sites-available/default.adoc[default]
-* xref:raddb/sites-available/detail.adoc[detail]
-* xref:raddb/sites-available/dhcp.adoc[dhcp]
-* xref:raddb/sites-available/dhcp.relay.adoc[dhcp relay]
-* xref:raddb/sites-available/dynamic-clients.adoc[dynamic clients]
-* xref:raddb/sites-available/example.adoc[example]
-* xref:raddb/sites-available/inner-tunnel.adoc[inner tunnel]
-* xref:raddb/sites-available/ldap_sync.adoc[ldap_sync]
-* xref:raddb/sites-available/originate-coa.adoc[originate coa]
-* xref:raddb/sites-available/proxy-inner-tunnel.adoc[proxy inner tunnel]
-* xref:raddb/sites-available/radius-acct.adoc[radius acct]
-* xref:raddb/sites-available/robust-proxy-accounting.adoc[robust proxy accounting]
-* xref:raddb/sites-available/status.adoc[status]
-* xref:raddb/sites-available/tacacs.adoc[tacacs]
-* xref:raddb/sites-available/tls.adoc[tls]
-* xref:raddb/sites-available/tls-cache.adoc[tls cache]
-* xref:raddb/sites-available/virtual.example.com.adoc[virtual example com]
-* xref:raddb/sites-available/vmps.adoc[vmps]
+```
+# This is a virtual server that handles *only* inner tunnel
+# requests for EAP-TTLS and PEAP types.
+```
+```
+server inner-tunnel {
+ namespace = radius
+```
This next section is here to allow testing of the "inner-tunnel"
authentication methods, independently from the "default" server.
Do NOT do any PEAP tests. It won't help. Instead, concentrate
on fixing the inner tunnel configuration. DO NOTHING ELSE.
+```
+listen {
+ type = Access-Request
+ transport = udp
+ udp {
+ ipaddr = 127.0.0.1
+ port = 18120
+ }
+}
+```
Authorization
+```
+recv Access-Request {
+```
The 'copy_request_to_tunnel' option has been removed
from from v4.0.
The following policy in raddb/policy.d/eap can be used
to copy attributes over.
+```
+# copy_request_to_tunnel
+```
Take a User-Name, and perform some checks on it, for spaces and other
invalid characters. If the User-Name appears invalid, reject the
See policy.d/filter for the definition of the filter_username policy.
+```
+ filter_username
+```
Do checks on outer / inner User-Name, so that users
can't spoof us by using incompatible identities
+```
+ filter_inner_identity
+```
The chap module will set 'Auth-Type := ::CHAP' if we are
handling a CHAP request and Auth-Type has not already been set
+```
+ chap
+```
If the users are logging in with an MS-CHAP-Challenge
attribute for authentication, the mschap module will find
the MS-CHAP-Challenge attribute, and add 'Auth-Type := ::MS-CHAP'
to the request, which will cause the server to then use
the mschap module for authentication.
+```
+ mschap
+```
Pull crypt'd passwords from /etc/passwd or /etc/shadow,
using the system API's to get the password. If you want
to read /etc/passwd or /etc/shadow directly, see the
passwd module, above.
+```
+# unix
+```
This module takes care of EAP-MSCHAPv2 authentication.
for the many packets that go back and forth to set up TTLS
or PEAP. The load on those servers will therefore be reduced.
+```
+ eap {
+ ok = return
+ }
+```
Read the 'users' file
+```
+ files
+```
Look in an SQL database. The schema of the database
is meant to mirror the "users" file.
See "Authorization Queries" in `mods-config/sql/main/$driver/queries.conf`
+```
+ -sql
+```
If you are using /etc/smbpasswd, and are also doing
mschap authentication, then uncomment this line, and
enable the "smbpasswd" module.
+```
+# smbpasswd
+```
The ldap module reads passwords from the LDAP database.
+```
+ -ldap
+```
Enforce daily limits on time spent logged in.
+```
+# daily
+ expiration
+```
If no other module has claimed responsibility for
authentication, then try to use PAP. This allows the
This module should be listed last, so that the other modules
get a chance to set Auth-Type for themselves.
+```
+ pap
+}
+```
Authentication.
This section lists which modules are available for authentication.
Note that it does NOT mean 'try each module in order'. It means
-that a module from the 'authorize' section adds a configuration
+that a module from the 'recv Access-Request' section adds a configuration
attribute 'Auth-Type := ::FOO'. That authentication type is then
used to pick the appropriate module from the list below.
PAP authentication, when a back-end database listed
-in the 'authorize' section supplies a password. The
+in the 'recv Access-Request' section supplies a password. The
password can be clear-text, or encrypted.
+```
+authenticate pap {
+ pap
+}
+```
Most people want CHAP authentication
-A back-end database listed in the 'authorize' section
+A back-end database listed in the 'recv Access-Request' section
MUST supply a CLEAR TEXT password. Encrypted passwords
won't work.
+```
+authenticate chap {
+ chap
+}
+```
MSCHAP authentication.
+```
+authenticate mschap {
+ mschap
+}
+```
Pluggable Authentication Modules.
+```
+#authenticate pam {
+# pam
+#}
+```
Uncomment it if you want to use ldap for authentication
Note that this means "check plain-text password against
authentication server, and knows what to do with authentication.
LDAP servers do not.
+```
+#authenticate ldap {
+# ldap
+#}
+```
Allow EAP authentication.
+```
+authenticate eap {
+ eap
+}
+```
Post-Authentication
Once we KNOW that the user has been authenticated, there are
additional steps we can take.
will copy this to the reply. To copy the entire reply see
"use_tunneled_reply" below.
+```
+send Access-Accept {
+```
If you want privacy to remain, see the
Chargeable-User-Identity attribute from https://tools.ietf.org/html/rfc4372[RFC 4372].
If you want to use it just uncomment the line below.
If you want to have a log of authentication replies,
uncomment the following line, and enable the
'detail reply_log' module.
+```
+# reply_log
+```
After authenticating the user, do another SQL query.
See "Authentication Logging Queries" in `mods-config/sql/main/$driver/queries.conf`
+```
+ -sql
+```
Instead of sending the query to the SQL server,
write it into a log file.
+```
+# sql_log
+```
Uncomment the following if you have set
'edir = yes' in the ldap module sub-section of
the 'modules' section.
+```
+# ldap
+```
Instead of the "use_tunneled_reply" option in previous
versions of the server, uncomment the following line to
section will then copy them from the session-state into
the reply.
+```
+# use_tunneled_reply
+```
Call an instance of `linelog` to log the authentication success
- equivalent to the previous log `auth = yes` option in v3.
See `mods-enabled/linelog` for message formats and destinations.
+```
+# log_auth_result
+}
+```
Access-Reject packets are sent through the REJECT sub-section of the
post-auth section.
Add the ldap module name (or instance) if you have set
'edir = yes' in the ldap module configuration
+```
+send Access-Reject {
+```
log failed authentications in SQL, too.
+```
+ -sql
+```
Call an instance of `linelog` to log the authentication failure
- equivalent to the previous log `auth = yes` option in v3.
See `mods-enabled/linelog` for message formats and destinations.
+```
+# log_auth_result
+ attr_filter.access_reject
+```
Let the outer session know which module failed, and why.
-
-== Default Configuration
-
```
-# This is a virtual server that handles *only* inner tunnel
-# requests for EAP-TTLS and PEAP types.
-server inner-tunnel {
- namespace = radius
-listen {
- type = Access-Request
- transport = udp
- udp {
- ipaddr = 127.0.0.1
- port = 18120
- }
-}
-recv Access-Request {
-# copy_request_to_tunnel
- filter_username
- filter_inner_identity
- chap
- mschap
-# unix
- eap {
- ok = return
- }
- files
- -sql
-# smbpasswd
- -ldap
-# daily
- expiration
- pap
-}
-authenticate pap {
- pap
-}
-authenticate chap {
- chap
-}
-authenticate mschap {
- mschap
-}
-#authenticate pam {
-# pam
-#}
-#authenticate ldap {
-# ldap
-#}
-authenticate eap {
- eap
-}
-send Access-Accept {
-# reply_log
- -sql
-# sql_log
-# ldap
-# use_tunneled_reply
-# log_auth_result
-}
-send Access-Reject {
- -sql
-# log_auth_result
- attr_filter.access_reject
&outer.session-state.Module-Failure-Message := &request.Module-Failure-Message
}
} # inner-tunnel server block
```
+
+== Default Configuration
+
+```
+```
See /etc/raddb/mods-available/ldap for more detailed descriptions of
configuration items.
+```
+server ldap_sync {
+ namespace = ldap_sync
+```
Local attributes which are used to cache results from LDAP
+```
+ dictionary {
+ string member
+ uint64 user-acct-control
+ string last-known-parent
+ }
+ listen {
+ transport = ldap
+ ldap {
+```
The LDAP server to connect to.
May be prefixed with:
- ldaps:// (LDAP over SSL)
- ldapi:// (LDAP over Unix socket)
- ldapc:// (Connectionless LDAP)
+```
+ server = "localhost"
+```
Port to connect on, defaults to 389, will be ignored for LDAP URIs.
+```
+# port = 389
+```
Administrator account for persistent search.
If using SASL + KRB5 these should be commented out.
+```
+ identity = 'cn=admin,dc=example,dc=com'
+ password = mypass
+ options {
+```
timeouts may need to be longer than for normal LDAP queries
if a refresh phase returns a lot of data.
+```
+ res_timeout = 20
+ srv_timelimit = 120
+ idle = 60
+ probes = 3
+ interval = 3
+ reconnection_delay = 10
+ }
+```
SASL parameters to use for binding as the sync user.
+```
+ sasl {
+```
SASL mechanism
+```
+# mech = 'PLAIN'
+```
SASL authorisation identity to proxy.
+```
+# proxy = 'autz_id'
+```
SASL realm. Used for kerberos.
+```
+# realm = 'example.org'
+ }
+```
How big the kernel's receive buffer should be.
+```
+# recv_buff = 1048576
+```
Maximum number of updates to have outstanding
When this number is reached, no more are read, potentially
causing the receive buffer to fill which will cause the
change notifications to queue up on the LDAP server
+```
+# max_outstanding = 65536
+ }
+```
When directories provide cookies to track progress through
the list of changes, these can be provided on every update,
How often to store cookies.
+```
+ cookie_interval = 10
+```
Number of completed changes which will prompt the storing
of a cookie
+```
+ cookie_changes = 100
+```
Persistent searches.
of the directory you are querying), number of syncs to retrieve
entries from the LDAP directory.
+```
+ sync {
+```
Where to start searching in the tree for entries
+```
+ base_dn = "ou=people,dc=example,dc=com"
+```
Only return entries matching this filter
Comment this out if all entries should be returned.
+```
+ filter = "(objectClass=posixAccount)"
+```
Search scope, may be 'base', 'one', 'sub' or 'children'
+```
+ scope = 'sub'
+```
Specify a map of LDAP attributes to FreeRADIUS dictionary attributes.
Protocol specific attributes must be qualified e.g. &Proto.radius.User-Name
+```
+ update {
+ &Proto.radius.User-Name = 'uid'
+ &Password.With-Header = 'userPassword'
+ }
+ }
+# sync {
+# base_dn = "ou=groups,dc=example,dc=com"
+# filter = "(objectClass=groupOfNames)"
+# scope = "sub"
+```
Since there are likely to be multiple members of
a given group, the += operator should be used when
defining a mapping of LDAP attribute "member" to
FreeRADIUS attributes.
+```
+# update {
+# &member += "member"
+# }
+# }
+```
If you are querying Active Directory, you are likely to
want two queries.
added, modified or restored from the Deleted Objects
container.
+```
+# sync {
+# base_dn = 'cn=Users,dc=example,dc=com'
+# filter = '(userAccountControl:1.2.840.113556.1.4.803:=512)'
+# scope = 'sub'
+```
+```
+# update {
+# &Proto.radius.User-Name = 'sAMAccountName'
+# &user-acct-control = 'userAccountControl'
+# }
+# }
+```
Secondly, if you have the Recycle Bin enabled in Active
Directory and wish to be notified about deleted objects,
from. However, lastKnownParent may not be returned when
searching the Global Catalog.
+```
+# sync {
+# base_dn = "CN=Deleted Objects,dc=example,dc=com"
+# filter = '(userAccountControl:1.2.840.113556.1.4.803:=512)'
+# scope = "one"
+```
+```
+# update {
+# &Proto.radius.User-Name = 'sAMAccountName'
+# &user-acct-control = 'userAccountControl'
+# &last-known-parent = 'lastKnownParent'
+# }
+# }
+ }
+```
Provides FreeRADIUS with the last cookie value we received for the sync
- Any other code with &reply.LDAP-Sync.Cookie populated to indicate a cookie value was loaded.
- Any other code without &reply.LDAP-Sync.Cookie populated to indicate no cookie was found.
+```
+ load Cookie {
+ debug_request
+```
If no cookie is returned for https://tools.ietf.org/html/rfc4533[RFC 4533] servers, then the response
to the initial search will be a complete copy of the directory.
presuming the ldap module is enabled and configured with the same
server settings as ldap_sync.
+```
+# if (!&reply.LDAP-Sync.Cookie) {
+# string csn
+```
+```
+# &csn := %concat(%ldap("ldap:///%ldap.uri.safe(%{LDAP-Sync.Directory-Root-DN})?contextCSN?base"), ';')
+# &reply.LDAP-Sync.Cookie := "rid=000,csn=%{csn}"
+# }
+ }
+```
Stores the latest cookie we've received for a sync
The return code of this section is ignored.
+```
+ store Cookie {
+ debug_request
+ }
+```
Notification that a new entry has been added to the LDAP directory
The return code of this section is ignored (for now).
+```
+ recv Add {
+ debug_request
+ }
+```
Notification that an entry has been modified in the LDAP directory
The return code of this section is ignored (for now).
+```
+ recv Modify {
+ debug_request
+ }
+```
Notification that an entry has been modified in the LDAP directory
The return code of this section is ignored (for now).
+```
+ recv Delete {
+ debug_request
+ }
+```
Notification that an entry is still present and unchanged in the LDAP directory.
The return code of this section is ignored (for now).
-
-== Default Configuration
-
```
-server ldap_sync {
- namespace = ldap_sync
- dictionary {
- string member
- uint64 user-acct-control
- string last-known-parent
- }
- listen {
- transport = ldap
- ldap {
- server = "localhost"
-# port = 389
- identity = 'cn=admin,dc=example,dc=com'
- password = mypass
- options {
- res_timeout = 20
- srv_timelimit = 120
- idle = 60
- probes = 3
- interval = 3
- reconnection_delay = 10
- }
- sasl {
-# mech = 'PLAIN'
-# proxy = 'autz_id'
-# realm = 'example.org'
- }
-# recv_buff = 1048576
-# max_outstanding = 65536
- }
- cookie_interval = 10
- cookie_changes = 100
- sync {
- base_dn = "ou=people,dc=example,dc=com"
- filter = "(objectClass=posixAccount)"
- scope = 'sub'
- update {
- &Proto.radius.User-Name = 'uid'
- &Password.With-Header = 'userPassword'
- }
- }
-# sync {
-# base_dn = "ou=groups,dc=example,dc=com"
-# filter = "(objectClass=groupOfNames)"
-# scope = "sub"
-# update {
-# &member += "member"
-# }
-# }
-# sync {
-# base_dn = 'cn=Users,dc=example,dc=com'
-# filter = '(userAccountControl:1.2.840.113556.1.4.803:=512)'
-# scope = 'sub'
-# update {
-# &Proto.radius.User-Name = 'sAMAccountName'
-# &user-acct-control = 'userAccountControl'
-# }
-# }
-# sync {
-# base_dn = "CN=Deleted Objects,dc=example,dc=com"
-# filter = '(userAccountControl:1.2.840.113556.1.4.803:=512)'
-# scope = "one"
-# update {
-# &Proto.radius.User-Name = 'sAMAccountName'
-# &user-acct-control = 'userAccountControl'
-# &last-known-parent = 'lastKnownParent'
-# }
-# }
- }
- load Cookie {
- debug_request
-# if (!&reply.LDAP-Sync.Cookie) {
-# string csn
-# &csn := %concat(%ldap("ldap:///%ldap.uri.safe(%{LDAP-Sync.Directory-Root-DN})?contextCSN?base"), ';')
-# &reply.LDAP-Sync.Cookie := "rid=000,csn=%{csn}"
-# }
- }
- store Cookie {
- debug_request
- }
- recv Add {
- debug_request
- }
- recv Modify {
- debug_request
- }
- recv Delete {
- debug_request
- }
recv Present {
debug_request
}
}
```
+
+== Default Configuration
+
+```
+```
The `load` virtual server does load testing.
+```
+server load {
+ namespace = radius
+```
Use `listen load { ... }` in any virtual server to do load
testing against that server.
+```
+ listen load {
+```
The main module is the proto module, even though we're
operating in the RADIUS namespace.
+```
+ proto = load
+```
This is a valid Packet-Type for the current `namespace`
+```
+ type = Access-Request
+```
For now, only 'step' transport is available.
+```
+ transport = step
+```
Do load testing in increasing steps.
+```
+ step {
+```
Filename with input packet. This is in the
same format as used by `radclient`.
+```
+ filename = ${confdir}/load.txt
+```
Where the statistics file goes, in CSV format.
- blocked - 1 = true, 0 = false. We're refusing
to enqueue more packets until we get responses
to the outstanding requests.
+```
+ csv = ${confdir}/stats.csv
+```
How many packets/s to start with.
+```
+ start_pps = 100
+```
How many packet/s to end up at.
it prints the final statistics, and makes
the server exit.
+```
+ max_pps = 2000
+```
How long we send packets for (in seconds) at each step.
+```
+ duration = 10
+```
How big of a packet/s step to jump after running each test.
+```
+ step = 200
+```
We don't want to overload the server. If
the server cannot process packets quickly
temporarily stop sending packets. Once the
backlog is low enough, it will continue.
+```
+ max_backlog = 1000
+```
How many packets to send immediately in
parallel, without waiting for a response.
When a reply is received, a new request may
be sent.
+```
+ parallel = 25
+ }
+ }
+```
The rest of the recv/send sections are protocol specific, and are
taken from the `namespace`.
-
-
-
-
-
-== Default Configuration
-
```
-server load {
- namespace = radius
- listen load {
- proto = load
- type = Access-Request
- transport = step
- step {
- filename = ${confdir}/load.txt
- csv = ${confdir}/stats.csv
- start_pps = 100
- max_pps = 2000
- duration = 10
- step = 200
- max_backlog = 1000
- parallel = 25
- }
- }
recv Access-Request {
accept
}
+
authenticate pap {
pap
}
+
send Access-Accept {
ok
}
+
send Access-Reject {
ok
}
+
}
```
+
+== Default Configuration
+
+```
+```
This information is usually a list of attributes such as:
+```
+# NAS-IP-Address (or NAS-IPv6 address)
+# NAS-Identifier
+# User-Name
+# Acct-Session-Id
+```
CoA packets can be originated when a normal Access-Request or
Accounting-Request packet is received. Simply create a subrequest,
and call the `radius` module to send the packet.
+```
+# subrequest Disconnect-Request {
+# &User-Name = &parent.request.User-Name
+# &Acct-Session-Id = &parent.request.Acct-Session-Id
+# &NAS-IP-Address = &parent.NAS-IP-Address}
+# ...
+# }
+```
NOTE: This functionality is configured differently from v3.
example, and copy the "subrequest" section to the virtual server
that is actually receiving `link:https://freeradius.org/rfc/rfc2866.html#Accounting-Request[Accounting-Request]` packets.
+```
+server originate-coa.example.com {
+ namespace = radius
+```
Listen on the Accounting port.
+```
+ listen {
+ type = Accounting-Request
+ transport = udp
+ udp {
+ ipaddr = *
+ port = 1812
+ }
+ }
+recv Accounting-Request {
+ subrequest Disconnect-Request {
+```
The subrequest begins empty, so copy all necessary
attributes over.
+```
+ &request.User-Name := &parent.request.User-Name
+ &request.Acct-Session-Id := &parent.request.Acct-Session-Id
+ &request.NAS-Identifier := &parent.request.NAS-Identifier
+ &request.NAS-IP-Address := &parent.request.NAS-IP-Addres
+ &request.NAS-IPv6-Address := &parent.request.NAS-IPv6-Address
+ &request.NAS-Port := &parent.request.NAS-Port
+ &request.Framed-IP-Address := &parent.request.Framed-IP-Address
+```
Call the `radius` module to send a CoA packet.
See the `radius` module for more documentation on
how it works.
+```
+ radius.coa
+ }
+} # recv Accounting-Request
+}
+```
== Default Configuration
```
-# NAS-IP-Address (or NAS-IPv6 address)
-# NAS-Identifier
-# User-Name
-# Acct-Session-Id
-# subrequest Disconnect-Request {
-# &User-Name = &parent.request.User-Name
-# &Acct-Session-Id = &parent.request.Acct-Session-Id
-# &NAS-IP-Address = &parent.NAS-IP-Address}
-# ...
-# }
-server originate-coa.example.com {
- namespace = radius
- listen {
- type = Accounting-Request
- transport = udp
- udp {
- ipaddr = *
- port = 1812
- }
- }
-recv Accounting-Request {
- subrequest Disconnect-Request {
- &request.User-Name := &parent.request.User-Name
- &request.Acct-Session-Id := &parent.request.Acct-Session-Id
- &request.NAS-Identifier := &parent.request.NAS-Identifier
- &request.NAS-IP-Address := &parent.request.NAS-IP-Addres
- &request.NAS-IPv6-Address := &parent.request.NAS-IPv6-Address
- &request.NAS-Port := &parent.request.NAS-Port
- &request.Framed-IP-Address := &parent.request.Framed-IP-Address
- radius.coa
- }
-} # recv Accounting-Request
-}
```
WARNING: This configuration file has not been updated for v4,
and therefore WILL NOT WORK. Please do not use it.
+```
+# This is a virtual server that handles *only* inner tunnel
+# requests for EAP-TTLS and PEAP types.
+```
+```
+server proxy-inner-tunnel {
+```
This example is very simple. All inner tunnel requests get
proxied to another RADIUS server.
+```
+recv Access-Request {
+```
Do other things here, as necessary.
You should update this to be one of your realms.
+```
+ &control.Proxy-To-Realm := "example.com"
+}
+authenticate eap {
+```
This is necessary so that the inner tunnel EAP-MSCHAPv2
method can be called. That method takes care of turning
EAP-MSCHAPv2 into plain MS-CHAPv2, if necessary.
-
-
-== Default Configuration
-
```
-# This is a virtual server that handles *only* inner tunnel
-# requests for EAP-TTLS and PEAP types.
-server proxy-inner-tunnel {
-recv Access-Request {
- &control.Proxy-To-Realm := "example.com"
-}
-authenticate eap {
eap
}
+
post-proxy {
}
}
```
+
+== Default Configuration
+
+```
+```
+```
+server proxy {
+ namespace = radius
+ listen {
+ type = Access-Request
+ transport = udp
+ udp {
+ ipaddr = *
+ port = 2812
+ }
+ }
+```
## Packet Processing sections
### Receive Access-Request packets
-
-
-
-== Default Configuration
-
```
-server proxy {
- namespace = radius
- listen {
- type = Access-Request
- transport = udp
- udp {
- ipaddr = *
- port = 2812
- }
- }
recv Access-Request {
update control {
&Auth-Type := proxy
}
}
+
authenticate proxy {
radius
}
+
}
```
+
+== Default Configuration
+
+```
+```
Acct-Type { } is no longer supported.
+```
+server radius-acct {
+namespace = radius
+```
This is all the same as before
+```
+listen {
+ type = acct
+ ipaddr = *
+ port = 3000
+}
+```
"preacct"
+```
+recv Accounting-Request {
+ ok
+}
+```
"accounting"
-
-
-== Default Configuration
-
```
-server radius-acct {
-namespace = radius
-listen {
- type = acct
- ipaddr = *
- port = 3000
-}
-recv Accounting-Request {
- ok
-}
send Accounting-Response {
ok
}
+
} # server radius-acct
```
+
+== Default Configuration
+
+```
+```
system status this virtual server is able to manipulate the outcome of the
controlled virtual server.
-Firstly, the authorize section of this virtual server will need to be
+Firstly, the "recv Status-Server" section of this virtual server will need to be
amended to check the status of the external resources and to set the status
of the control module appropriately, as described in the inline comments
below...
whose task is to perform the resource checks and sets the status of the
"control module"
+```
+server resource-check {
+namespace = radius
+listen {
+ transport = udp
+ udp {
+ ipaddr = 127.0.0.1
+ port = 18122
+ }
+ type = Status-Server
+}
+recv Status-Server {
+```
In this example we check whether a PostgreSQL database is in
recovery (or inaccessible) and when this is the case we fail the
interval to avoid buildup of checks when resources do not respond.
See rlm_exec for details.
+```
+ if ("%sql('SELECT pg_is_in_recovery()')" != "f") {
+```
Fail the db_online module, if it isn't already
-
-
-Set the db_online module status to alive, if it isn't already
-
-
-
-
-== Default Configuration
-
```
-server resource-check {
-namespace = radius
-listen {
- transport = udp
- udp {
- ipaddr = 127.0.0.1
- port = 18122
- }
- type = Status-Server
-}
-recv Status-Server {
- if ("%sql('SELECT pg_is_in_recovery()')" != "f") {
if (%db_online() != "fail") {
%db_online(fail)
}
+
} else {
+
+```
+Set the db_online module status to alive, if it isn't already
+```
if (%db_online() != "alive") {
%db_online(alive)
}
+
}
+
}
+
}
```
+
+== Default Configuration
+
+```
+```
WARNING: This configuration file has not been updated for v4,
and therefore WILL NOT WORK. Please do not use it.
+```
+# This is a sample configuration for robust proxy accounting.
+# accounting packets are proxied, OR logged locally if all
+# home servers are down. When the home servers come back up,
+# the accounting packets are forwarded.
+```
+```
+# This method enables the server to proxy all packets to the
+# home servers when they're up, AND to avoid writing to the
+# detail file in most situations.
+```
+```
+# In most situations, proxying of accounting messages is done
+# in a "pass-through" fashion. If the home server does not
+# respond, then the proxy server does not respond to the NAS.
+# That means that the NAS must retransmit packets, sometimes
+# forever. This example shows how the proxy server can still
+# respond to the NAS, even if all home servers are down.
+```
+```
+# This configuration could be done MUCH more simply if ALL
+# packets were written to the detail file. But that would
+# involve a lot more disk writes, which may not be a good idea.
+```
+```
+# NOTE: This file is NOT meant to be used as-is. It needs to be
+# edited to match your local configuration.
+```
(1) Define two home servers.
+```
+home_server home1.example.com {
+ type = acct
+ ipaddr = 192.0.2.10
+ port = 1813
+ secret = testing123
+```
Mark this home server alive ONLY when it starts being responsive
+```
+ status_check = request
+ username = "test_user_status_check"
+```
Set the response timeout aggressively low.
You MAY have to increase this, depending on tests with
your local installation.
+```
+ response_window = 6
+}
+home_server home2.example.com {
+ type = acct
+ ipaddr = 192.0.2.20
+ port = 1813
+ secret = testing123
+```
Mark this home server alive ONLY when it starts being responsive
+```
+ status_check = request
+ username = "test_user_status_check"
+```
Set the response timeout aggressively low.
You MAY have to increase this, depending on tests with
your local installation.
+```
+ response_window = 6
+}
+```
(2) Put all of the servers into a pool.
+```
+home_server_pool acct_pool.example.com {
+ type = load-balance # other types are OK, too.
+ home_server = home1.example.com
+ home_server = home2.example.com
+```
add more home_server's here.
for pre/post-proxy policies
+```
+ virtual_server = home.example.com
+}
+```
(3) Define a realm for these home servers.
It should NOT be used as part of normal proxying decisions!
+```
+realm acct_realm.example.com {
+ acct_pool = acct_pool.example.com
+}
+```
(4) Define a detail file writer.
See raddb/modules/detail.example.com
(5) Define a virtual server to handle pre/post-proxy re-writing
+```
+server home.example.com {
+ pre-proxy {
+```
Insert pre-proxy rules here
+```
+ }
+ post-proxy {
+```
Insert post-proxy rules here
This will be called when the CURRENT packet failed
"detail" file, where it will be read, and sent to
another home server.
+```
+ Post-Proxy-Type Fail-Accounting {
+ detail.example.com
+ }
+```
This section is run when there are problems
proxying Access-Request packets
+```
+ Post-Proxy-Type Fail-Authentication {
+```
add policies here
+```
+ }
+ }
+```
Read accounting packets from the detail file(s) for
the home server.
below. Having two "listen" sections reading detail files
from the same directory WILL cause problems. The packets
may be read by one, the other, or both "listen" sections.
+```
+ listen {
+ type = detail
+ filename = "${radacctdir}/detail.example.com/detail-*:*"
+ load_factor = 10
+ }
+```
All packets read from the detail file are proxied back to
the home servers.
When the home servers come back up, the packets are forwarded,
and the detail file processed as normal.
+```
+ recv Accounting-Request {
+```
You may want accounting policies here...
+```
+ &control.Proxy-To-Realm := "acct_realm.example.com"
+ }
+}
+```
== Default Configuration
```
-# This is a sample configuration for robust proxy accounting.
-# accounting packets are proxied, OR logged locally if all
-# home servers are down. When the home servers come back up,
-# the accounting packets are forwarded.
-# This method enables the server to proxy all packets to the
-# home servers when they're up, AND to avoid writing to the
-# detail file in most situations.
-# In most situations, proxying of accounting messages is done
-# in a "pass-through" fashion. If the home server does not
-# respond, then the proxy server does not respond to the NAS.
-# That means that the NAS must retransmit packets, sometimes
-# forever. This example shows how the proxy server can still
-# respond to the NAS, even if all home servers are down.
-# This configuration could be done MUCH more simply if ALL
-# packets were written to the detail file. But that would
-# involve a lot more disk writes, which may not be a good idea.
-# NOTE: This file is NOT meant to be used as-is. It needs to be
-# edited to match your local configuration.
-home_server home1.example.com {
- type = acct
- ipaddr = 192.0.2.10
- port = 1813
- secret = testing123
- status_check = request
- username = "test_user_status_check"
- response_window = 6
-}
-home_server home2.example.com {
- type = acct
- ipaddr = 192.0.2.20
- port = 1813
- secret = testing123
- status_check = request
- username = "test_user_status_check"
- response_window = 6
-}
-home_server_pool acct_pool.example.com {
- type = load-balance # other types are OK, too.
- home_server = home1.example.com
- home_server = home2.example.com
- virtual_server = home.example.com
-}
-realm acct_realm.example.com {
- acct_pool = acct_pool.example.com
-}
-server home.example.com {
- pre-proxy {
- }
- post-proxy {
- Post-Proxy-Type Fail-Accounting {
- detail.example.com
- }
- Post-Proxy-Type Fail-Authentication {
- }
- }
- listen {
- type = detail
- filename = "${radacctdir}/detail.example.com/detail-*:*"
- load_factor = 10
- }
- recv Accounting-Request {
- &control.Proxy-To-Realm := "acct_realm.example.com"
- }
-}
```
-
-
-
-
-
-
-
-
-
-
-
-We recommend that you list ONLY management clients here.
-i.e. NOT your NASes or Access Points, and for an ISP,
-DEFINITELY not any RADIUS servers that are proxying packets
-to you.
-
-If you do NOT list a client here, then any client that is
-globally defined (i.e. all of them) will be able to query
-these statistics.
-
-Do you really want your partners seeing the internal details
-of what your RADIUS server is doing?
-
-
-
-Receive a Status-Server packet
-
-
-Add statistics based on the Vendor-Specific.FreeRADIUS.Stats4-* queries.
-
-
-
-
-
-
-
-
-Due to internal limitations, the statistics might not be exactly up
-to date. Do not expect all of the numbers to add up perfectly.
-
-
-== Default Configuration
-
```
# A virtual server to handle ONLY Status-Server packets.
+```
+
+```
# Server statistics can be queried with a properly formatted
# Status-Server request. See dictionary.freeradius for comments.
+```
+
+```
# If radiusd.conf has "status_server = yes", then any client
# will be able to send a Status-Server packet to any port
# (listen section type "auth", "acct", or "status"), and the
# server will respond.
+```
+
+```
# If radiusd.conf has "status_server = no", then the server will
# ignore Status-Server packets to "auth" and "acct" ports. It
# will respond only if the Status-Server packet is sent to a
# "status" port.
+```
+
+```
# The server statistics are available ONLY on socket of type
# "status". Queries for statistics sent to any other port
# are ignored.
+```
+
+```
# Similarly, a socket of type "status" will not process
# authentication or accounting packets. This is for security.
+```
+
+
+
+```
server status {
namespace = radius
listen {
ipaddr = 127.0.0.1
port = 18121
}
+
type = Status-Server
}
+
+```
+
+We recommend that you list ONLY management clients here.
+i.e. NOT your NASes or Access Points, and for an ISP,
+DEFINITELY not any RADIUS servers that are proxying packets
+to you.
+
+If you do NOT list a client here, then any client that is
+globally defined (i.e. all of them) will be able to query
+these statistics.
+
+Do you really want your partners seeing the internal details
+of what your RADIUS server is doing?
+
+```
client admin {
ipaddr = 127.0.0.1
secret = adminsecret
}
+
+```
+
+Receive a Status-Server packet
+
+```
recv Status-Server {
+```
+
+Add statistics based on the Vendor-Specific.FreeRADIUS.Stats4-* queries.
+
+```
stats
ok
}
}
+
# Statistics can be queried via a number of methods:
+```
+
+```
# All packets received/sent by the server (1 = auth, 2 = acct)
# Vendor-Specific.FreeRADIUS.Stats4-Type = Global
+```
+
+```
# All packets for a particular client (globally defined)
# Vendor-Specific.FreeRADIUS.Stats4-Type = Client
# Vendor-Specific.FreeRADIUS.Stats4-IPv4-Address = 192.0.2.1
+```
+
+```
# All packets for a client attached to a "listen" ip/port
# Vendor-Specific.FreeRADIUS.Stats4-Type = Listener
# Vendor-Specific.FreeRADIUS.Stats4-IPv4-Address = 192.0.2.1
# Vendor-Specific.FreeRADIUS.Stats4-port = 1812
```
+
+
+
+Due to internal limitations, the statistics might not be exactly up
+to date. Do not expect all of the numbers to add up perfectly.
+
+```
+
+== Default Configuration
+
+```
+```
The `tacacs` virtual server processes TACACS+ packets.
+```
+# https://www.rfc-editor.org/rfc/rfc8907
+```
This is the `tacacs` virtual server.
+```
+server tacacs {
+```
namespace:: Needs to be "tacacs" for TACACS+ functionality.
+```
+ namespace = tacacs
+```
### TACACS+ Configuration
All of the configuration for processing TACACS+ packets goes here.
+```
+ tacacs {
+```
#### Authentication subsection
packets. At this time, there is no configuration
needed for other packet types.
+```
+ Authentication {
+```
session:: Controls how ongoing
(multi-round) sessions are handled
It is the only authentication type which supports
sending challenges for further data.
+```
+ session {
+```
max:: The maximum number of concurrent ongoing sessions
+```
+# max = 4096
+```
max_rounds: The maximum number of round trips which are allowed
Some broken clients will send packets in a loop, forever.
This configuration helps to catch and prevent that.
+```
+ max_rounds = 4
+```
timeout:: How long to wait before expiring a
session.
containing the previously sent
state value is received.
+```
+# timeout = 15
+ }
+ }
+```
There is currently no configuration for other packet types.
+```
+ }
+ listen {
+```
type:: The type of packet to accept.
As described in https://tools.ietf.org/html/rfc8907[RFC 8907], the packet types are:
+```
+ type = Authentication-Start
+ type = Authentication-Continue
+ type = Authorization-Request
+ type = Accounting-Request
+```
transport:: The transport protocol.
Only `tcp` is allowed. TACACS+ does not use UDP or TLS.
+```
+ transport = tcp
+```
## Protocols
tcp { ... }:: TCP is configured here.
+```
+ tcp {
+```
NOTE: Don't change anything if you are not sure.
The port should be 49 for a production network.
+```
+ port = 49
+```
ipaddr:: The IP address where we accept packets.
+```
+ ipaddr = *
+```
interface:: Interface to bind to.
+```
+# interface = eth0
+```
max_packet_size:: Our max packet size. may be different from the parent.
+```
+# max_packet_size = 4096
+```
recv_buff:: How big the kernel's receive buffer should be.
+```
+# recv_buff = 1048576
+```
send_buff:: How big the kernel's send buffer should be.
+```
+# send_buff = 1048576
+```
src_ipaddr:: IP we open our socket on.
+```
+# src_ipaddr = ""
+ }
+```
limit:: limits for this socket.
Limits are used to prevent "run-away" problems.
+```
+ limit {
+```
max_connections:: The maximum number of
connected sockets which will be accepted
sockets (e.g. TCP), then this configuration
item is ignored.
+```
+ max_connections = 256
+```
idle_timeout:: Time after which idle
connections are deleted.
Useful range of values: 5 to 600
+```
+ idle_timeout = 60.0
+ }
+ }
+```
## Clients
See the main `clients.conf` file for documentation on the `client` section.
+```
+ client tacacs {
+ ipaddr = 127.0.0.1
+```
This has to be specified for all TACACS+ clients.
There is no standard for TACACS+ over UDP.
+```
+ proto = tcp
+```
The TACACS+ key, or secret. If a secret is defined, then
it will be used. All packets coming from this client MUST be
are sent over the network in the clear. This practice is
not recommended.
+```
+ secret = testing123
+ }
+```
## Authentication-Start
the packet contains `Authentication-Type = PAP` _and_ the passwords in LDAP are stored
in "crypt" or hashed form.
+```
+ recv Authentication-Start {
+ -sql
+ }
+ authenticate PAP {
+ pap
+ }
+ authenticate CHAP {
+ chap
+ }
+ authenticate MSCHAP {
+ mschap
+ }
+ authenticate MSCHAPv2 {
+ mschap
+ }
+```
LDAP authentication will only work with PAP authentication
+```
+# authenticate ldap {
+# if (Authentication-Type != PAP) {
+# %log.warn("The packet is not PAP. LDAP authentication is likely to fail!")
+# }
+```
+```
+# ldap
+# }
+```
The automatic state machine will ensure that both User-Name
and User-Password have been provided by this point making
to request the extra data, which will be in &User-Message in
the next packet (if the client provides it)
+```
+ authenticate ASCII {
+ pap
+ }
+```
### Send
Note that "follow" is officially deprecated, and is not supported.
+```
+ send Authentication-Pass {
+ &reply.Server-Message := "Hello %{User-Name}"
+```
Call an instance of `linelog` to log the authentication success
- equivalent to the previous log `auth = yes` option in v3.
See `mods-enabled/linelog` for message formats and destinations.
+```
+# log_auth_authentication_pass
+ }
+ send Authentication-Fail {
+ &reply.Server-Message := "Failed login!"
+```
Call an instance of `linelog` to log the authentication failure
- equivalent to the previous log `auth = yes` option in v3.
See `mods-enabled/linelog` for message formats and destinations.
+```
+# log_auth_authentication_fail
+ }
+```
With ASCII methods, GetUser and GetPass typically send a prompt
for the client to present to the user.
+```
+ send Authentication-GetUser {
+ &reply.Server-Message := "Username:"
+ }
+ send Authentication-GetPass {
+ &reply.Server-Message := "Password:"
+ }
+```
## Authentication-Continue
run an `authenticate ... { }` section. It will then call
one of the `send` sections to send the reply.
+```
+ recv Authentication-Continue {
+```
https://tools.ietf.org/id/draft-ietf-opsawg-07.html#rfc.section.4.3
+```
+ "%{Authentication-Continue-Flags}"
+ "%{User-Message}"
+ "%{Data}"
+ }
+```
## Authorization
### Recv
+```
+ recv Authorization-Request {
+ "%{Authentication-Method}"
+ "%{Privilege-Level}"
+ "%{Authentication-Type}"
+ "%{Authentication-Service}"
+ "%{User-Name}"
+ "%{Client-Port}"
+ "%{Remote-Address}"
+ "%{Argument-List}"
+ }
+```
### Send
Add the arguments to whatever the user entered.
+```
+ send Authorization-Pass-Add {
+ &reply.Authorization-Status := Pass-Add
+ &reply.Server-Message := "authorization-response-server"
+ &reply.Data := "authorization-response-data"
+ &reply.Argument-List := "key1=var1"
+ }
+```
Replace whatever the user entered with the following arguments
+```
+ send Authorization-Pass-Reply {
+ &reply.Authorization-Status := Pass-Repl
+ &reply.Server-Message := "authorization-response-server"
+ &reply.Data := "authorization-response-data"
+ &reply.Argument-List := "key1=var1"
+ }
+```
Reject the request
+```
+ send Authorization-Fail {
+ &reply.Authorization-Status := Fail
+ }
+```
## Accounting
### Recv
+```
+ recv Accounting-Request {
+```
Create a 'detail'ed log of the packets.
+```
+ detail
+ }
+```
First packet for a session
+```
+ accounting Start {
+ }
+```
Updates a previous start
+```
+ accounting Watchdog-Update {
+ }
+```
Updates a session
+```
+ accounting Watchdog {
+ }
+```
Stops a session
+```
+ accounting Stop {
+ }
+```
### Send
+```
+ send Accounting-Success {
+ &reply.Server-Message := "Success"
+ }
+ send Accounting-Error {
+ &reply.Server-Message := "Error"
+ }
+```
NOTE: Proxying of TACACS+ requests is NOT supported.
+```
+}
+```
== Default Configuration
```
-# https://www.rfc-editor.org/rfc/rfc8907
-server tacacs {
- namespace = tacacs
- tacacs {
- Authentication {
- session {
-# max = 4096
- max_rounds = 4
-# timeout = 15
- }
- }
- }
- listen {
- type = Authentication-Start
- type = Authentication-Continue
- type = Authorization-Request
- type = Accounting-Request
- transport = tcp
- tcp {
- port = 49
- ipaddr = *
-# interface = eth0
-# max_packet_size = 4096
-# recv_buff = 1048576
-# send_buff = 1048576
-# src_ipaddr = ""
- }
- limit {
- max_connections = 256
- idle_timeout = 60.0
- }
- }
- client tacacs {
- ipaddr = 127.0.0.1
- proto = tcp
- secret = testing123
- }
- recv Authentication-Start {
- -sql
- }
- authenticate PAP {
- pap
- }
- authenticate CHAP {
- chap
- }
- authenticate MSCHAP {
- mschap
- }
- authenticate MSCHAPv2 {
- mschap
- }
-# authenticate ldap {
-# if (Authentication-Type != PAP) {
-# %log.warn("The packet is not PAP. LDAP authentication is likely to fail!")
-# }
-# ldap
-# }
- authenticate ASCII {
- pap
- }
- send Authentication-Pass {
- &reply.Server-Message := "Hello %{User-Name}"
-# log_auth_authentication_pass
- }
- send Authentication-Fail {
- &reply.Server-Message := "Failed login!"
-# log_auth_authentication_fail
- }
- send Authentication-GetUser {
- &reply.Server-Message := "Username:"
- }
- send Authentication-GetPass {
- &reply.Server-Message := "Password:"
- }
- recv Authentication-Continue {
- "%{Authentication-Continue-Flags}"
- "%{User-Message}"
- "%{Data}"
- }
- recv Authorization-Request {
- "%{Authentication-Method}"
- "%{Privilege-Level}"
- "%{Authentication-Type}"
- "%{Authentication-Service}"
- "%{User-Name}"
- "%{Client-Port}"
- "%{Remote-Address}"
- "%{Argument-List}"
- }
- send Authorization-Pass-Add {
- &reply.Authorization-Status := Pass-Add
- &reply.Server-Message := "authorization-response-server"
- &reply.Data := "authorization-response-data"
- &reply.Argument-List := "key1=var1"
- }
- send Authorization-Pass-Reply {
- &reply.Authorization-Status := Pass-Repl
- &reply.Server-Message := "authorization-response-server"
- &reply.Data := "authorization-response-data"
- &reply.Argument-List := "key1=var1"
- }
- send Authorization-Fail {
- &reply.Authorization-Status := Fail
- }
- recv Accounting-Request {
- detail
- }
- accounting Start {
- }
- accounting Watchdog-Update {
- }
- accounting Watchdog {
- }
- accounting Stop {
- }
- send Accounting-Success {
- &reply.Server-Message := "Success"
- }
- send Accounting-Error {
- &reply.Server-Message := "Error"
- }
-}
```
## Virtual Server
+```
+server load {
+```
For now, only "namespace = radius" is supported.
+```
+ namespace = radius
+```
Listen
+```
+ listen {
+```
Any packet types are supported.
However, only one packet type should be specified.
+```
+ type = Access-Request
+```
The load generator uses the "load" transport.
+```
+ transport = load
+```
load:: Configuration for load testing.
+```
+ load {
+```
filename:: File which contains one test packet.
The Packet-Type attribute is also ignored.
+```
+ filename = ${confdir}/input.txt
+```
csv:: Where the output statistics are printed,
in CSV format.
The first line of the output file contains a header
which describes the columns.
+```
+ csv = ${logdir}/stats.csv
+```
start_pps:: What packet/s rate to start at.
+```
+ start_pps = 600
+```
max_pps:: What maximum packet/s rate to end at.
+```
+ max_pps = 1000
+```
duration:: How long in seconds to run each test.
+```
+ duration = 5
+```
step:: Once `duration` is done, increase
the PPS by this rate.
point, the test stops, and no more packets
are generated.
+```
+ step = 20
+```
parallel: How many packets to send at once.
second. So to send 50K pps, set "pps =
50K" and "parallel = 10".
+```
+ parallel = 1
+```
max_backlog:: The maximum allowed backlog
in milliseconds, not packets.
limit, then the load generator switches
back to sending at the "pps" rate.
+```
+ max_backlog = 1000
+```
repeat:: whether or not to start again after
we reach max_pps
+```
+ repeat = no
+ }
+ }
+```
Put any logic here.
-
-
-
-
-== Default Configuration
-
```
-server load {
- namespace = radius
- listen {
- type = Access-Request
- transport = load
- load {
- filename = ${confdir}/input.txt
- csv = ${logdir}/stats.csv
- start_pps = 600
- max_pps = 1000
- duration = 5
- step = 20
- parallel = 1
- max_backlog = 1000
- repeat = no
- }
- }
recv Access-Request {
accept
}
+
authenticate pap {
pap
}
+
send Access-Accept {
ok
}
+
send Access-Reject {
ok
}
}
```
+
+== Default Configuration
+
+```
+```
+++ /dev/null
-
-This virtual server controls caching of TLS sessions.
-
-When a TLS session is used, the server will automatically create
-the following attributes in the session-state list. These attributes
-are the ones for the *server* certificate.
-
-
-If a client certificate is required (e.g. EAP-TLS or sometimes PEAP / TTLS),
-the following attributes are also created in the session-state list:
-
-
-
-
-
-
-This section can be run to verify a client certificate if
-additional checks need to be performed beyond standard
-checks verification against a trust chain, CRLs and OCSP.
-
-Attributes extracted from the certificates forming the
-client certificate chain will be in the session state list.
-
-Returning 'ok', 'updated' or 'noop' will cause the verification
-to succeed. Other return codes will cause the verification
-to fail.
-
-
-
-This section is run whenever the server needs to read an
-entry from the TLS session cache.
-
-It should read the attribute &session-state.TLS-Session-Data
-from the cache, along with any other attributes which
-were in the cache
-
-On success it should return 'ok' or 'updated'.
-
-The return code has no real effect on session processing
-and will just cause the server to emit a warning.
-
-
-
-
-This section is run whenever the server needs to write an
-entry to the TLS session cache.
-
-It should write the attribute &session-state.Session-Data
-to the cache, along with any other attributes which
-need to be cached.
-
-On success it should return 'ok' or 'updated'.
-
-The return code has no real effect on session processing
-and will just cause the server to emit a warning.
-
-
-
-
-This section is run whenever the server needs to delete an
-entry from the TLS session cache.
-
-On success it should return 'ok', 'updated', 'noop' or 'notfound'
-
-The return code has no real effect on session processing
-and will just cause the server to emit a warning.
-
-
-
-
-This section is run after certificate attributes are added
-to the request list, and before performing OCSP validation.
-
-It should read the attribute &control.TLS-OCSP-Cert-Valid
-from the cache.
-
-On success it should return 'ok', 'updated', 'noop' or 'notfound'
-To force OCSP validation failure, it should return 'reject'.
-
-
-
-
-This section is run after OCSP validation has completed.
-
-It should write the attribute &reply.TLS-OCSP-Cert-Valid
-to the cache.
-
-On success it should return 'ok' or 'updated'.
-
-The return code has no real effect on session processing
-and will just cause the server to emit a warning.
-
-
-
-== Default Configuration
-
-```
-# TLS-Cert-Serial
-# TLS-Cert-Expiration
-# TLS-Cert-Subject
-# TLS-Cert-Issuer
-# TLS-Cert-Common-Name
-# TLS-Cert-Subject-Alt-Name-Email
-# TLS-Client-Cert-Serial
-# TLS-Client-Cert-Expiration
-# TLS-Client-Cert-Subject
-# TLS-Client-Cert-Issuer
-# TLS-Client-Cert-Common-Name
-# TLS-Client-Cert-Subject-Alt-Name-Email
-server tls-cache {
- namespace = tls
- verify certificate {
- ok
- }
- load session {
- &control.Cache-Allow-Insert := no
- cache_tls_session
- }
- store session {
- &control.Cache-TTL := 0
- cache_tls_session
- }
- clear session {
- &control.Cache-TTL := 0
- &control.Cache-Allow-Insert := no
- cache_tls_session
- }
- load ocsp-state {
- &control.Cache-Allow-Insert := no
- cache_ocsp
- }
- store ocsp-state {
- &control.Cache-TTL := "%{&reply.TLS-OCSP-Next-Update * -1}"
- &control.Cache-Allow-Merge := no
- cache_ocsp
- }
-}
-```
the following attributes in the session-state list. These attributes
are the ones for the *server* certificate.
+```
+# TLS-Cert-Serial
+# TLS-Cert-Expiration
+# TLS-Cert-Subject
+# TLS-Cert-Issuer
+# TLS-Cert-Common-Name
+# TLS-Cert-Subject-Alt-Name-Email
+```
If a client certificate is required (e.g. EAP-TLS or sometimes PEAP / TTLS),
the following attributes are also created in the session-state list:
+```
+# TLS-Client-Cert-Serial
+# TLS-Client-Cert-Expiration
+# TLS-Client-Cert-Subject
+# TLS-Client-Cert-Issuer
+# TLS-Client-Cert-Common-Name
+# TLS-Client-Cert-Subject-Alt-Name-Email
+```
+```
+server tls-cache {
+ namespace = tls_cache
+```
This section is run whenever the server needs to read an
entry from the TLS session cache.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
+```
+ load tls-session {
+ update control {
+ Cache-Allow-Insert := no
+ }
+ cache_tls_session
+ }
+```
This section is run whenever the server needs to write an
entry to the TLS session cache.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
+```
+ store tls-session {
+ update control {
+ Cache-TTL := 0
+ }
+ cache_tls_session
+ }
+```
This section is run whenever the server needs to delete an
entry from the TLS session cache.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
+```
+ clear tls-session {
+ update control {
+ Cache-TTL := 0
+ Cache-Allow-Insert := no
+ }
+ cache_tls_session
+ }
+```
This section is run after certificate attributes are added
to the request list, and before performing OCSP validation.
On success it should return 'ok', 'updated', 'noop' or 'notfound'
To force OCSP validation failure, it should return 'reject'.
+```
+ load ocsp-state {
+ update control {
+ Cache-Allow-Insert := no
+ }
+ cache_ocsp
+ }
+```
This section is run after OCSP validation has completed.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
-
-== Default Configuration
-
```
-# TLS-Cert-Serial
-# TLS-Cert-Expiration
-# TLS-Cert-Subject
-# TLS-Cert-Issuer
-# TLS-Cert-Common-Name
-# TLS-Cert-Subject-Alt-Name-Email
-# TLS-Client-Cert-Serial
-# TLS-Client-Cert-Expiration
-# TLS-Client-Cert-Subject
-# TLS-Client-Cert-Issuer
-# TLS-Client-Cert-Common-Name
-# TLS-Client-Cert-Subject-Alt-Name-Email
-server tls-cache {
- namespace = tls_cache
- load tls-session {
- update control {
- Cache-Allow-Insert := no
- }
- cache_tls_session
- }
- store tls-session {
- update control {
- Cache-TTL := 0
- }
- cache_tls_session
- }
- clear tls-session {
- update control {
- Cache-TTL := 0
- Cache-Allow-Insert := no
- }
- cache_tls_session
- }
- load ocsp-state {
- update control {
- Cache-Allow-Insert := no
- }
- cache_ocsp
- }
store ocsp-state {
update control {
Cache-TTL := "%{expr:&reply.TLS-OCSP-Next-Update * -1}"
}
}
```
+
+== Default Configuration
+
+```
+```
Certificates are decoded into nested attributes e.g.
+```
+# TLS-Certificate = {
+# Subject = '...',
+# Common-Name = '...',
+# Issuer = '...'
+# }
+```
When more than one certificate is decoded, the first ( i.e.
&session-state.TLS-Certificate[0] ) will be the client certificate,
with the next being its issuer.
+```
+server tls-session {
+ namespace = tls
+```
This section can be run to verify a client certificate if
additional checks need to be performed beyond standard
to succeed. Other return codes will cause the verification
to fail.
+```
+ verify certificate {
+```
Check the client certificate matches a string, and reject otherwise
+```
+# if ("%{session-state.TLS-Certificate.Common-Name}" != 'client.example.com') {
+# reject
+# }
+```
Check the client certificate common name against the supplied identity
+```
+# if (&EAP-Identity != "host/%{session-state.TLS-Certificate.Common-Name}") {
+# reject
+# }
+```
This is a convenient place to call LDAP, for example, when using
EAP-TLS, as it will only be called once, after all certificates as
groupmembership_filter = "(&(objectClass=group)(member=%{control.Ldap-UserDn}))"
+```
+# ldap
+```
Now let's test membership of an LDAP group (the ldap bind user will
need permission to read this group membership):
+```
+# if (!%ldap.group("Permitted-Laptops")) {
+# reject
+# }
+```
or, to be more specific, you could use the group's full DN:
if (!%ldap.group("CN=Permitted-Laptops,OU=Groups,DC=example,DC=org")) {
iteration has completed.
+```
+# files
+ ok
+ }
+```
This section is run prior to creating a new TLS session
and can be used to modify session parameters such as
max and min TLS versions.
+```
+# new session {
+# &control.Max-Version := 1.3
+# &control.Min-Version := 1.2
+# }
+```
This section is run whenever the server needs to read an
entry from the TLS session cache.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
+```
+ load session {
+ &control.Cache-Allow-Insert := no
+ cache_tls_session
+ }
+```
This section is run whenever the server needs to write an
entry to the TLS session cache.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
+```
+ store session {
+ &control.Cache-TTL := 0
+ cache_tls_session
+ }
+```
This section is run whenever the server needs to delete an
entry from the TLS session cache.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
+```
+ clear session {
+ &control.Cache-TTL := 0
+ &control.Cache-Allow-Insert := no
+ cache_tls_session
+ }
+```
This section is run after the TLS session is established.
It is intended for logging session details such as
TLS version or cipher suite.
+```
+# establish session {
+```
+```
+# }
+```
This section is run after certificate attributes are added
to the request list, and before performing OCSP validation.
On success it should return 'ok', 'updated', 'noop' or 'notfound'
To force OCSP validation failure, it should return 'reject'.
+```
+ load ocsp-state {
+ &control.Cache-Allow-Insert := no
+ cache_ocsp
+ }
+```
This section is run after OCSP validation has completed.
The return code has no real effect on session processing
and will just cause the server to emit a warning.
-
-
-== Default Configuration
-
```
-# TLS-Certificate = {
-# Subject = '...',
-# Common-Name = '...',
-# Issuer = '...'
-# }
-server tls-session {
- namespace = tls
- verify certificate {
-# if ("%{session-state.TLS-Certificate.Common-Name}" != 'client.example.com') {
-# reject
-# }
-# if (&EAP-Identity != "host/%{session-state.TLS-Certificate.Common-Name}") {
-# reject
-# }
-# ldap
-# if (!%ldap.group("Permitted-Laptops")) {
-# reject
-# }
-# files
- ok
- }
-# new session {
-# &control.Max-Version := 1.3
-# &control.Min-Version := 1.2
-# }
- load session {
- &control.Cache-Allow-Insert := no
- cache_tls_session
- }
- store session {
- &control.Cache-TTL := 0
- cache_tls_session
- }
- clear session {
- &control.Cache-TTL := 0
- &control.Cache-Allow-Insert := no
- cache_tls_session
- }
-# establish session {
-# }
- load ocsp-state {
- &control.Cache-Allow-Insert := no
- cache_ocsp
- }
store ocsp-state {
&control.Cache-TTL := "%{&reply.TLS-OCSP-Next-Update * -1}"
&control.Cache-Allow-Merge := no
+
cache_ocsp
}
}
```
+
+== Default Configuration
+
+```
+```
RADIUS over TLS
+```
+server radsec {
+ listen {
+ transport = tls
+ type = Access-Request
+ type = Accounting-Request
+ tls {
+ ipaddr = *
+ port = 2083
+```
Connection limiting for sockets with "proto = tcp".
+```
+ limit {
+```
Limit the number of simultaneous TCP connections to the socket
The default is 16.
Setting this to 0 means "no limit"
+```
+ max_connections = 16
+```
The per-socket "max_requests" option does not exist.
this lifetime, the connection will be closed.
Setting this to 0 means "forever".
+```
+ lifetime = 0
+```
The idle timeout, in seconds, of a TCP connection.
If no packets have been received over the connection for
We STRONGLY RECOMMEND that you set an idle timeout.
+```
+ idle_timeout = 30
+ }
+ private_key_password = whatever
+ private_key_file = ${certdir}/server.pem
+```
If Private key & Certificate are located in
the same file, then private_key_file &
certificate_file must contain the same file
only the server certificate, but ALSO all
of the CA certificates used to sign the
server certificate.
+```
+ certificate_file = ${certdir}/server.pem
+```
Trusted Root CA list
ALL of the CA's in this list will be trusted
not use client certificates, and you do not want
to permit EAP-TLS authentication, then delete
this configuration item.
+```
+ ca_file = ${cadir}/ca.pem
+```
For DH cipher suites to work, you have to
run OpenSSL to create the DH file first:
openssl dhparam -out certs/dh 1024
+```
+ dh_file = ${certdir}/dh
+```
If your system doesn't have /dev/urandom,
you will need to create this file, and
there are fewer round trips when setting up a TLS
connection. But only if the certificates are large.
+```
+ fragment_size = 8192
+```
include_length is a flag which is
by default set to yes If set to
yes, Total Length of the message is
3) uncomment the line below.
5) Restart radiusd
check_crl = yes
+```
+ ca_path = ${cadir}
+```
Accept an expired Certificate Revocation List
allow_expired_crl = no
Set this option to specify the allowed
TLS cipher suites. The format is listed
in "man 1 ciphers".
+```
+ cipher_list = "DEFAULT"
+```
If enabled, OpenSSL will use server cipher list
(possibly defined by cipher_list option above)
for choosing right cipher suite rather than
using client-specified list which is OpenSSl default
behavior. Having it set to 'yes' is best practice
for TLS.
+```
+ cipher_server_preference = yes
+```
Session resumption / fast reauthentication
cache.
You probably also want "use_tunneled_reply = yes"
when using fast session resumption.
+```
+ cache {
+```
Lifetime of the cached entries, in hours.
The sessions will be deleted after this
time.
+```
+ lifetime = 24 # hours
+```
Internal "name" of the session cache.
Used to distinguish which TLS context
This feature REQUIRES "name" option be set above.
persist_dir = "${logdir}/tlscache"
+```
+ }
+```
Require a client certificate.
+```
+ require_client_cert = yes
+```
As of version 2.1.10, client certificates can be
validated via an external command. This allows
default configuration. Uncomment it, and configure
the correct paths below to enable it.
+```
+ verify {
+```
The command used to verify the client cert.
We recommend using the OpenSSL command-line
tool.
deleted by the server when the command
returns.
client = "/path/to/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}"
-
-
-
-== Default Configuration
-
```
-server radsec {
- listen {
- transport = tls
- type = Access-Request
- type = Accounting-Request
- tls {
- ipaddr = *
- port = 2083
- limit {
- max_connections = 16
- lifetime = 0
- idle_timeout = 30
- }
- private_key_password = whatever
- private_key_file = ${certdir}/server.pem
- certificate_file = ${certdir}/server.pem
- ca_file = ${cadir}/ca.pem
- dh_file = ${certdir}/dh
- fragment_size = 8192
- ca_path = ${cadir}
- cipher_list = "DEFAULT"
- cipher_server_preference = yes
- cache {
- lifetime = 24 # hours
- }
- require_client_cert = yes
- verify {
}
}
}
+
recv Access-Request {
ok
}
+
recv Accounting-Request {
ok
}
}
```
+
+== Default Configuration
+
+```
+```
+```
+# Sample virtual server for internally proxied requests.
+```
Consult the default file for information on the syntax and available options.
+```
+server virtual.example.com {
+```
In v4, all "server" sections MUST start with a "namespace"
parameter. This tells the server which protocol is being used.
Consult the sites-available/default for more information and documentation.
+```
+ namespace = radius
+```
Define our listeners and the types of application packets we expect.
+```
+ listen {
+ type = Access-Request
+ transport = udp
+ udp {
+ ipaddr = *
+ port = 11812
+ }
+ }
+```
Our listener for Accounting
+```
+ listen {
+ type = Accounting-Request
+ transport = udp
+ udp {
+ ipaddr = *
+ port = 11813
+ }
+ }
+```
Now we define our policy framework for how this virtual server will handle various application packets.
Consult the default file for information on the syntax and available options.
+```
+ recv Access-Request {
+```
insert policies here
In this example we simply validate locally
+```
+ filter_username
+ auth_log
+ files
+ pap
+ }
+ send Access-Accept {
+```
insert policies here
+```
+ }
+ recv Accounting-Request {
+```
insert policies here
Ensure that we have a semi-unique identifier for every
request, and many NAS boxes are broken.
+```
+ acct_unique
+```
Read the 'acct_users' file
+```
+ files
+ }
+ send Accounting-Response {
+```
Create a 'detail'ed log of the packets.
Note that accounting requests which are proxied
are also logged in the detail file.
+```
+ detail
+```
Filter attributes from the accounting response.
+```
+ attr_filter.accounting_response
+ }
+```
Allow for PAP in our example
+```
+ authenticate pap {
+ pap
+ }
+```
etc.
+```
+}
+```
== Default Configuration
```
-# Sample virtual server for internally proxied requests.
-server virtual.example.com {
- namespace = radius
- listen {
- type = Access-Request
- transport = udp
- udp {
- ipaddr = *
- port = 11812
- }
- }
- listen {
- type = Accounting-Request
- transport = udp
- udp {
- ipaddr = *
- port = 11813
- }
- }
- recv Access-Request {
- filter_username
- auth_log
- files
- pap
- }
- send Access-Accept {
- }
- recv Accounting-Request {
- acct_unique
- files
- }
- send Accounting-Response {
- detail
- attr_filter.accounting_response
- }
- authenticate pap {
- pap
- }
-}
```
+```
+# As of version 2.0.0, the server also supports the VMPS
+# protocol.
+```
+```
+server vmps {
+```
In v4, all "server" sections MUST start with a "namespace"
parameter. This tells the server which protocol is being used.
All of the subsequent "listen" sections in this server will
only accept packets for that protocol.
+```
+ namespace = vmps
+ listen {
+```
transport::
+```
+ transport = udp
+```
type:: Type of VMPS packets to listen for.
+```
+ type = Join-Request
+ type = Reconfirm-Request
+ udp {
+```
ipaddr:: VMPS sockets only support IPv4 addresses.
+```
+ ipaddr = *
+```
port:: Port on which to listen.
NOTE: 1589 is the default VMPS port.
+```
+ port = 1589
+```
Some systems support binding to an interface, in addition
to the IP address. This feature isn't strictly necessary,
If your system does not support this feature, you will
get an error if you try to use it.
+```
+# interface = eth0
+ }
+ }
+```
You can list multiple "client" sections here in order to define
clients which apply only to this virtual server. i.e. only for
This section is called when it receives a Join-Request.
+```
+ recv Join-Request {
+```
Some requests may not have a MAC address. Try to
create one using other attributes.
+```
+ if (!&MAC-Address) {
+ if (&Ethernet-Frame =~ /0x.{12}(..)(..)(..)(..)(..)(..).*/) {
+ &request.MAC-Address = "%{1}:%{2}:%{3}:%{4}:%{5}:%{6}"
+ }
+ else {
+ &request.MAC-Address = &Cookie
+ }
+ }
+```
Do a simple mapping of MAC to VLAN.
See `raddb/mods-available/mac2vlan` for the definition of the "mac2vlan"
module.
+```
+# mac2vlan
+```
required VMPS reply attributes
+```
+ &reply.Packet-Type = Join-Response
+ &reply.Error-Code = No-Error
+ &reply.Cookie = &MAC-Address
+ &reply.VLAN-Name = "please_use_real_vlan_here"
+```
NOTE: If you have VLAN's in a database, you can `select`
the VLAN name based on the MAC address.
+```
+# &reply.VLAN-Name = %sql("select ... where mac='%{MAC-Address}'")
+ }
+```
This section is called when it sends a Join-Response.
+```
+ send Join-Response {
+ ok
+ }
+```
This section is called when it receives a Reconfirm-Request.
+```
+ recv Reconfirm-Request {
+```
Add contents here!
+```
+ ok
+ }
+```
This section is called when it receives a Reconfirm-Response
+```
+ recv Reconfirm-Response {
+```
Add contents here!
+```
+ ok
+ }
+```
This section is called when not responding to packets.
-
-== Default Configuration
-
```
-# As of version 2.0.0, the server also supports the VMPS
-# protocol.
-server vmps {
- namespace = vmps
- listen {
- transport = udp
- type = Join-Request
- type = Reconfirm-Request
- udp {
- ipaddr = *
- port = 1589
-# interface = eth0
- }
- }
- recv Join-Request {
- if (!&MAC-Address) {
- if (&Ethernet-Frame =~ /0x.{12}(..)(..)(..)(..)(..)(..).*/) {
- &request.MAC-Address = "%{1}:%{2}:%{3}:%{4}:%{5}:%{6}"
- }
- else {
- &request.MAC-Address = &Cookie
- }
- }
-# mac2vlan
- &reply.Packet-Type = Join-Response
- &reply.Error-Code = No-Error
- &reply.Cookie = &MAC-Address
- &reply.VLAN-Name = "please_use_real_vlan_here"
-# &reply.VLAN-Name = %sql("select ... where mac='%{MAC-Address}'")
- }
- send Join-Response {
- ok
- }
- recv Reconfirm-Request {
- ok
- }
- recv Reconfirm-Response {
- ok
- }
send Do-Not-Respond {
ok
}
}
```
+
+== Default Configuration
+
+```
+```