The secret can be any string, up to 8k characters in length.
-Control codes can be entered via octal encoding,
-e.g. `\101\102` is the same as `AB`
-Quotation marks can be entered by escaping them,
-e.g. `foo\"bar`
+Control codes can be entered via octal encoding:
-An important note on security: The security of the
-RADIUS protocol depends *completely* on this secret! We
-recommend using a shared secret that is composed of:
+`secret = "\101\102"` is the same as `AB`
- * upper case letters
- * lower case letters
- * numbers
+Quotation marks can be entered by escaping them:
-And is *at least* 8 characters, but preferably 16 characters in
-length. The secret *must* be random, and should not be words,
-phrase, or anything else that is recognisable.
+`secret = "foo\"bar"`
+
+or by using triple quotes:
+
+`secret = """foo"bar"""
+
+A note on security: The security of the RADIUS protocol
+depends COMPLETELY on this secret! We recommend using a
+shared secret that at LEAST 16 characters long. It should
+preferably be 32 characters in length. The secret MUST be
+random, and should not be words, phrase, or anything else
+that is recognisable.
+
+Computing power has increased enormously since RADIUS was
+first defined. A hobbyist with a high-end GPU can try ALL
+of the 8-character shared secrets in about a day. The
+security of shared secrets increases MUCH more with the
+length of the shared secret, than with number of different
+characters used in it. So don't bother trying to use
+"special characters" or anything else in an attempt to get
+un-guessable secrets. Instead, just get data from a secure
+random number generator, and use that.
+
+You should create shared secrets using a method like this:
+
+dd if=/dev/random bs=1 count=24 | base64
+
+This process will give output which takes 24 random bytes,
+and converts them to 32 characters of ASCII. The output
+should be accepted by all RADIUS clients.
+
+You should NOT create shared secrets by hand. They will
+not be random. They will will be trivial to crack.
The default secret below is only for testing, and should
not be used in any real environment.
require_message_authenticator::Require Message-Authenticator in Access-Requests.
-https://tools.ietf.org/html/rfc5080[RFC 5080] suggests that all clients *should* include it in an
-Access-Request. The configuration item below allows the server
-to require it. If a client is required to include a `link:https://freeradius.org/rfc/rfc2869.html#Message-Authenticator[Message-Authenticator]`
-and it does not, then the packet will be silently discarded.
-
-If value is auto, then if any packet received from the client
-contains a valid Message-Authenticator attribute, then the server
-will require it from all future packets from that client.
-
-NOTE: This setting overrides the identically named config item in the
-radius listener.
+https://tools.ietf.org/html/rfc5080[RFC 5080] suggests that all clients *should* include it in
+an Access-Request. The configuration item below allows the
+server to require it. If a client is required to include a
+`link:https://freeradius.org/rfc/rfc2869.html#Message-Authenticator[Message-Authenticator]` and it does not, then the packet
+will be silently discarded.
+
+If value is` auto`, then when an `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packet from
+the client contains a valid `link:https://freeradius.org/rfc/rfc2869.html#Message-Authenticator[Message-Authenticator]`
+attribute, the server will then require that it exist in
+all future `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packets from that client.
+
+This flag exists solely for legacy clients which do not
+send `link:https://freeradius.org/rfc/rfc2869.html#Message-Authenticator[Message-Authenticator]` in all `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]`
+packets. We do not recommend setting it to `no`, as that
+may allow the BlastRADIUS attack to take place.
+
+The number one way to protect yourself from the BlastRADIUS
+attack is to update all RADIUS servers, and then set this
+flag to `yes`. If all RADIUS servers are updated, and if
+all of them have this flag set to `yes` for all clients,
+then your network is safe. You can then upgrade the
+clients when it is convenient, instead of rushing the
+upgrades.
+
+NOTE: This per-client setting overrides the identically
+named configuration item in the `listen` section.
Allowed values: yes, no, auto
limit_proxy_state:: Control whether Proxy-State is allowed in
-packets from this client which do not have a Message-Authenticator.
+packets from this client which do not have a `link:https://freeradius.org/rfc/rfc2869.html#Message-Authenticator[Message-Authenticator]`.
-The blastradius prefix attack allows an attacker to manipulate
-the contents of response packets without knowing the shared secret.
+The BlastRADIUS attack allows an attacker to manipulate the
+contents of responses to `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packets, without
+knowing the shared secret.
The attack relies on controlling a portion of the data sent back
in the response by the RADIUS server. As Proxy-State is always
manipulate the data sent back from the server and facilitate the
attack.
-The attack also relies on defficiencies in the original RADIUS
-standards that provided no integrity protection for Access-Requests.
+The attack also relies on deficiencies in the original
+RADIUS standards which do not provide xintegrity protection
+for `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]`s.
The attack is mitigated by requiring the Message-Authenticator,
which contains a HMAC over the entire request, preventing
modification of the request by the attacker.
-If value is auto, and the first packet received from the client
-does not contain a Proxy-State attribute, Proxy-State will be
-disallowed in any future packets which do not contain a
-Message-Authenticator.
+If value is` auto`, then when an `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]` packet
+from the client contains does not contain a `link:https://freeradius.org/rfc/rfc2865.html#Proxy-State[Proxy-State]`
+attribute, the server will the discard `link:https://freeradius.org/rfc/rfc2865.html#Access-Request[Access-Request]`
+packets from the client which contain `link:https://freeradius.org/rfc/rfc2865.html#Proxy-State[Proxy-State]`, but no
+`Message-Authenticator.
-This provides some level of protection against the blastradius
-attack, without requiring Message-Authenticator, or breaking existing
-deployments.
+This provides some level of protection against the
+blastradius attack, without requiring
+`link:https://freeradius.org/rfc/rfc2869.html#Message-Authenticator[Message-Authenticator]` in all packets, or breaking
+existing deployments.
NOTE: This setting overrides the identically named config item in the
-radius listener.
+radius `listen` section.
Allowed values: yes, no, auto
NOTE: We recommend using local variables inside of "unlang"
sections instead of defining attributes in this file. See
- the xref:index.adoc[reference documentation]
+ the xref:reference:index.adoc[reference documentation]
for more information on
xref:unlang/local.adoc[local variables].
major version numbers means that the configuration files are *not*
100% compatible. This includes the dictionaries!
-All of the v3 compatibility names are in the RADIUS namespace.
+The v3 compatibility names are in the RADIUS namespace.
There are no aliases for DHCPv4.
+This dictionary includes v3-compatible names like "Cleartext-Password",
+or "NT-Password".
+
+
== Default Configuration
```
#$INCLUDE ${dictdir}/radius/v3/dictionary.cisco
#$INCLUDE ${dictdir}/radius/v3/dictionary.aruba
#END-PROTOCOL RADIUS
+#$INCLUDE ${dictdir}/freeradius/v3/dictionary.freeradius.internal
```
-= CHAP module
+= CHAP
This module authenticates requests containing a `link:https://freeradius.org/rfc/rfc2865.html#CHAP-Password[CHAP-Password]` attribute.
```
detail {
- filename = ${radacctdir}/%{Net.Src.IP}/detail-%Y-%m-%d
+ filename = "${radacctdir}/%{Net.Src.IP}/detail-%Y-%m-%d"
# filename = ${radacctdir}/detail
escape_filenames = no
permissions = 0600
```
detail detail.example.com {
- filename = ${radacctdir}/detail.example.com/detail-%Y-%m-%dT%H:%G:00
+ filename = "${radacctdir}/detail.example.com/detail-%Y-%m-%dT%H:%G:00"
}
```
```
detail auth_log {
- filename = ${radacctdir}/%{Net.Src.IP}/auth-detail-%Y-%m-%d
+ filename = "${radacctdir}/%{Net.Src.IP}/auth-detail-%Y-%m-%d"
permissions = 0600
suppress {
User-Password
}
}
detail reply_log {
- filename = ${radacctdir}/%{Net.Src.IP}/reply-detail-%Y-%m-%d
+ filename = "${radacctdir}/%{Net.Src.IP}/reply-detail-%Y-%m-%d"
permissions = 0600
}
detail pre_proxy_log {
- filename = ${radacctdir}/%{Net.Src.IP}/pre-proxy-detail-%Y-%m-%d
+ filename = "${radacctdir}/%{Net.Src.IP}/pre-proxy-detail-%Y-%m-%d"
permissions = 0600
# suppress {
# User-Password
# }
}
detail post_proxy_log {
- filename = ${radacctdir}/%{Net.Src.IP}/post-proxy-detail-%Y-%m-%d
+ filename = "${radacctdir}/%{Net.Src.IP}/post-proxy-detail-%Y-%m-%d"
permissions = 0600
}
```
type:: Only EAP types listed below with a `type = <EAP-Type>` pair will be allowed.
+If the `control.EAP-Type` attribute is set, then that is used to form the list of
+allowed EAP types, with the first instance being the default type and others also
+being allowed.
+
+Setting an EAP type in `control.EAP-Type` which is not allowed below, will not have
+any effect, since this list determines which methods are loaded and potentially
+available.
+
### EAP-MD5
| `clear session { ... }`
| Clear stateful session information from a cache.
-| `verify certificate { ... }`
+| `verify certificate { ... }`
| Apply policies based on the client certificate presented.
| `staple certificate { ... }`
|===
More information about the various sections can be found in the virtual server
-link:../../../../../../sites-available/tls-cache.adoc[sites-available/tls-cache].
+xref:reference:raddb/sites-available/tls-session.adoc[sites-available/tls-session].
auto_chain::
removed in v4.0.
See the new policy `copy_request_to_tunnel` in
-link:../../../../../../sites-available/inner-tunnel.adoc[sites-available/inner-tunnel], and in `policy.d/eap` for
+xref:reference:raddb/sites-available/inner-tunnel.adoc[sites-available/inner-tunnel], and in `policy.d/eap` for
more information.
====
NOTE: To use `PEAP` you must also configure an inner method in
`mods-enabled/eap_inner`.
+
tls:: Point to the common TLS configuration
Which `tls-config` section the TLS negotiation parameters are
removed in v4.0.
See the new policy `copy_request_to_tunnel` in
-link:../../../../../../sites-available/inner-tunnel.adoc[sites-available/inner-tunnel], and in `policy.d/eap`
+xref:reference:raddb/sites-available/inner-tunnel.adoc[sites-available/inner-tunnel], and in `policy.d/eap`
for more information.
+
====
+
virtual_server:: The virtual server used for "inner" authentication.
The inner tunneled request can be sent through a virtual
auth_type = PAP
}
tls-config tls-common {
-# virtual_server = tls-cache
+# virtual_server = tls-session
# auto_chain = no
chain rsa {
# format = "PEM"
Note: the attriubte type should be capable of holding data of the type
used as key values.
Particularly useful if matching IP addresses to subnets, since the populated
-value will be the subnet. In that case it is best to use 0.0.0.0/0 in place
-of DEFAULT for any catch-all entries.
+value will be the subnet. In that case it is best to use `0.0.0.0/0` in place
+of `DEFAULT` for any catch-all entries.
+
+
+
+v3_compat:: Version 3 compatibility flag.
+
+When this flag is set, any enumeration names (e.g. Service-Type := Framed-User)
+do not need to have the v4 "::" prefix. This flag helps with migrating v3
+configurations to v4.
+
+Default value "false". Allowerd vlaues, "true' and "false".
# key = "%{&Stripped-User-Name || &User-Name}"
filename = ${moddir}/authorize
# match_attr = &control.User-Category
+# v3_compat = false
}
files files_accounting {
# key = "%{&Stripped-User-Name || &User-Name}"
-pool { ... }:: Pool of `krb5` contexts.
+username:: The username (principal) to authenticate as
-This allows us to make the module multithreaded and to avoid expensive
-operations like resolving and opening keytabs on every request.
-It may also allow TCP connections to the KDC to be cached if that is
-supported by the version of libkrb5 used.
+If this is just a user name, then the default Kerberos realm will
+automatically be added.
-NOTE: The context `pool` is only used if the underlying libkrb5 reported
-that it was thread safe at compile time.
+password:: The password to use in user authentication
-start:: Connections to create during module instantiation.
-If the server cannot create specified number of
-connections during instantiation it will exit.
-Set to `0` to allow the server to start without the
-external service being available.
+.Reusable Handles
+Reusable krb5 handles are allocated in blocks. These
+parameters allow for tuning how that is done.
-min:: Minimum number of connections to keep open.
+min:: The minimum number of handles to keep allocated
-max:: Maximum number of connections.
+max:: The maximum number of reusable handles to allocate.
-If these connections are all in use and a new one
-is requested, the request will NOT get a connection.
-Setting `max` to *LESS* than the number of threads means
-that some threads may starve, and you will see errors
-like _No connections available and at max connection limit_.
-Setting `max` to MORE than the number of threads means
-that there are more connections than necessary.
-
-If `max` is not specified, then it defaults to the number
-of workers configured.
-
-
-
-spare:: Spare connections to be left idle.
-
-NOTE: Idle connections WILL be closed if `idle_timeout`
-is set. This should be less than or equal to `max` above.
-
-
-
-uses:: Number of uses before the connection is closed.
-
-NOTE: A setting of `0` means infinite (no limit).
-
-
-
-lifetime:: The lifetime (in seconds) of the connection.
-
-NOTE: A setting of `0` means infinite (no limit).
-
-
-
-idle_timeout:: The idle timeout (in seconds). A connection which is
-unused for this length of time will be closed.
-
-NOTE: A setting of `0` means infinite (no timeout).
-
-
-
-[NOTE]
-====
-All configuration settings are enforced. If a
-connection is closed because of `idle_timeout`,
-`uses`, or `lifetime`, then the total number of
-connections MAY fall below `min`. When that
-happens, it will open a new connection. It will
-also log a WARNING message.
-
-The solution is to either lower the `min` connections,
-or increase lifetime/idle_timeout.
-====
+cleanup_interval:: How often to free un-used handles.
krb5 {
keytab = /path/to/keytab
service_principal = name_of_principle
- pool {
- start = 0
- min = 0
-# max =
- spare = 1
- uses = 0
- lifetime = 0
- idle_timeout = 0
+# username = &User-Name
+# password = &User-Password
+ reuse {
+# min = 10
+# max = 100
+# cleanup_interval = 30s
}
}
```
sorting order will be reversed for that attribute.
* If `sort_by` is set, and the server does not support sorting
-the search will fail.
+or the attributes do not have an ORDERING rule, the search will fail.
* If a search returns multiple user objects and `sort_by` is not
set, the search will fail.
+sort_by:: Server side result sorting.
+
+A list of space delimited attributes to order the result set by,
+controlling the sequence that profiles are applied if the filter
+returns more than one object.
+
+ * If the attribute name is prefixed with a hyphen '-' the
+sorting order will be reversed for that attribute.
+
+ * If `sort_by` is set, and the server does not support sorting
+or the attributes do not have an ORDERING rule, the search will fail.
+
+
+
### Modify user object on receiving Accounting-Request
Useful for recording things like the last time the user logged
-
-### Post-Auth can modify LDAP objects too
+### "send" sections can modify LDAP objects too
# default = 'cn=radprofile,dc=example,dc=org'
# attribute = 'radiusProfileDn'
# attribute_suspend = 'radiusProfileDn'
+# sort_by = 'radiusProfilePriority'
}
accounting {
- reference = "%tolower(type.%{Acct-Status-Type})"
- type {
- start {
- update {
- description := "Online at %S"
- }
+ start {
+ update {
+ description := "Online at %S"
}
- interim-update {
- update {
- description := "Last seen at %S"
- }
+ }
+ interim-update {
+ update {
+ description := "Last seen at %S"
}
- stop {
- update {
- description := "Offline at %S"
- }
+ }
+ stop {
+ update {
+ description := "Offline at %S"
}
}
}
- post-auth {
- update {
- description := "Authenticated at %S"
+ send {
+ access-accept {
+ update {
+ description := "Authenticated at %S"
+ }
}
}
options {
-.Pool
+.Reusable Handles
-TIP: Information for the winbind connection pool. The
-configuration items below are the same for all modules
-which use the connection pool.
+Reusable connection handles are allocated in blocks. These
+parameters allow for tuning how that is done.
-start:: Connections to create during module instantiation.
+min:: The minimum number of connection handles to
+keep allocated
-If the server cannot create specified number of
-connections during instantiation it will exit.
-Set to `0` to allow the server to start without the
-external service being available.
+max:: The maximum number of reusable connection
+handles to allocate.
-min:: Minimum number of connections to keep open.
-
-max:: Maximum number of connections.
-
-If these connections are all in use and a new one
-is requested, the request will NOT get a connection.
-
-Setting `max` to *LESS* than the number of threads means
-that some threads may starve, and you will see errors
-like _No connections available and at max connection limit_.
-
-Setting `max` to MORE than the number of threads means
-that there are more connections than necessary.
-
-If `max` is not specified, then it defaults to the number
-of workers configured.
-
-
-
-spare:: Spare connections to be left idle.
-
-NOTE: Idle connections WILL be closed if `idle_timeout`
-is set. This should be less than or equal to `max` above.
-
-
-
-uses:: Number of uses before the connection is closed.
-
-0 means "infinite"
-
-
-
-retry_delay::
-
-The number of seconds to wait after the server tries
-to open a connection, and fails. During this time,
-no new connections will be opened.
-
-
-
-lifetime::
-
-The lifetime (in seconds) of the connection.
-
-NOTE: A setting of 0 means infinite (no limit).
-
-
-
-cleanup_interval::
-
-The pool is checked for free connections every
-`cleanup_interval`. If there are free connections,
-then one of them is closed.
-
-
-
-idle_timeout::
-
-The idle timeout (in seconds). A connection which is
-unused for this length of time will be closed.
-
-NOTE: A setting of `0` means infinite (no timeout).
-
-
-
-[NOTE]
-====
-All configuration settings are enforced. If a
-connection is closed because of `idle_timeout`,
-`uses`, or `lifetime`, then the total number of
-connections MAY fall below `min`. When that
-happens, it will open a new connection. It will
-also log a WARNING message.
-
-The solution is to either lower the `min` connections,
-or increase lifetime/idle_timeout.
-====
+cleanup_interval:: How often to free un-used
+connection handles.
changing using MSCHAP.
+
+TACACS+ puts the MS-CHAP2-Success information in the Data field,
+but we call it MS-CHAP2-Success for simplicity.
+See the ALIAS definition in dictionary/tacacs/dictionary.freeradius.internal
+
+
+
+Similarly, TACACS+ puts the MS-CHAP-Error into the Server-Message
+field.
+
+
== Default Configuration
```
# username = "%mschap(User-Name)"
# domain = "%mschap(NT-Domain)"
# retry_with_normalised_username = no
- }
- pool {
- start = 0
- min = 0
-# max =
- spare = 1
- uses = 0
- retry_delay = 30
- lifetime = 86400
- cleanup_interval = 300
- idle_timeout = 600
+ reuse {
+# min = 10
+# max = 100
+# cleanup_interval = 30s
+ }
}
passchange {
# ntlm_auth = "/usr/bin/ntlm_auth --helper-protocol=ntlm-change-password-1"
# use_open_directory = yes
# allow_retry = yes
# retry_msg = "Re-enter (or reset) the password"
- Xattributes {
+ attributes {
username = &User-Name
chap_challenge = &Vendor-Specific.Microsoft.CHAP-Challenge
chap_response = &Vendor-Specific.Microsoft.CHAP-Response
chap2_cpw = &Vendor-Specific.Microsoft.CHAP2-CPW
chap_nt_enc_pw = &Vendor-Specific.Microsoft.CHAP-NT-Enc-PW
}
- attributes {
- username = &User-Name
- chap_challenge = &MS-CHAP-Challenge
- chap_response = &MS-CHAP-Response
- chap2_response = &MS-CHAP2-Response
- chap2_success = &MS-CHAP2-Success
- chap_error = &MS-CHAP-Error
- }
+# attributes {
+# username = &User-Name
+# chap_challenge = &MS-CHAP-Challenge
+# chap_response = &MS-CHAP-Response
+# chap2_response = &MS-CHAP2-Response
+# chap2_success = &MS-CHAP2-Success
+# chap_error = &MS-CHAP-Error
+# }
}
```
WARNING: On some systems, the system PAM libraries have
memory leaks! We STRONGLY SUGGEST that you do not
-use `link:http://www.kernel.org/pub/linux/libs/pam/index.html[PAM]` for authentication, due to those memory leaks.
+use `link:https://www.kernel.org/pub/linux/libs/pam/[PAM]` for authentication, due to those memory leaks.
The name to use for PAM authentication.
-`link:http://www.kernel.org/pub/linux/libs/pam/index.html[PAM]` looks in `/etc/pam.d/${pam_auth_name}` for it's
+`link:https://www.kernel.org/pub/linux/libs/pam/[PAM]` looks in `/etc/pam.d/${pam_auth_name}` for it's
configuration.
See `redhat/radiusd-pam` for a sample PAM configuration file.
In most cases, you can just set something like `Auth-Type :=
example.com`, and then have a section `authenticate example.com {
... }`, which contains the `radius` modules which do proxying. See
-link:../../../../../../sites-available/default.adoc[sites-available/default] for sample configuration which uses this
+xref:reference:raddb/sites-available/default.adoc[sites-available/default] for sample configuration which uses this
pattern.
## Behavior
pool { ... }::
-The connection pool is new for 3.0, and will be used in many modules, for all kinds of
-connection-related activity.
-
-When the server is not threaded, the connection pool limits are ignored, and only one
-connection is used.
-
-[NOTE]
-====
-If you want to have multiple SQL modules reuse the same connection pool, use `pool = name`
-instead of a `pool` section.
-
-e.g:
-
-[source,sql]
-----
-sql sql1 {
- ...
- pool {
- ...
- }
-}
+The connection pool is a set of per-thread parameters for connections to the SQL database.
-# sql2 will use the connection pool from sql1
-sql sql2 {
- ...
- pool = sql1
-}
-----
-====
+If the driver supports it, then queries are run asynchronously. Currently the list of
+drivers this applies to is:
+
+ * mysql
+ * postgresql
+ * unixodbc
+ * oracle
+ * cassandra
+
+Other drivers are synchronous and therefore queries will block packet processing, resulting
+in significantly worse system performance.
start:: Connections to create during module instantiation.
If these connections are all in use and a new one
is requested, the request will NOT get a connection.
-Setting `max` to *LESS* than the number of threads means
-that some threads may starve, and you will see errors
-like _No connections available and at max connection limit_.
-
-Setting `max` to MORE than the number of threads means
-that there are more connections than necessary.
+Since the majority of SQL drivers only allow one outstanding
+query per connection, this represents the maximum number of
+simultaneous packets that a thread can process.
-If `max` is not specified, then it defaults to the number
-of workers configured.
+Note: The maximum number of connections from FreeRADIUS to
+the database will be this number multiplied by the number of
+worker threads. Ensure that the database server supports that
+number of connections.
-spare:: Spare connections to be left idle.
+connecting:: Number of connections which can be starting at once
-NOTE: Idle connections WILL be closed if `idle_timeout`
-is set. This should be less than or equal to `max` above.
+Used to throttle connection spawning.
-retry_delay:: The number of seconds to wait after the server tries
-to open a connection, and fails.
+lifetime:: The lifetime (in seconds) of the connection.
-During this time, no new connections will be opened.
+open_delay:: Open delay (in seconds).
-lifetime:: The lifetime (in seconds) of the connection.
+How long must we be above the target utilisation for connections to be opened.
+close_delay:: Close delay (in seconds).
-idle_timeout:: idle timeout (in seconds).
+How long we must be below the target utilisation for connections to be closed
-A connection which is unused for this length of time will be closed.
+manage_interval:: How often to manage the connection pool.
-connect_timeout:: Connection timeout (in seconds).
-The maximum amount of time to wait for a new connection to be established.
-Not supported by:
+request:: Options specific to requests handled by this connection pool
-[options="header,autowidth"]
-|===
-| Driver | Description
-| firebird | Likely possible but no documentation.
-| oracle | Not possible.
-| postgresql | Should be set via the radius_db string instead.
-|===
+Note: Due to the one outstanding query per connection limit, the settings
+`per_connection_max` and `per_connection_target` are forcibly set to 1 for
+SQL database connections.
-[NOTE]
-====
- * All configuration settings are enforced. If a connection is closed because
-of `idle_timeout`, `uses`, or `lifetime`, then the total number of connections
-MAY fall below `min`.
-When that happens, it will open a new connection. It will also log a WARNING message.
+free_delay:: How long must a request in the unassigned (free) list not have been
+used for before it's cleaned up and actually freed.
- * The solution is to either lower the "min" connections, or increase lifetime/idle_timeout.
-====
+Unassigned requests can be re-used, multiple times, reducing memory allocation
+and freeing overheads.
# query_timeout = 5
pool {
start = 0
- min = 0
-# max =
- spare = 1
+ min = 1
+ max = 100
+ connecting = 2
uses = 0
- retry_delay = 30
lifetime = 0
- idle_timeout = 60
- connect_timeout = 3.0
+# open_delay = 0.2
+# close_delay = 10
+# manage_interval = 0.2
+ request {
+# free_delay = 10
+ }
}
group_attribute = "${.:instance}-Group"
# cache_groups = no
The old `Unix-Group`, `Group`, and `Group-Name` attributes and comparisons
are no longer supported.
+All of `radutmp`, `radwho`, `radlast`, and `radzap` have been removed.
+
+You can no longer have the `unix` module process accounting packets.
-## Configuration Settings
+## Configuration Settings
== Default Configuration
```
unix {
-
}
```
-pool { ... }::
+.Reusable Handles
-Information for the `winbind` connection pool.
+Reusable connection handles are allocated in blocks. These
+parameters allow for tuning how that is done.
-The configuration items below are the same for all modules which
-use the new connection pool.
+min:: The minimum number of connection handles to
+keep allocated
-start:: Connections to create during module instantiation.
-If the server cannot create specified number of
-connections during instantiation it will exit.
-Set to `0` to allow the server to start without the
-external service being available.
+max:: The maximum number of reusable connection
+handles to allocate.
-min:: Minimum number of connections to keep open.
-
-
-max:: Maximum number of connections.
-
-If these connections are all in use and a new one
-is requested, the request will NOT get a connection.
-
-Setting `max` to *LESS* than the number of threads means
-that some threads may starve, and you will see errors
-like _No connections available and at max connection limit_.
-
-Setting `max` to MORE than the number of threads means
-that there are more connections than necessary.
-
-If `max` is not specified, then it defaults to the number
-of workers configured.
-
-
-
-spare:: Spare connections to be left idle.
-
-NOTE: Idle connections WILL be closed if `idle_timeout`
-is set. This should be less than or equal to `max` above.
-
-
-
-uses:: Number of uses before the connection is closed.
-
-NOTE: A setting of 0 means infinite (no limit).
-
-
-
-retry_delay:: The number of seconds to wait after the server tries
-to open a connection, and fails.
-
-During this time, no new connections will be opened.
-
-
-
-lifetime:: The lifetime (in seconds) of the connection.
-
-NOTE: A setting of 0 means infinite (no limit).
-
-
-
-cleanup_interval:: The pool is checked for free connections every
-`cleanup_interval`.
-
-If there are free connections, then one of them is closed.
-
-
-
-idle_timeout:: The idle timeout (in seconds).
-
-A connection which is unused for this length of time will be closed.
-
-NOTE: A setting of 0 means infinite (no timeout).
-
-
-
-[NOTE]
-====
-All configuration settings are enforced. If a connection is closed because of
-`idle_timeout`, `uses`, or `lifetime`, then the total
-number of connections MAY fall below `min`.
-
-When that happens, it will open a new connection. It will also log a *WARNING* message.
-
-The solution is to either lower the "min" connections, or
-increase lifetime/idle_timeout.
-====
+cleanup_interval:: How often to free un-used
+connection handles.
== Default Configuration
search_username = "%{&Stripped-User-Name || &User-Name}"
# add_domain = yes
}
- pool {
- start = 0
- min = 0
-# max =
- spare = 1
- uses = 0
- retry_delay = 30
- lifetime = 86400
- cleanup_interval = 300
- idle_timeout = 600
+ reuse {
+# min = 10
+# max = 100
+# cleanup_interval = 30s
}
}
```
Some of these flags can also be passed on the command line as
`-S flag=value`.
+Dictionary migration instructions can be found in `${raddbdir}/dictionary`.
+
rewrite_update:: Rewrite old `update` sections to use the new
"edit" code.
inventing two 'instance' names, e.g. 'instance1' and 'instance2'
The instance names can then be used in later configuration
-INSTEAD of the original 'name'.
+INSTEAD of the original 'name'. e.g. instead of `pap { ...}`,
+you can use `pap other {...}`. The `other` name will then be
+a reference to the second PAP module.
Sneak in more data after a BFD packet!
```
-# &reply.Additional-Data := {
-# &more-data := 0xabcdef
+# reply.Additional-Data := {
+# more-data := 0xabcdef
# }
}
the user.
```
- if (!&State) {
- &control.Auth-Type := ::Step1
- &control.Password.Cleartext := "hello"
+ if (!State) {
+ control.Auth-Type := ::Step1
+ control.Password.Cleartext := "hello"
}
else {
```
saved in the session-state list.
```
- &control.Auth-Type := ::Step2
- &control.Password.Cleartext := &session-state.challenge-string
+ control.Auth-Type := ::Step2
+ control.Password.Cleartext := session-state.challenge-string
}
}
Set the random number to save.
```
- &session-state.challenge-string := "%randstr(n)"
- &reply.Reply-Message := "Please enter %{session-state.challenge-string}: "
+ session-state.challenge-string := "%randstr(n)"
+ reply.Reply-Message := "Please enter %{session-state.challenge-string}: "
```
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")
+# 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")
+# 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
+ control.sent-counter := 0
```
Split the string and split into pieces.
```
- if ("%explode(&control.user-session, '|')") {
+ if ("%explode(control.user-session, '|')") {
- foreach &control.user-session {
+ foreach control.user-session {
```
Send an update for each session we find.
```
NAS-IP-Address
```
- &control.NAS-IP-Address := "%{1}"
+ control.NAS-IP-Address := "%{1}"
```
Acct-Session-Id
```
- &control.Acct-Session-Id := "%{2}"
+ control.Acct-Session-Id := "%{2}"
subrequest CoA-Request {
```
from the incoming request.
```
- &request := &parent.request
+ request := parent.request
```
Add/override the session identification attributes looked up
```
- &request.Acct-Session-Id := &parent.control.Acct-Session-Id
+ request.Acct-Session-Id := parent.control.Acct-Session-Id
```
Some NASs want these, others don't
```
- &request.Event-Timestamp := "%l"
- &request.Message-Authenticator := 0x00
+ request.Event-Timestamp := "%l"
+ request.Message-Authenticator := 0x00
```
SQL-User-Name is a side-effect of the xlat
```
- &request -= &SQL-User-Name[*]
+ request -= SQL-User-Name[*]
```
Those attributes should be listed here
```
- &request -= &Acct-Delay-Time[*]
- &request -= &Proxy-State[*]
+ request -= Acct-Delay-Time[*]
+ request -= Proxy-State[*]
```
Uncomment if the NAS does not expect User-Name
-&request -= &User-Name[*]
+request -= User-Name[*]
Call the radius client module instance for the NAS-IP-Address
```
- switch &parent.control.NAS-IP-Address {
+ switch parent.control.NAS-IP-Address {
```
Repeat this block for each NAS
Increment count of sent updates
```
- &parent.control.sent-counter += 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}"
+ parent.control += {
+ Reply-Message = "Missing map for NAS: %{parent.control.NAS-IP-Address}"
}
}
Report what we did
```
- if (&control.sent-counter) {
- &reply += {
- &Reply-Message = "Sent updates for %{control.sent-counter} active sessions"
+ if (control.sent-counter) {
+ reply += {
+ Reply-Message = "Sent updates for %{control.sent-counter} active sessions"
}
ok
} else {
- &reply += {
- &Reply-Message = "No active sessions found"
+ reply += {
+ Reply-Message = "No active sessions found"
}
reject
Return an address to the IP Pool when we see a stop record.
-Ensure that &control.IP-Pool.Name is set to determine which
+Ensure that control.IP-Pool.Name is set to determine which
```
 # pool of IPs are used.
```
configurations These references serve as place-holders, and as
documentation. If you need the functionality of that module, then:
- * configure the module in xref:raddb/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.
username ends in example.com.
```
-# if (&User-Name =~ /@example\.com$/) {
-# &control.Auth-Type := "proxy-example.com"
+# if (User-Name =~ /@example\.com$/) {
+# control.Auth-Type := "proxy-example.com"
# }
```
Service-Type = ::Authorize-Only.
```
-# if (!&reply.State) {
-# &reply.State := "0x%randstr(16h)"
+# if (!reply.State) {
+# reply.State := "0x%randstr(16h)"
# }
```
`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
+ reply += session-state
```
via:
```
-# &request.WiMAX-MN-NAI = "%{User-Name}"
+# request.WiMAX-MN-NAI = "%{User-Name}"
```
If you want various keys to be calculated, you will
calculations, e.g.
```
-# &reply += {
-# &Vendor-Specific.WiMAX = {
-# &FA-RK-Key = 0x00
-# &MSK = &reply.EAP-MSK
+# reply += {
+# Vendor-Specific.WiMAX = {
+# FA-RK-Key = 0x00
+# MSK = reply.EAP-MSK
# }
# }
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}"
+# 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}"
# }
```
into the EAP-Key-Name attribute.
```
-# if (&reply.EAP-Session-Id) {
-# &reply.EAP-Key-Name := &reply.EAP-Session-Id
+# if (reply.EAP-Session-Id) {
+# reply.EAP-Key-Name := reply.EAP-Session-Id
# }
```
Refresh leases when we see a start.
-Ensure that &control.IP-Pool.Name is set to determine which
+Ensure that control.IP-Pool.Name is set to determine which
pool of IPs are used. Set this in `recv Accounting-Request` so
it is available for all the accounting sections.
it could be wrong.
```
- if (&Acct-Delay-Time) {
- &Acct-Delay-Time += %l - &Packet-Original-Timestamp
+ if (Acct-Delay-Time) {
+ Acct-Delay-Time += %l - Packet-Original-Timestamp
}
- if (!&Event-Timestamp) {
- &Event-Timestamp := &Packet-Original-Timestamp
+ if (!Event-Timestamp) {
+ Event-Timestamp := Packet-Original-Timestamp
}
```
```
The DHCP Server Identifier is set here since it is returned in OFFERs
```
- &control.Server-Identifier = 192.0.2.1
+ control.Server-Identifier = 192.0.2.1
```
Call a policy (defined in policy.d/dhcp) to set common reply attributes
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"
+# control.IP-Pool.Name := "local"
# sqlippool
```
based on the rcode of this section.
```
-# &reply.Message-Type = Offer
+# reply.Message-Type = Offer
```
If Message-Type is not set, returning "ok" or
```
The DHCP Server Identifier is set here since it is returned in OFFERs
```
- &control.Server-Identifier = 192.0.2.1
+ 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) {
+ if (request.Server-Identifier &&
+ request.Server-Identifier != control.Server-Identifier) {
do_not_respond
}
```
Response packet type. See Discover section above.
```
-# &reply.Message-Type = Ack
+# reply.Message-Type = Ack
```
Call a policy (defined in policy.d/dhcp) to set common reply attributes
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"
+# control.IP-Pool.Name := "local"
# sqlippool
if (ok) {
- &reply.Your-IP-Address := "%{&request.Requested-IP-Address || &request.Client-IP-Address}"
+ reply.Your-IP-Address := "%{request.Requested-IP-Address || request.Client-IP-Address}"
}
```
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"
+# control.IP-Pool.Name := "local"
# sqlippool
ok
```
#recv Inform {
-# &reply.Net.Dst.Port = 67
-# &reply.Message-Type = Ack
-# &reply.Server-Identifier = "%{Net.Dst.IP}"
-# &reply.Site-specific-28 = 0x0a00
+# reply.Net.Dst.Port = 67
+# reply.Message-Type = Ack
+# reply.Server-Identifier = "%{Net.Dst.IP}"
+# reply.Site-specific-28 = 0x0a00
# ok
#}
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"
+# control.IP-Pool.Name := "local"
# sqlippool
ok
has MAC, asking for IP, etc.
```
- if (&Client-Hardware-Address) {
+ if (Client-Hardware-Address) {
```
look up MAC in database
```
```
has IP, asking for MAC, etc.
```
- elsif (&Your-IP-Address) {
+ elsif (Your-IP-Address) {
```
look up IP in database
```
```
has host name, asking for IP, MAC, etc.
```
- elsif (&Client-Identifier) {
+ elsif (Client-Identifier) {
```
look up identifier in database
```
}
else {
- &reply.Message-Type = Lease-Unknown
+ reply.Message-Type = Lease-Unknown
ok
```
if (notfound) {
- &reply.Message-Type = Lease-Unknown
+ reply.Message-Type = Lease-Unknown
ok
Lease-Unassigned
```
- &reply.Message-Type = Lease-Unassigned
+ reply.Message-Type = Lease-Unassigned
}
}
```
IP Address of the DHCP server
```
- &control.Net.Dst.IP := 192.0.2.2
+ 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
+ request.Gateway-IP-Address := 192.0.2.1
```
Call the dhcpv4 module to do the relay
```
recv Request {
- &control.Net.Dst.IP := 192.0.2.2
+ control.Net.Dst.IP := 192.0.2.2
- &request.Gateway-IP-Address := 192.0.2.1
+ request.Gateway-IP-Address := 192.0.2.1
dhcpv4
All replies MUST include a Server-ID option
```
- &reply.Server-ID.DUID = UUID
- &reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
+ reply.Server-ID.DUID = UUID
+ reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
}
```
All replies MUST include a Server-ID option
```
- &reply.Server-ID.DUID = UUID
- &reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
+ reply.Server-ID.DUID = UUID
+ reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
}
```
All replies MUST include a Server-ID option
```
- &reply.Server-ID.DUID = UUID
- &reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
+ reply.Server-ID.DUID = UUID
+ reply.Server-ID.DUID.UUID.Value := 0x00000000000000000000000000000000
}
}
It's meant to be a _flexible_ DNS server. Want to give different answers to VoIP phones
and desktops, or other types of split horizon? It can do that.
-Because DNS uses the &Header.Rcode to communicate the result of a query (instead of opcode)
+Because DNS uses the Header.Rcode to communicate the result of a query (instead of opcode)
the DNS state machine works differently to other protocols.
Requests will pass through the following processing sections:
- A `recv { ... }` section matching the opcode. e.g. `recv Query { ... }`. Query processing
and response formulation should be done here.
- If this section returns anything other than `ok` or `updated`, a &reply.Header.Rcode value is
+ If this section returns anything other than `ok` or `updated`, a reply.Header.Rcode value is
set.
-- An `error { ... }` section matching &reply.Header.Rcode. e.g. `error Server-Fail { ... }`.
- If the `recv { ... }` section produced a &reply.Header.Rcode value other than `No-Error`
- and a `error { ... } section matching the &reply.Header.Rcode is provided, it is executed.
+- An `error { ... }` section matching reply.Header.Rcode. e.g. `error Server-Fail { ... }`.
+ If the `recv { ... }` section produced a reply.Header.Rcode value other than `No-Error`
+ and a `error { ... } section matching the reply.Header.Rcode is provided, it is executed.
Error sections are intended only for simplifying logging, and as such, the rcode of the section is ignored.
- Error sections can manipulate the reply, e.g. setting a new value for &reply.Header.Rcode, but
+ Error sections can manipulate the reply, e.g. setting a new value for reply.Header.Rcode, but
this will not cause additional `error { ... }` section to be executed.
- 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.
}
recv Query {
- if (&Question[0].Name == 'foo.example.com') {
- &reply.Resource-Record := {
- &Name = 'foo.example.com'
- &Type = A
- &Class = ::Internet
- &TTL = 0
- &Type.A.IP = 127.0.0.1
+ if (Question[0].Name == 'foo.example.com') {
+ reply.Resource-Record := {
+ Name = 'foo.example.com'
+ Type = ::A
+ Class = ::Internet
+ TTL = 0
+ Type.A.IP = 127.0.0.1
}
}
Copy the IP address of the client from
the request just received
```
- &control += {
- &FreeRADIUS-Client-IP-Address = "%{Net.Src.IP}"
+ control += {
+ FreeRADIUS-Client-IP-Address = "%{Net.Src.IP}"
```
require_message_authenticator
```
- &FreeRADIUS-Client-Require-MA = no
+ FreeRADIUS-Client-Require-MA = no
- &FreeRADIUS-Client-Limit-Proxy-State = "auto"
+ FreeRADIUS-Client-Limit-Proxy-State = "auto"
- &FreeRADIUS-Client-Secret = "testing123"
+ FreeRADIUS-Client-Secret = "testing123"
```
shortname
```
- &FreeRADIUS-Client-Shortname = "%{Net.Src.IP}"
+ FreeRADIUS-Client-Shortname = "%{Net.Src.IP}"
```
nas_type
```
- &FreeRADIUS-Client-NAS-Type = "other"
+ FreeRADIUS-Client-NAS-Type = "other"
}
ok
`recv Identity-Response { ... }` section of the specified
EAP-SIM virtual_server, to the reply list:
-- &reply.Any-Id-Req
-- &reply.Fullauth-Id-Req
-- &reply.Permanent-Id-Req
+- reply.Any-Id-Req
+- reply.Fullauth-Id-Req
+- reply.Permanent-Id-Req
Even if this configuration item is set to 'no', additional
identities can be requested by policy.
```
strip_permanent_identity_hint:: Strip the identity hint when
-copying &EAP-Identity or &Identity to &Permanent-Identity.
+copying EAP-Identity or Identity to Permanant-Identity.
The stripping is only performed if this config item is set
to yes, and the hint byte matches what we'd expect for the
`recv Identity-Response { ... }` section of the specified
EAP-AKA virtual_server, to the reply list:
-- &reply.Any-Id-Req
-- &reply.Fullauth-Id-Req
-- &reply.Permanent-Id-Req
+- reply.Any-Id-Req
+- reply.Fullauth-Id-Req
+- reply.Permanent-Id-Req
Even if this configuration item is set to 'no', additional
identities can be requested by policy.
```
strip_permanent_identity_hint:: Strip the identity hint when
-copying &EAP-Identity or &Identity to &Permanent-Identity.
+copying EAP-Identity or Identity to Permanant-Identity.
The stripping is only performed if this config item is set
to yes, and the hint byte matches what we'd expect for the
to be.
The value of the AT_KDF_INPUT can be overridden in the
-eap-aka-prime virtual server with &reply.KDF-Input if
+eap-aka-prime virtual server with reply.KDF-Input if
this value needs to be determined dynamically.
How this value should be created and formatted is specified
`recv Identity-Response { ... }` section of the specified
EAP-AKA virtual_server, to the reply list:
-- &reply.Any-Id-Req
-- &reply.Fullauth-Id-Req
-- &reply.Permanent-Id-Req
+- reply.Any-Id-Req
+- reply.Fullauth-Id-Req
+- reply.Permanent-Id-Req
Even if this configuration item is set to 'no', additional
identities can be requested by policy.
```
strip_permanent_identity_hint:: Strip the identity hint when
-copying &EAP-Identity or &Identity to &Permanent-Identity.
+copying EAP-Identity or Identity to Permanant-Identity.
The stripping is only performed if this config item is set
to yes, and the hint byte matches what we'd expect for the
- `AKA`
- `SIM`
-At the end of this section the value of `&Identity-Type` will be
+At the end of this section the value of `Identity-Type` will be
checked to see if any additional identity processing steps are
required.
The following actions are associated with the various
`Identity-Type` values:
-- `Permanent`:: The current `&Identity` value will be copied to
- `&session-state.Permanent-Identity`. The hint byte
+- `Permanent`:: The current `Identity` value will be copied to
+ `session-state.Permanent-Identity`. The hint byte
will be stripped if the hint matches the current
EAP-Method. If the hint byte does not match
the current EAP-Method the complete value of
involved in that negotiation, you can use
`%aka_sim_id_method(%{User-Name})` in the top level virtual server,
which will return the EAP method hinted by the identity, and then
-set `&control.EAP-Type` to an appropriate value before calling the
+set `control.EAP-Type` to an appropriate value before calling the
EAP module.
#### Pseudonyms
If for whatever reason the identity cannot be validated, you should
return `notfound` to request an additional identity.
-NOTE: Setting `&Method-Hint = Pseudonym` here will cause the server
+NOTE: Setting `Method-Hint = Pseudonym` here will cause the server
to execute the `load pseudonym { ... }` section next. This is
sometimes useful when dealing with non-standard pseudonym identities.
If the identity cannot be resolved, you should return `notfound` to
request an additional identity.
-NOTE: Setting `&Method-Hint = Fastauth` here will cause the server
+NOTE: Setting `Method-Hint = Fastauth` here will cause the server
to execute the `load session { ... }` section next. This is
sometimes useful when dealing with non-standard fastauth identities.
- 3gpp_temporary_id_decrypt
- 3gpp_temporary_id_encrypt
-The rlm_cipher module and the &control.KDF-Identity attribute override
+The rlm_cipher module and the control.KDF-Identity attribute override
(see notes below) are provided to allow the "Privacy Protection for EAP-AKA"
scheme described by 3GPP S3-170116 and the Wireless Broadband Allowance
document "IMSI PRIVACY PROTECTION FOR WI-FI".
### Pseudonyms
-For identity privacy you may include a `&reply.Next-Pseudonym`
-attribute. `&reply.Next-Pseudonym` must be a valid UTF8 string and
+For identity privacy you may include a `reply.Next-Pseudonym`
+attribute. `reply.Next-Pseudonym` must be a valid UTF8 string and
MUST NOT contain a realm. The supplicant will decorate the identity
as appropriate to ensure correct routing.
- The `%3gpp_temporary_id_encrypt()` expansion.
- The `%randstr()` expansion.
-NOTE: Add a `&reply.Next-Pseudonym-Id` attribute in this section to
+NOTE: Add a `reply.Next-Pseudonym-Id` attribute in this section to
avoid having the permanent Id of the SIM exposed during subsequent
authentication attempts.
The value of this attribute may be empty (a zero length string) if
then used to generate new MSKs (Master Session Keys) for subsequent
authentication attempts.
-NOTE: Add a `&reply.Next-Reauth-Id` attribute in this section, to
+NOTE: Add a `reply.Next-Reauth-Id` attribute in this section, to
allow session-resumption for subsequent authentication attempts.
The value of this attribute may be empty (a zero length string) if
which case a random value with the correct hint character will be
WBA document.
If you need to implement one of these identity privacy schemes, the
-cryptographic identity can be specified with `&control.KDF-Identity`.
+cryptographic identity can be specified with `control.KDF-Identity`.
```
send Challenge-Request {
There's not much to do here as the majority of the work for
session resumption is done in `load session { ... }`.
-Add a `&reply.Next-Pseudonym` attribute in this section if you want
+Add a `reply.Next-Pseudonym` attribute in this section if you want
to allow avoid having the permanent Id of the SIM exposed during
subsequent authentication attempts.
-Add a `&reply.Next-Reauth-Id` attribute in this section, to allow
+Add a `reply.Next-Reauth-Id` attribute in this section, to allow
session resumption for subsequent authentication attempts.
The following rcodes have special meanings in this section:
### `recv Client-Error { ... }` - Log the fact that the supplicant has terminated authentication
-The reason for the error should be available in `&Client-Error-Code`
+The reason for the error should be available in `Client-Error-Code`
After this section is run authentication fails immediately with no
EAP-Response/AKA-Notification round.
If the original UMTS quintuplets were calculated locally and you
provided Ki and OP/OPc in the Challenge-Request round, then the
EAP-AKA module will automatically calculate a new SQN for you and
-place it in `&control.SIM-SQN`. You should store this new SQN.
+place it in `control.SIM-SQN`. You should store this new SQN.
As a convenience, the EAP-AKA module will also repopulate
-&control.SIM-Ki and &control.SIM-OPc so you do not need to retrieve
+control.SIM-Ki and control.SIM-OPc so you do not need to retrieve
them again in the `send Challenge-Request { ... }` section.
If the UMTS quintuplets were provided by an AuC, you should submit
`send Challenge-Request { ... }` section.
If the rcode returned from this section does not indicate failure
-and a &control.SQN value is provided, we send a new challenge to
+and a control.SQN value is provided, we send a new challenge to
the supplicant and continue; otherwise authentication fails.
NOTE: Only one Synchronisation attempt is permitted per
### `store pseudonym { ... }`
If when sending a Challenge-Request Reauthentication-Request a
-`&reply.Next-Pseudonym-Id` attribute is found, this section will be
+`reply.Next-Pseudonym-Id` attribute is found, this section will be
called.
-If `&reply.Next-Pseudonym-Id` is empty, it will be filled with a random
+If `reply.Next-Pseudonym-Id` is empty, it will be filled with a random
string of alphanumeric characters.
-For consistency, &reply.Next-Pseudonym-Id will also be made available
-temporarily in `&Next-Pseudonym-Id` for use as a key.
+For consistency, reply.Next-Pseudonym-Id will also be made available
+temporarily in `Next-Pseudonym-Id` for use as a key.
You should store the following attributes against the key
-`&Next-Paeudonym-Id`:
+`Next-Paeudonym-Id`:
-- `&session-state.Permanent-Identity`::The permanent identity of the user.
+- `session-state.Permanent-Identity`::The permanent identity of the user.
If a failure rcode is returned authentication continues but the
Next-Pseudonym-Id will not be sent to the supplicant.
This section will be called prior to entering the AKA-CHALLENGE state.
You should restore the contents of the following attributes using
-`&Next-Pseudonym-Id` as a key:
+`Next-Pseudonym-Id` as a key:
-- `&session-state.Permanent-Identity`::The permanent identity of the user.
+- `session-state.Permanent-Identity`::The permanent identity of the user.
NOTE: If you're using 3GPP style encrypted pseudonyms, you should
decrypt the pseudonym here, and store the decrypted value in
-`&session-state.Permanent-Identity`.
+`session-state.Permanent-Identity`.
```
load pseudonym {
This section we be called if authentication or re-authentication fails.
You should remove any session information stored against
-`&Next-Pseudonym-Id`.
+`Next-Pseudonym-Id`.
```
clear pseudonym {
### `store session { ... }`
-If when sending a Reauthentication-Request a `&reply.Next-Reauth-Id`
+If when sending a Reauthentication-Request a `reply.Next-Reauth-Id`
attribute is found, this section will be called.
You should restore the contents of the following attributes using
-`&request.Session-ID` as a key:
+`request.Session-ID` as a key:
-- `&session-state.Counter`:: How many times this session has
+- `session-state.Counter`:: How many times this session has
been resumed.
-- `&session-state.Session-Data`:: The master session key.
-- `&session-state.Permanent-Identity`::(optionally) the permanent
+- `session-state.Session-Data`:: The master session key.
+- `session-state.Permanent-Identity`::(optionally) the permanent
identity of the user.
If a failure rcode is returned, authentication continues but the
This section will be called prior to attempting re-authentication.
You should restore the contents of the following attributes using
-`&request.Session-ID` as a key:
+`request.Session-ID` as a key:
-- `&session-state.Counter`:: How many times this session has
+- `session-state.Counter`:: How many times this session has
been resumed.
-- `&session-state.Session-Data`:: The master session key.
-- `&session-state.Permanent-Identity`::(optionally) the permanent
+- `session-state.Session-Data`:: The master session key.
+- `session-state.Permanent-Identity`::(optionally) the permanent
identity of the user.
The following rcodes have special meanings in this section:
This section we be called if authentication or re-authentication fails.
-You should remove any session information stored against `&request.Session-ID`.
+You should remove any session information stored against `request.Session-ID`.
```
clear session {
Some example policies. See "man unlang" for more.
```
- if (&User-Name == "bob") {
- &control.Password.Cleartext := "bob"
+ if (User-Name == "bob") {
+ control.Password.Cleartext := "bob"
}
```
}
send Access-Reject {
- &reply.Reply-Message = "This is only an example."
+ reply.Reply-Message = "This is only an example."
}
}
Individual attributes from the outer request may be
accessed with:
- &outer.request.<attribute>
+ outer.request.<attribute>
The following policy in raddb/policy.d/eap can be used
to copy attributes over.
Attributes that should be provided in the reply should be
copied to the outer.session-state list:
- &outer.session-state.Attribute := <Value>
+ outer.session-state.Attribute := <Value>
The default configuration in the outer post-auth "send" section
will copy this to the reply. To copy the entire reply see
Let the outer session know which module failed, and why.
```
- &outer.session-state.Module-Failure-Message := &request.Module-Failure-Message
+ outer.session-state.Module-Failure-Message := request.Module-Failure-Message
}
} # inner-tunnel server block
```
single instance of the attribute and += setting as
many as the LDAP query returns.
-Protocol specific attributes must be qualified e.g. &Proto.radius.User-Name
+Protocol specific attributes must be qualified e.g. Proto.radius.User-Name
```
update {
- &Proto.radius.User-Name = 'uid'
- &Password.With-Header = 'userPassword'
+ Proto.radius.User-Name = 'uid'
+ Password.With-Header = 'userPassword'
}
}
```
# update {
-# &member += "member"
+# member += "member"
# }
# }
```
# update {
-# &Proto.radius.User-Name = 'sAMAccountName'
-# &user-acct-control = 'userAccountControl'
+# Proto.radius.User-Name = 'sAMAccountName'
+# user-acct-control = 'userAccountControl'
# }
# }
```
# update {
-# &Proto.radius.User-Name = 'sAMAccountName'
-# &user-acct-control = 'userAccountControl'
-# &last-known-parent = 'lastKnownParent'
+# Proto.radius.User-Name = 'sAMAccountName'
+# user-acct-control = 'userAccountControl'
+# last-known-parent = 'lastKnownParent'
# }
# }
}
A request will be generated with the following attributes:
-- &request.LDAP-Sync.DN the base_dn of the sync.
-- &request.LDAP-Sync.Filter the filter of the sync (optional).
-- &request.LDAP-Sync.Scope the scope of the sync (optional).
+- request.LDAP-Sync.DN the base_dn of the sync.
+- request.LDAP-Sync.Filter the filter of the sync (optional).
+- request.LDAP-Sync.Scope the scope of the sync (optional).
You should use these attributes to uniquely identify the sync when retrieving
previous cookie values.
-In addition the attribute &request.LDAP-Sync.Directory-Root-DN will be
+In addition the attribute request.LDAP-Sync.Directory-Root-DN will be
populated with the root DN of the directory to aid creating a cookie if one
has not previously been stored.
- fail / invalid / reject / disallow to indicate failure. The section will be
retried after a delay (the ldap reconnection delay). The sync query will not be started until
this section succeeds.
-- 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.
+- 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 {
server settings as ldap_sync.
```
-# if (!&reply.LDAP-Sync.Cookie) {
+# 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}"
+# csn := %concat(%ldap("ldap:///%ldap.uri.safe(%{LDAP-Sync.Directory-Root-DN})?contextCSN?base"), ';')
+# reply.LDAP-Sync.Cookie := "rid=000,csn=%{csn}"
# }
}
A request will be generated with the following attributes:
-- &request.LDAP-Sync.DN the base_dn of the sync.
-- &request.LDAP-Sync.Cookie the cookie value to store.
-- &request.LDAP-Sync.Filter the filter of the sync (optional).
-- &request.LDAP-Sync.Scope the scope of the sync (optional).
+- request.LDAP-Sync.DN the base_dn of the sync.
+- request.LDAP-Sync.Cookie the cookie value to store.
+- request.LDAP-Sync.Filter the filter of the sync (optional).
+- request.LDAP-Sync.Scope the scope of the sync (optional).
The return code of this section is ignored.
A request will be generated with the following attributes:
-- &request.LDAP-Sync.DN the base_dn of the sync.
-- &request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
-- &request.LDAP-Sync.Entry-DN the DN of the object that was added.
-- &*:* attributes mapped from the LDAP entry to FreeRADIUS
+- request.LDAP-Sync.DN the base_dn of the sync.
+- request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
+- request.LDAP-Sync.Entry-DN the DN of the object that was added.
+- *:* attributes mapped from the LDAP entry to FreeRADIUS
attributes using the update section within the sync.
-- &request.LDAP-Sync.Filter the filter of the sync (optional).
-- &request.LDAP-Sync.Scope the scope of the sync (optional).
-- &request.LDAP-Sync.Attr the attributes returned by the sync (optional).
+- request.LDAP-Sync.Filter the filter of the sync (optional).
+- request.LDAP-Sync.Scope the scope of the sync (optional).
+- request.LDAP-Sync.Attr the attributes returned by the sync (optional).
The return code of this section is ignored (for now).
A request will be generated with the following attributes:
-- &request.LDAP-Sync.DN the base_dn of the sync.
-- &request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
-- &request.LDAP-Sync.Entry-DN the DN of the object that was added.
-- &*:* attributes mapped from the LDAP entry to FreeRADIUS
+- request.LDAP-Sync.DN the base_dn of the sync.
+- request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
+- request.LDAP-Sync.Entry-DN the DN of the object that was added.
+- *:* attributes mapped from the LDAP entry to FreeRADIUS
attributes using the update section within the sync.
-- &request.LDAP-Sync.Filter the filter of the sync (optional).
-- &request.LDAP-Sync.Scope the scope of the sync (optional).
-- &request.LDAP-Sync.Original-DN the original DN of the object, if the object was renamed
+- request.LDAP-Sync.Filter the filter of the sync (optional).
+- request.LDAP-Sync.Scope the scope of the sync (optional).
+- request.LDAP-Sync.Original-DN the original DN of the object, if the object was renamed
and the directory returns this attribute.
The return code of this section is ignored (for now).
A request will be generated with the following attributes:
-- &request.LDAP-Sync.DN the base_dn of the sync.
-- &request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
-- &request.LDAP-Sync.Entry-DN the DN of the object that was removed (optional).
-- &*:* attributes mapped from the LDAP entry to FreeRADIUS
+- request.LDAP-Sync.DN the base_dn of the sync.
+- request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
+- request.LDAP-Sync.Entry-DN the DN of the object that was removed (optional).
+- *:* attributes mapped from the LDAP entry to FreeRADIUS
attributes using the update section within the sync,
if the attributes are returned by the directory.
-- &request.LDAP-Sync.Filter the filter of the sync (optional).
-- &request.LDAP-Sync.Scope the scope of the sync (optional).
+- request.LDAP-Sync.Filter the filter of the sync (optional).
+- request.LDAP-Sync.Scope the scope of the sync (optional).
The return code of this section is ignored (for now).
A request will be generated with the following attributes:
-- &request.LDAP-Sync.DN the base_dn of the sync.
-- &request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
-- &request.LDAP-Sync.Entry-DN the DN of the object that is still present (optional).
-- &request.LDAP-Sync.Filter the filter of the sync (optional).
-- &request.LDAP-Sync.Scope the scope of the sync (optional).
+- request.LDAP-Sync.DN the base_dn of the sync.
+- request.LDAP-Sync.Entry-UUID the UUID of the object. (https://tools.ietf.org/html/rfc4533[RFC 4533] directories only)
+- request.LDAP-Sync.Entry-DN the DN of the object that is still present (optional).
+- request.LDAP-Sync.Filter the filter of the sync (optional).
+- request.LDAP-Sync.Scope the scope of the sync (optional).
The return code of this section is ignored (for now).
```
# subrequest Disconnect-Request {
-# &User-Name = &parent.request.User-Name
-# &Acct-Session-Id = &parent.request.Acct-Session-Id
-# &NAS-IP-Address = &parent.NAS-IP-Address}
+# User-Name = parent.request.User-Name
+# Acct-Session-Id = parent.request.Acct-Session-Id
+# NAS-IP-Address = parent.NAS-IP-Address}
# ...
# }
```
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
+ 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
```
You should update this to be one of your realms.
```
- &control.Proxy-To-Realm := "example.com"
+ control.Proxy-To-Realm := "example.com"
}
authenticate eap {
You may want accounting policies here...
```
- &control.Proxy-To-Realm := "acct_realm.example.com"
+ control.Proxy-To-Realm := "acct_realm.example.com"
}
}
stats
ok
}
-}
# Statistics can be queried via a number of methods:
```
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
```
-
```
ASCII authentication equivalent to PAP.
Alternatively, if extra data is required, set
-&reply.Authentication-Status := Getdata
-to request the extra data, which will be in &User-Message in
+reply.Authentication-Status := Getdata
+to request the extra data, which will be in User-Message in
the next packet (if the client provides it)
```
```
send Authentication-Pass {
- &reply.Server-Message := "Hello %{User-Name}"
+ reply.Server-Message := "Hello %{User-Name}"
```
}
send Authentication-Fail {
- &reply.Server-Message := "Failed login!"
+ reply.Server-Message := "Failed login!"
```
```
send Authentication-GetUser {
- &reply.Server-Message := "Username:"
+ reply.Server-Message := "Username:"
}
send Authentication-GetPass {
- &reply.Server-Message := "Password:"
+ reply.Server-Message := "Password:"
}
```
```
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"
+ 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"
+ 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
+ reply.Authorization-Status := Fail
}
```
```
send Accounting-Success {
- &reply.Server-Message := "Success"
+ reply.Server-Message := "Success"
}
send Accounting-Error {
- &reply.Server-Message := "Error"
+ reply.Server-Message := "Error"
}
```
```
When more than one certificate is decoded, the first ( i.e.
-&session-state.TLS-Certificate[0] ) will be the client certificate,
+session-state.TLS-Certificate[0] ) will be the client certificate,
with the next being its issuer.
Check the client certificate common name against the supplied identity
```
-# if (&EAP-Identity != "host/%{session-state.TLS-Certificate.Common-Name}") {
+# if (EAP-Identity != "host/%{session-state.TLS-Certificate.Common-Name}") {
# reject
# }
```
# new session {
-# &control.Max-Version := 1.3
-# &control.Min-Version := 1.2
+# 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.
-It should read the attribute &session-state.TLS-Session-Data
+It should read the attribute session-state.TLS-Session-Data
from the cache, along with any other attributes which
were in the cache
```
load session {
- &control.Cache-Allow-Insert := no
+ 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.
-It should write the attribute &session-state.Session-Data
+It should write the attribute session-state.Session-Data
to the cache, along with any other attributes which
need to be cached.
```
store session {
- &control.Cache-TTL := 0
+ control.Cache-TTL := 0
cache_tls_session
}
```
clear session {
- &control.Cache-TTL := 0
- &control.Cache-Allow-Insert := no
+ control.Cache-TTL := 0
+ control.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.
-It should read the attribute &control.TLS-OCSP-Cert-Valid
+It should read the attribute control.TLS-OCSP-Cert-Valid
from the cache.
On success it should return 'ok', 'updated', 'noop' or 'notfound'
```
load ocsp-state {
- &control.Cache-Allow-Insert := no
+ control.Cache-Allow-Insert := no
cache_ocsp
}
This section is run after OCSP validation has completed.
-It should write the attribute &reply.TLS-OCSP-Cert-Valid
+It should write the attribute reply.TLS-OCSP-Cert-Valid
to the cache.
On success it should return 'ok' or 'updated'.
```
store ocsp-state {
- &control.Cache-TTL := "%{&reply.TLS-OCSP-Next-Update * -1}"
- &control.Cache-Allow-Merge := no
+ control.Cache-TTL := "%{reply.TLS-OCSP-Next-Update * -1}"
+ control.Cache-Allow-Merge := no
cache_ocsp
}
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}"
+ if (!MAC-Address) {
+ if (Ethernet-Frame =~ /0x.{12}(..)(..)(..)(..)(..)(..).*/) {
+ request.MAC-Address = "%{1}:%{2}:%{3}:%{4}:%{5}:%{6}"
}
else {
- &request.MAC-Address = &Cookie
+ request.MAC-Address = Cookie
}
}
required VMPS reply attributes
```
- &reply.Packet-Type = Join-Response
- &reply.Error-Code = No-Error
- &reply.Cookie = &MAC-Address
+ 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 = "please_use_real_vlan_here"
```
the VLAN name based on the MAC address.
```
-# &reply.VLAN-Name = %sql("select ... where mac='%{MAC-Address}'")
+# reply.VLAN-Name = %sql("select ... where mac='%{MAC-Address}'")
}
```