summaryrefslogtreecommitdiffstats
path: root/raddb/mods-available
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 14:11:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 14:11:00 +0000
commitaf754e596a8dbb05ed8580c342e7fe02e08b28e0 (patch)
treeb2f334c2b55ede42081aa6710a72da784547d8ea /raddb/mods-available
parentInitial commit. (diff)
downloadfreeradius-af754e596a8dbb05ed8580c342e7fe02e08b28e0.tar.xz
freeradius-af754e596a8dbb05ed8580c342e7fe02e08b28e0.zip
Adding upstream version 3.2.3+dfsg.upstream/3.2.3+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'raddb/mods-available')
-rw-r--r--raddb/mods-available/README.rst116
-rw-r--r--raddb/mods-available/abfab_psk_sql15
-rw-r--r--raddb/mods-available/always81
-rw-r--r--raddb/mods-available/attr_filter61
-rw-r--r--raddb/mods-available/cache150
-rw-r--r--raddb/mods-available/cache_auth116
-rw-r--r--raddb/mods-available/chap11
-rw-r--r--raddb/mods-available/couchbase204
-rw-r--r--raddb/mods-available/counter82
-rw-r--r--raddb/mods-available/cui53
-rw-r--r--raddb/mods-available/date35
-rw-r--r--raddb/mods-available/detail109
-rw-r--r--raddb/mods-available/detail.example.com27
-rw-r--r--raddb/mods-available/detail.log75
-rw-r--r--raddb/mods-available/dhcp19
-rw-r--r--raddb/mods-available/dhcp_files56
-rw-r--r--raddb/mods-available/dhcp_passwd20
-rw-r--r--raddb/mods-available/dhcp_sql92
-rw-r--r--raddb/mods-available/dhcp_sqlippool101
-rw-r--r--raddb/mods-available/digest13
-rw-r--r--raddb/mods-available/dynamic_clients32
-rw-r--r--raddb/mods-available/eap1115
-rw-r--r--raddb/mods-available/echo123
-rw-r--r--raddb/mods-available/etc_group32
-rw-r--r--raddb/mods-available/exec29
-rw-r--r--raddb/mods-available/expiration13
-rw-r--r--raddb/mods-available/expr148
-rw-r--r--raddb/mods-available/files30
-rw-r--r--raddb/mods-available/idn28
-rw-r--r--raddb/mods-available/inner-eap107
-rw-r--r--raddb/mods-available/ippool66
-rw-r--r--raddb/mods-available/json271
-rw-r--r--raddb/mods-available/krb582
-rw-r--r--raddb/mods-available/ldap712
-rw-r--r--raddb/mods-available/ldap_google262
-rw-r--r--raddb/mods-available/linelog170
-rw-r--r--raddb/mods-available/logintime23
-rw-r--r--raddb/mods-available/mac2ip25
-rw-r--r--raddb/mods-available/mac2vlan18
-rw-r--r--raddb/mods-available/moonshot-targeted-ids57
-rw-r--r--raddb/mods-available/mschap253
-rw-r--r--raddb/mods-available/ntlm_auth18
-rw-r--r--raddb/mods-available/opendirectory26
-rw-r--r--raddb/mods-available/pam26
-rw-r--r--raddb/mods-available/pap18
-rw-r--r--raddb/mods-available/passwd55
-rw-r--r--raddb/mods-available/perl94
-rw-r--r--raddb/mods-available/preprocess62
-rw-r--r--raddb/mods-available/python65
-rw-r--r--raddb/mods-available/python365
-rw-r--r--raddb/mods-available/radutmp53
-rw-r--r--raddb/mods-available/realm80
-rw-r--r--raddb/mods-available/redis99
-rw-r--r--raddb/mods-available/rediswho52
-rw-r--r--raddb/mods-available/replicate42
-rw-r--r--raddb/mods-available/rest301
-rw-r--r--raddb/mods-available/smbpasswd16
-rw-r--r--raddb/mods-available/smsotp94
-rw-r--r--raddb/mods-available/soh4
-rw-r--r--raddb/mods-available/sometimes12
-rw-r--r--raddb/mods-available/sql376
-rw-r--r--raddb/mods-available/sql_map49
-rw-r--r--raddb/mods-available/sqlcounter122
-rw-r--r--raddb/mods-available/sqlippool109
-rw-r--r--raddb/mods-available/sradutmp16
-rw-r--r--raddb/mods-available/totp40
-rw-r--r--raddb/mods-available/unbound13
-rw-r--r--raddb/mods-available/unix25
-rw-r--r--raddb/mods-available/unpack105
-rw-r--r--raddb/mods-available/utf814
-rw-r--r--raddb/mods-available/wimax165
-rw-r--r--raddb/mods-available/yubikey158
72 files changed, 7406 insertions, 0 deletions
diff --git a/raddb/mods-available/README.rst b/raddb/mods-available/README.rst
new file mode 100644
index 0000000..79ed5c3
--- /dev/null
+++ b/raddb/mods-available/README.rst
@@ -0,0 +1,116 @@
+Modules in Version 3
+====================
+
+As of Version 3, all of the modules have been placed in the
+"mods-available/" directory. This practice follows that used by other
+servers such as Nginx, Apache, etc. The "modules" directory should
+not be used.
+
+Modules are enabled by creating a file in the mods-enabled/ directory.
+You can also create a soft-link from one directory to another::
+
+ $ cd raddb/mods-enabled
+ $ ln -s ../mods-available/foo
+
+This will enable module "foo". Be sure that you have configured the
+module correctly before enabling it, otherwise the server will not
+start. You can verify the server configuration by running
+"radiusd -XC".
+
+A large number of modules are enabled by default. This allows the
+server to work with the largest number of authentication protocols.
+Please be careful when disabling modules. You will likely need to
+edit the "sites-enabled/" files to remove references to any disabled
+modules.
+
+Conditional Modules
+-------------------
+
+Version 3 allows modules to be conditionally loaded. This is useful
+when you want to have a virtual server which references a module, but
+does not require it. Instead of editing the virtual server file, you
+can just conditionally enable the module.
+
+Modules are conditionally enabled by adding a "-" before their name in
+a virtual server. For example, you can do::
+
+ server {
+ authorize {
+ ...
+ ldap
+ -sql
+ ...
+ }
+ }
+
+This says "require the LDAP module, but use the SQL module only if it
+is configured."
+
+This feature is not very useful for production configurations. It is,
+however, very useful for the default examples that ship with the
+server.
+
+Ignoring module
+---------------
+
+If you see this message::
+
+ Ignoring module (see raddb/mods-available/README.rst)
+
+Then you are in the right place. Most of the time this message can be
+ignored. The message can be fixed by finding the references to "-module"
+in the virtual server, and deleting them.
+
+Another way to fix it is to configure the module, as described above.
+
+Simplification
+--------------
+
+Allowing conditional modules simplifies the default virtual servers
+that are shipped with FreeRADIUS. This means that if you want to
+enable LDAP (for example), you no longer need to edit the files in
+raddb/sites-available/ in order to enable it.
+
+Instead, you should edit the raddb/mods-available/ldap file to point
+to your local LDAP server. Then, enable the module via the soft-link
+method described above.
+
+Once the module is enabled, it will automatically be used in the
+default configuration.
+
+Multiple Instances
+------------------
+
+It is sometimes necessary to have the same module do two different
+things. The server supports this functionality via "instances" of
+modules.
+
+Normally, a module configuration looks like this:
+
+ sql {
+ ... sql stuff ...
+ }
+
+This module is then refereed to as the "sql" module.
+
+
+But what happens if you want to connect to two different SQL
+databases? The solution is simple; copy the "sql" module
+configuration, and add an instance name after the "sql" string:
+
+ sql mysql1 {
+ ... configuration for connecting to mysql11 ...
+ }
+
+ sql mysql2 {
+ ... configuration for connecting to mysql12 ...
+ }
+
+This configuration says "load the SQL module, but create two copies of
+it, with different configurations". The different configurations can
+be referred to by name, as "mysql1" and "mysql2". That is, anywhere
+you would normally use "sql", you could use either "mysql1" or
+"mysql2".
+
+For further examples of using module instances, see the "attr_filter"
+module configuration in this directory.
diff --git a/raddb/mods-available/abfab_psk_sql b/raddb/mods-available/abfab_psk_sql
new file mode 100644
index 0000000..d75130d
--- /dev/null
+++ b/raddb/mods-available/abfab_psk_sql
@@ -0,0 +1,15 @@
+# -*- text -*-
+##
+## Module for PSK authorizations from ABFAB trust router
+##
+## $Id$
+
+sql psksql {
+
+ driver = "rlm_sql_sqlite"
+
+ sqlite {
+ filename = "/var/lib/trust_router/keys"
+ }
+
+}
diff --git a/raddb/mods-available/always b/raddb/mods-available/always
new file mode 100644
index 0000000..b77d00c
--- /dev/null
+++ b/raddb/mods-available/always
@@ -0,0 +1,81 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# The "always" module is here for debugging purposes, or
+# for use in complex policies.
+# Instance simply returns the same result, always, without
+# doing anything.
+#
+# rcode may be one of the following values:
+# - reject - Reject the user.
+# - fail - Simulate or indicate a failure.
+# - ok - Simulate or indicate a success.
+# - handled - Indicate that the request has been handled,
+# stop processing, and send response if set.
+# - invalid - Indicate that the request is invalid.
+# - userlock - Indicate that the user account has been
+# locked out.
+# - notfound - Indicate that a user account can't be found.
+# - noop - Simulate a no-op.
+# - updated - Indicate that the request has been updated.
+#
+# If an instance is listed in a session {} section,
+# this simulates a user having <integer> sessions.
+#
+# simulcount = <integer>
+#
+# If an instance is listed in a session {} section,
+# this simulates the user having multilink
+# sessions.
+#
+# mpp = <integer>
+#
+# An xlat based on the instance name can be called to change the status
+# returned by the instance, in this example "always db_status { ... }"
+#
+# Force the module status to be alive or dead:
+#
+# %{db_status:alive}
+# %{db_status:dead}
+#
+# Update the rcode returned by an alive module (a dead module returns fail):
+#
+# %{db_status:ok}
+# %{db_status:fail}
+# %{db_status:notfound}
+# ...
+#
+# The above xlats expand to the current status of the module. To fetch the
+# current status without affecting it call the xlat with an empty argument:
+#
+# %{db_status:}
+#
+always reject {
+ rcode = reject
+}
+always fail {
+ rcode = fail
+}
+always ok {
+ rcode = ok
+}
+always handled {
+ rcode = handled
+}
+always invalid {
+ rcode = invalid
+}
+always userlock {
+ rcode = userlock
+}
+always notfound {
+ rcode = notfound
+}
+always noop {
+ rcode = noop
+}
+always updated {
+ rcode = updated
+}
diff --git a/raddb/mods-available/attr_filter b/raddb/mods-available/attr_filter
new file mode 100644
index 0000000..a23d3c0
--- /dev/null
+++ b/raddb/mods-available/attr_filter
@@ -0,0 +1,61 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# This file defines a number of instances of the "attr_filter" module.
+#
+
+# attr_filter - filters the attributes received in replies from
+# proxied servers, to make sure we send back to our RADIUS client
+# only allowed attributes.
+attr_filter attr_filter.post-proxy {
+ key = "%{Realm}"
+ filename = ${modconfdir}/${.:name}/post-proxy
+}
+
+# attr_filter - filters the attributes in the packets we send to
+# the RADIUS home servers.
+attr_filter attr_filter.pre-proxy {
+ key = "%{Realm}"
+ filename = ${modconfdir}/${.:name}/pre-proxy
+}
+
+# Enforce RFC requirements on the contents of Access-Reject
+# packets. See the comments at the top of the file for
+# more details.
+#
+attr_filter attr_filter.access_reject {
+ key = "%{User-Name}"
+ filename = ${modconfdir}/${.:name}/access_reject
+}
+
+# Enforce RFC requirements on the contents of Access-Challenge
+# packets. See the comments at the top of the file for
+# more details.
+#
+attr_filter attr_filter.access_challenge {
+ key = "%{User-Name}"
+ filename = ${modconfdir}/${.:name}/access_challenge
+}
+
+
+# Enforce RFC requirements on the contents of the
+# Accounting-Response packets. See the comments at the
+# top of the file for more details.
+#
+attr_filter attr_filter.accounting_response {
+ key = "%{User-Name}"
+ filename = ${modconfdir}/${.:name}/accounting_response
+}
+
+#
+# Enforce CoA or Disconnect packets.
+#
+# Note that you MUST edit the "coa" file below for your
+# local configuration. Add in any attributes needed by the NAS.
+#
+attr_filter attr_filter.coa {
+ key = "%{User-Name}"
+ filename = ${modconfdir}/${.:name}/coa
+}
diff --git a/raddb/mods-available/cache b/raddb/mods-available/cache
new file mode 100644
index 0000000..cf0054f
--- /dev/null
+++ b/raddb/mods-available/cache
@@ -0,0 +1,150 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# A module to cache attributes. The idea is that you can look
+# up information in a database, and then cache it. Repeated
+# requests for the same information will then have the cached
+# values added to the request.
+#
+# The module can cache a fixed set of attributes per key.
+# It can be listed in "authorize", "post-auth", "pre-proxy"
+# and "post-proxy".
+#
+# If you want different things cached for authorize and post-auth,
+# you will need to define two instances of the "cache" module.
+#
+# The module returns "ok" if it found or created a cache entry.
+# The module returns "updated" if it merged a cached entry.
+# The module returns "noop" if it did nothing.
+# The module returns "fail" on error.
+#
+cache {
+ # The backend datastore used to store the cache entries.
+ # Current datastores are
+ # rlm_cache_rbtree - An in memory, non persistent rbtree based datastore.
+ # Useful for caching data locally.
+ # rlm_cache_memcached - A non persistent "webscale" distributed datastore.
+ # Useful if the cached data need to be shared between
+ # a cluster of RADIUS servers.
+ # rlm_cache_redis - uses Redis.
+# driver = "rlm_cache_rbtree"
+
+ #
+ # Some drivers accept specific options, to set them a
+ # config section with the the name as the driver should be added
+ # to the cache instance.
+ #
+ # Driver specific options are:
+ #
+# memcached {
+# # Memcached configuration options, as documented here:
+# # http://docs.libmemcached.org/libmemcached_configuration.html#memcached
+# options = "--SERVER=localhost"
+#
+# pool {
+# start = ${thread[pool].start_servers}
+# min = ${thread[pool].min_spare_servers}
+# max = ${thread[pool].max_servers}
+# spare = ${thread[pool].max_spare_servers}
+# uses = 0
+# lifetime = 0
+# idle_timeout = 60
+# }
+# }
+
+ #
+ # See mods-available/redis for documentation on the following
+ # configuration items. They are identical here.
+ #
+ # Note that the "pool" section can re-use the normal Redis
+ # connections. This is done by setting the "pool" configuration
+ # item to the name of the Redis module. The other configuration
+ # items should then be the same as for the original "redis" module.
+ #
+# redis {
+# server = ...
+# port =
+# database =
+# query_timeout = ...
+# pool = redis
+# }
+
+ # The key used to index the cache. It is dynamically expanded
+ # at run time.
+ key = "%{User-Name}"
+
+ # The TTL of cache entries, in seconds. Entries older than this
+ # will be expired.
+ #
+ # This value should be between 10 and 86400.
+ ttl = 10
+
+ # If yes the following attributes will be added to the request:
+ # * &request:Cache-Entry-Hits - The number of times this entry
+ # has been retrieved.
+ #
+ # Note: Not supported by the rlm_cache_memcached module.
+ add_stats = no
+
+ #
+ # The list of attributes to cache for a particular key.
+ #
+ # Each key gets the same set of cached attributes. The attributes
+ # are dynamically expanded at run time.
+ #
+ # The semantics of this construct are identical to an unlang
+ # update block, except the left hand side of the expression
+ # represents the cache entry. see man unlang for more information
+ # on update blocks.
+ #
+ # Note: Only request, reply, control and session-state lists
+ # are available in cache entries. Attempting to store attributes
+ # in other lists will raise an error during config validation.
+ #
+ update {
+ # <list>:<attribute> <op> <value>
+
+ # Cache all instances of Reply-Message in the reply list
+ &reply:Reply-Message += &reply:Reply-Message[*]
+
+ # Add our own to show when the cache was last updated
+ &reply:Reply-Message += "Cache last updated at %t"
+
+ &reply:Class := "%{randstr:ssssssssssssssssssssssssssssssss}"
+ }
+
+ # This module supports a number of runtime configuration parameters
+ # represented by attributes in the &control: list.
+ #
+ # &control:Cache-TTL - Sets the TTL of an entry to be created, or
+ # modifies the TTL of an existing entry.
+ # - Setting a Cache-TTL of > 0 means set the TTL of the entry to
+ # the new value (and reset the expiry timer).
+ # - Setting a Cache-TTL of < 0 means expire the existing entry
+ # (without merging) and create a new one with TTL set to
+ # value * -1.
+ # - Setting a Cache-TTL of 0 means expire the existing entry
+ # (without merging) and don't create a new one.
+ #
+ # &control:Cache-Status-Only - If present and set to 'yes' will
+ # prevent a new entry from being created, and existing entries from
+ # being merged. It will also alter the module's return codes.
+ # - The module will return "ok" if a cache entry was found.
+ # - The module will return "notfound" if no cache entry was found.
+ #
+ # &control:Cache-Read-Only - If present and set to 'yes' will
+ # prevent a new entry from being created, but will allow existing
+ # entries to be merged. It will also alter the module's return codes.
+ # - The module will return "updated" if a cache entry was found.
+ # - The module will return "notfound" if no cache was found.
+ #
+ # &control:Cache-Merge - If present and set to 'yes' will merge new
+ # cache entries into the current request. Useful if results
+ # of execs or expansions are stored directly in the cache.
+ #
+ # All runtime configuration attributes will be removed from the
+ # &control: list after the cache module is called.
+
+}
diff --git a/raddb/mods-available/cache_auth b/raddb/mods-available/cache_auth
new file mode 100644
index 0000000..7485f36
--- /dev/null
+++ b/raddb/mods-available/cache_auth
@@ -0,0 +1,116 @@
+# -*- text -*-
+#
+# $Id$
+
+# This file contains a collection of cache module configurations
+# which have been designed to be used to cache accepts, rejects, and
+# LDAP User DNs. The main use of these modules is Google Secure
+# LDAP.
+#
+# In scenarios where there is repeated authentication requests for the same
+# user within a short time frame (e.g. 802.1x wifi), these modules can help to
+# compensate for slow responses from poor LDAP servers (i.e. Google).
+#
+# See also mods-available/ldap_google, and sites-available/google-ldap-auth.
+#
+# The configurations in this file can be used for non-Google LDAP
+# servers, too.
+#
+
+
+#
+# This instance of the cache module caches successful
+# authentications.
+#
+# The TTL controls how often the authentication will be cached.
+#
+# In addition, if group membership is used as part of the policy, the
+# &control:LDAP-Group attribute should be added to the "update: section here.
+#
+# If a user's authentication is found in the cache, then any data
+# which is normally retrieved from LDAP for local policies must also
+# be stored in the cache via the "update" section.
+#
+cache cache_auth_accept {
+ driver = "rlm_cache_rbtree"
+ key = "%{md5:%{%{Stripped-User-Name}:-%{User-Name}}%{User-Password}}"
+ ttl = 7200
+ update {
+ #
+ # We need to cache something, so we just cache
+ # a random attribute. This attribute is not used
+ # for anything else, just as a "place-holder" to
+ # contain a cache entry.
+ #
+ # If you add other attributes to this update section, then
+ # this attribute can be deleted.
+ #
+ &control:User-Category = "success"
+ }
+}
+
+
+#
+# This instance of the cache module caches failed authentications.
+#
+# In many cases, rejected users will repeatedly try to authenticate.
+# These repeated authentication attempts can cause significant load
+# on the system. By caching the reject, we can avoid hitting the database.
+#
+# We index the cache by a hash of the client's MAC and the user name
+# and password. If a user corrects their user name or password, then
+# that authentication attempt won't hit the cache, and their
+# credentials will be immediately checked against the database.
+#
+# The TTL controls how long a combination of device / user and
+# password wil be rejected without looking at the database. Once the
+# cache entry expires, the server will delete the cache entry, and
+# contact the database.
+#
+cache cache_auth_reject {
+ driver = "rlm_cache_rbtree"
+ key = "%{md5:%{Calling-Station-Id}%{Stripped-User-Name}%{User-Password}}"
+ ttl = 3600
+ update {
+ #
+ # We need to cache something, so we just cache
+ # a random attribute. This attribute is not used
+ # for anything else, just as a "place-holder" to
+ # contain a cache entry.
+ #
+ &control:User-Category = "failure"
+ }
+}
+
+
+#
+# An instance of the cache module which caches the LDAP user DN.
+#
+# If LDAP authentication is being used for a simple auth / reject without
+# any need to retrieve other attributes (e.g. group membership), each LDAP
+# bind authentication is three steps
+#
+# - bind as admin user
+# - lookup user's DN
+# - bind as user using retrieved DN
+#
+# By caching the DN after the first LDAP querry, the first two steps
+# are skipped on subsequent authentications.
+#
+# If an alternative attribute name is being used for the user DN, you
+# should change the update section here appropriately. But that is
+# likely rare.
+#
+# In scenarios where DNs may change, consideration should be given as
+# to whether use of this cache may create issues. i.e. if the cache
+# doesn't help, then don't use it.
+#
+cache cache_ldap_user_dn {
+ driver = "rlm_cache_rbtree"
+ key = "%{Stripped-User-Name}"
+ ttl = 86400
+ update {
+ &control:LDAP-UserDN = &control:LDAP-UserDN
+ }
+}
+
diff --git a/raddb/mods-available/chap b/raddb/mods-available/chap
new file mode 100644
index 0000000..e2a3cd3
--- /dev/null
+++ b/raddb/mods-available/chap
@@ -0,0 +1,11 @@
+# -*- text -*-
+#
+# $Id$
+
+# CHAP module
+#
+# To authenticate requests containing a CHAP-Password attribute.
+#
+chap {
+ # no configuration
+}
diff --git a/raddb/mods-available/couchbase b/raddb/mods-available/couchbase
new file mode 100644
index 0000000..da1a39d
--- /dev/null
+++ b/raddb/mods-available/couchbase
@@ -0,0 +1,204 @@
+couchbase {
+ #
+ # List of Couchbase hosts (hosts may be space, tab, comma or semi-colon separated).
+ # Ports are optional if servers are listening on the standard port.
+ # Complete pool urls are preferred.
+ #
+ server = "http://cb01.blargs.com:8091/pools/ http://cb04.blargs.com:8091/pools/"
+
+ # Couchbase bucket name
+ bucket = "radius"
+
+ # Couchbase bucket password (optional)
+ #password = "password"
+
+ # Couchbase accounting document key (unlang supported)
+ acct_key = "radacct_%{%{Acct-Unique-Session-Id}:-%{Acct-Session-Id}}"
+
+ # Value for the 'docType' element in the json body for accounting documents
+ doctype = "radacct"
+
+ ## Accounting document expire time in seconds (0 = never)
+ expire = 2592000
+
+ #
+ # Map attribute names to json element names for accounting.
+ #
+ # Configuration items are in the format:
+ # <radius attribute> = '<element name>'
+ #
+ # Element names should be single quoted.
+ #
+ # Note: Attributes not in this map will not be recorded.
+ #
+ update {
+ Acct-Session-Id = 'sessionId'
+ Acct-Unique-Session-Id = 'uniqueId'
+ Acct-Status-Type = 'lastStatus'
+ Acct-Authentic = 'authentic'
+ User-Name = 'userName'
+ Stripped-User-Name = 'strippedUserName'
+ Stripped-User-Domain = 'strippedUserDomain'
+ Realm = 'realm'
+ NAS-IP-Address = 'nasIpAddress'
+ NAS-Identifier = 'nasIdentifier'
+ NAS-Port = 'nasPort'
+ Called-Station-Id = 'calledStationId'
+ Called-Station-SSID = 'calledStationSSID'
+ Calling-Station-Id = 'callingStationId'
+ Framed-Protocol = 'framedProtocol'
+ Framed-IP-Address = 'framedIpAddress'
+ NAS-Port-Type = 'nasPortType'
+ Connect-Info = 'connectInfo'
+ Acct-Session-Time = 'sessionTime'
+ Acct-Input-Packets = 'inputPackets'
+ Acct-Output-Packets = 'outputPackets'
+ Acct-Input-Octets = 'inputOctets'
+ Acct-Output-Octets = 'outputOctets'
+ Acct-Input-Gigawords = 'inputGigawords'
+ Acct-Output-Gigawords = 'outputGigawords'
+ Event-Timestamp = 'lastUpdated'
+ }
+
+ # Couchbase document key for user documents (unlang supported)
+ user_key = "raduser_%{md5:%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}}}"
+
+ # Set to 'yes' to read radius clients from the Couchbase view specified below.
+ # NOTE: Clients will ONLY be read on server startup.
+ #read_clients = no
+
+ #
+ # Map attribute names to json element names when loading clients.
+ #
+ # Configuration follows the same rules as the accounting map above.
+ #
+ client {
+ # Couchbase view that should return all available client documents.
+ view = "_design/client/_view/by_id"
+
+ #
+ # Sets default values (not obtained from couchbase) for new client entries
+ #
+ template {
+# login = 'test'
+# password = 'test'
+# proto = tcp
+# require_message_authenticator = yes
+
+ # Uncomment to add a home_server with the same
+ # attributes as the client.
+# coa_server {
+# response_window = 2.0
+# }
+ }
+
+ #
+ # Client mappings are in the format:
+ # <client attribute> = '<element name>'
+ #
+ # Element names should be single quoted.
+ #
+ # The following attributes are required:
+ # * ipaddr | ipv4addr | ipv6addr - Client IP Address.
+ # * secret - RADIUS shared secret.
+ #
+ # All attributes usually supported in a client
+ # definition are also supported here.
+ #
+ attribute {
+ ipaddr = 'clientIdentifier'
+ secret = 'clientSecret'
+ shortname = 'clientShortname'
+ nas_type = 'nasType'
+ virtual_server = 'virtualServer'
+ require_message_authenticator = 'requireMessageAuthenticator'
+ limit {
+ max_connections = 'maxConnections'
+ lifetime = 'clientLifetime'
+ idle_timeout = 'idleTimeout'
+ }
+ }
+ }
+
+ # Set to 'yes' to enable simultaneous use checking (multiple logins).
+ # NOTE: This will cause the execution of a view request on every check
+ # and may be a performance penalty.
+# check_simul = no
+
+ # Couchbase view that should return all account documents keyed by username.
+# simul_view = "_design/acct/_view/by_user"
+
+ # The key to the above view.
+ # NOTE: This will need to match EXACTLY what you emit from your view.
+# simul_vkey = "%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}}"
+
+ # Set to 'yes' to enable verification of the results returned from the above view.
+ # NOTE: This may be an additional performance penalty to the actual check and
+ # should be avoided unless absolutely neccessary.
+# verify_simul = no
+
+ # Remove stale session if checkrad does not see a double login.
+ # NOTE: This will only be executed if both check_simul and verify_simul
+ # are set to 'yes' above.
+# delete_stale_sessions = yes
+
+ #
+ # The connection pool is used to pool outgoing connections.
+ #
+ pool {
+ # 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
+ # couchbase being available.
+ start = ${thread[pool].start_servers}
+
+ # Minimum number of connections to keep open
+ min = ${thread[pool].min_spare_servers}
+
+ # 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.
+ max = ${thread[pool].max_servers}
+
+ # 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.
+ spare = ${thread[pool].max_spare_servers}
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ uses = 0
+
+ # The lifetime (in seconds) of the connection
+ #
+ # NOTE: A setting of 0 means infinite (no limit).
+ lifetime = 0
+
+ # 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).
+ idle_timeout = 1200
+
+ # 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.
+ }
+}
diff --git a/raddb/mods-available/counter b/raddb/mods-available/counter
new file mode 100644
index 0000000..a5ac1e6
--- /dev/null
+++ b/raddb/mods-available/counter
@@ -0,0 +1,82 @@
+# -*- text -*-
+#
+# $Id$
+
+# counter module:
+# This module takes an attribute (count-attribute).
+# It also takes a key, and creates a counter for each unique
+# key. The count is incremented when accounting packets are
+# received by the server. The value of the increment depends
+# on the attribute type.
+# If the attribute is Acct-Session-Time or of an integer type we add
+# the value of the attribute. If it is anything else we increase the
+# counter by one.
+#
+# The 'reset' parameter defines when the counters are all reset to
+# zero. It can be hourly, daily, weekly, monthly or never.
+#
+# hourly: Reset on 00:00 of every hour
+# daily: Reset on 00:00:00 every day
+# weekly: Reset on 00:00:00 on sunday
+# monthly: Reset on 00:00:00 of the first day of each month
+#
+# It can also be user defined. It should be of the form:
+# num[hdwm] where:
+# h: hours, d: days, w: weeks, m: months
+# If the letter is omitted days will be assumed. In example:
+# reset = 10h (reset every 10 hours)
+# reset = 12 (reset every 12 days)
+#
+#
+# The check_name attribute defines an attribute which will be
+# registered by the counter module and can be used to set the
+# maximum allowed value for the counter after which the user
+# is rejected.
+# Something like:
+#
+# DEFAULT Max-Daily-Session := 36000
+# Fall-Through = 1
+#
+# You should add the counter module in the instantiate
+# section so that it registers check_name before the files
+# module reads the users file.
+#
+# If check_name is set and the user is to be rejected then we
+# send back a Reply-Message and we log a Failure-Message in
+# the radius.log
+#
+# If the count attribute is Acct-Session-Time then on each
+# login we send back the remaining online time as a
+# Session-Timeout attribute ELSE and if the reply_name is
+# set, we send back that attribute. The reply_name attribute
+# MUST be of an integer type.
+#
+# The counter-name can also be used instead of using the check_name
+# like below:
+#
+# DEFAULT Daily-Session-Time > 3600, Auth-Type = Reject
+# Reply-Message = "You've used up more than one hour today"
+#
+# The allowed_service_type attribute can be used to only take
+# into account specific sessions. For example if a user first
+# logs in through a login menu and then selects ppp there will
+# be two sessions. One for Login-User and one for Framed-User
+# service type. We only need to take into account the second one.
+#
+# The module should be added in the instantiate, authorize and
+# accounting sections. Make sure that in the authorize
+# section it comes after any module which sets the
+# 'check_name' attribute.
+#
+counter daily {
+ filename = ${db_dir}/db.daily
+ key = User-Name
+ count_attribute = Acct-Session-Time
+ reset = daily
+ counter_name = Daily-Session-Time
+ check_name = Max-Daily-Session
+ reply_name = Session-Timeout
+ allowed_service_type = Framed-User
+ cache_size = 5000
+}
+
diff --git a/raddb/mods-available/cui b/raddb/mods-available/cui
new file mode 100644
index 0000000..54842d4
--- /dev/null
+++ b/raddb/mods-available/cui
@@ -0,0 +1,53 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Write Chargeable-User-Identity to the database.
+#
+# Schema raddb/mods-config/sql/cui/<DB>/schema.sql
+# Queries raddb/mods-config/sql/cui/<DB>/queries.conf
+#
+sql cuisql {
+
+ # The dialect of SQL you want to use, this should usually match
+ # the driver below.
+ #
+ # If you're using rlm_sql_null, then it should be the type of
+ # database the logged queries are going to be executed against.
+ dialect = "sqlite"
+
+ # The sub-module to use to execute queries. This should match
+ # the database you're attempting to connect to.
+ #
+ # There are CUI queries available for:
+ # * rlm_sql_mysql
+ # * rlm_sql_postgresql
+ # * rlm_sql_sqlite
+ # * rlm_sql_null (log queries to disk)
+ #
+ driver = "rlm_sql_${dialect}"
+
+ sqlite {
+ filename = ${radacctdir}/cui.sqlite
+ bootstrap = ${modconfdir}/${..:name}/cui/sqlite/schema.sql
+ }
+
+ # Write CUI queries to a logfile. Useful for debugging.
+# logfile = ${logdir}/cuilog.sql
+
+ pool {
+ start = 5
+ min = 4
+ max = 10
+ spare = 3
+ uses = 0
+ lifetime = 0
+ idle_timeout = 60
+ }
+
+ cui_table = "cui"
+ sql_user_name = "%{User-Name}"
+
+ $INCLUDE ${modconfdir}/${.:name}/cui/${dialect}/queries.conf
+}
diff --git a/raddb/mods-available/date b/raddb/mods-available/date
new file mode 100644
index 0000000..25a64da
--- /dev/null
+++ b/raddb/mods-available/date
@@ -0,0 +1,35 @@
+#
+# Registers xlat to convert between time formats.
+#
+# xlat input string is an attribute name. If this attribute is of date
+# or integer type, the date xlat will convert it to a time string in
+# the format of the format config item.
+#
+# If the attribute is a string type, date will attempt to parse it in
+# the format specified by the format config item, and will expand
+# to a Unix timestamp.
+#
+date {
+ format = "%b %e %Y %H:%M:%S %Z"
+
+ # Use UTC instead of local time.
+ #
+ # default = no
+# utc = yes
+}
+
+#
+# The WISPr-Session-Terminate-Time attribute is of type "string",
+# and not "date". Use this expansion to create an attribute
+# that holds an actual date:
+#
+# Tmp-Date-0 := "%{wispr2date:&reply:WISPr-Session-Terminate-Time}"
+#
+date wispr2date {
+ format = "%Y-%m-%dT%H:%M:%S"
+
+ # Use UTC instead of local time.
+ #
+ # default = no
+# utc = yes
+}
diff --git a/raddb/mods-available/detail b/raddb/mods-available/detail
new file mode 100644
index 0000000..ccf65f9
--- /dev/null
+++ b/raddb/mods-available/detail
@@ -0,0 +1,109 @@
+# -*- text -*-
+#
+# $Id$
+
+# Write a detailed log of all accounting records received.
+#
+detail {
+ # Note that we do NOT use NAS-IP-Address here, as
+ # that attribute MAY BE from the originating NAS, and
+ # NOT from the proxy which actually sent us the
+ # request.
+ #
+ # The following line creates a new detail file for
+ # every radius client (by IP address or hostname).
+ # In addition, a new detail file is created every
+ # day, so that the detail file doesn't have to go
+ # through a 'log rotation'
+ #
+ # If your detail files are large, you may also want to add
+ # a ':%H' (see doc/configuration/variables.rst) to the end
+ # of it, to create a new detail file every hour, e.g.:
+ #
+ # ..../detail-%Y%m%d:%H
+ #
+ # This will create a new detail file for every hour.
+ #
+ # If you are reading detail files via the "listen" section
+ # (e.g. as in raddb/sites-available/robust-proxy-accounting),
+ # you MUST use a unique directory for each combination of a
+ # detail file writer, and reader. That is, there can only
+ # be ONE "listen" section reading detail files from a
+ # particular directory.
+ #
+ # The configuration below puts the detail files into separate
+ # directories for each client. If you are reading the detail
+ # files via the "listen" section, just use one directory.
+ #
+ # e.g. filename = ${radacctdir}/reader1/detail-%Y%m%d
+ #
+ # AND use a separate directory (reader2, reader3, etc.) for each
+ # reader.
+ #
+ filename = ${radacctdir}/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d
+
+ #
+ # If you are using radrelay, delete the above line for "file",
+ # and use this one instead:
+ #
+# filename = ${radacctdir}/detail
+
+ #
+ # Most file systems can handly nearly the full range of UTF-8
+ # characters. Ones that can deal with a limited range should
+ # set this to "yes".
+ #
+ escape_filenames = no
+
+ #
+ # The Unix-style permissions on the 'detail' file.
+ #
+ # The detail file often contains secret or private
+ # information about users. So by keeping the file
+ # permissions restrictive, we can prevent unwanted
+ # people from seeing that information.
+ permissions = 0600
+
+ # The Unix group of the log file.
+ #
+ # The user that the server runs as must be in the specified
+ # system group otherwise this will fail to work.
+ #
+# group = ${security.group}
+
+ #
+ # Every entry in the detail file has a header which
+ # is a timestamp. By default, we use the ctime
+ # format (see "man ctime" for details).
+ #
+ # The header can be customised by editing this
+ # string. See "doc/configuration/variables.rst" for a
+ # description of what can be put here.
+ #
+ header = "%t"
+
+ #
+ # Uncomment this line if the detail file reader will be
+ # reading this detail file.
+ #
+# locking = yes
+
+ #
+ # Log the Packet src/dst IP/port. This is disabled by
+ # default, as that information isn't used by many people.
+ #
+# log_packet_header = yes
+
+ #
+ # Certain attributes such as User-Password may be
+ # "sensitive", so they should not be printed in the
+ # detail file. This section lists the attributes
+ # that should be suppressed.
+ #
+ # The attributes should be listed one to a line.
+ #
+ #suppress {
+ # User-Password
+ #}
+
+}
diff --git a/raddb/mods-available/detail.example.com b/raddb/mods-available/detail.example.com
new file mode 100644
index 0000000..827cdf5
--- /dev/null
+++ b/raddb/mods-available/detail.example.com
@@ -0,0 +1,27 @@
+# -*- text -*-
+#
+# Detail file writer, used in the following examples:
+#
+# raddb/sites-available/robust-proxy-accounting
+# raddb/sites-available/decoupled-accounting
+#
+# Note that this module can write detail files that are read by
+# only ONE "listen" section. If you use BOTH of the examples
+# above, you will need to define TWO "detail" modules.
+#
+# e.g. detail1.example.com && detail2.example.com
+#
+#
+# We write *multiple* detail files here. They will be processed by
+# the detail "listen" section in the order that they were created.
+# The directory containing these files should NOT be used for any
+# other purposes. i.e. It should have NO other files in it.
+#
+# Writing multiple detail enables the server to process the pieces
+# in smaller chunks. This helps in certain catastrophic corner cases.
+#
+# $Id$
+#
+detail detail.example.com {
+ filename = ${radacctdir}/detail.example.com/detail-%Y%m%d:%H:%G
+}
diff --git a/raddb/mods-available/detail.log b/raddb/mods-available/detail.log
new file mode 100644
index 0000000..b91cf7c
--- /dev/null
+++ b/raddb/mods-available/detail.log
@@ -0,0 +1,75 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# More examples of doing detail logs.
+
+#
+# Many people want to log authentication requests.
+# Rather than modifying the server core to print out more
+# messages, we can use a different instance of the 'detail'
+# module, to log the authentication requests to a file.
+#
+# You will also need to un-comment the 'auth_log' line
+# in the 'authorize' section, below.
+#
+detail auth_log {
+ filename = ${radacctdir}/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/auth-detail-%Y%m%d
+
+ #
+ # This MUST be 0600, otherwise anyone can read
+ # the users passwords!
+ permissions = 0600
+
+ # You may also strip out passwords completely
+ suppress {
+ User-Password
+ }
+}
+
+#
+# This module logs authentication reply packets sent
+# to a NAS. Both Access-Accept and Access-Reject packets
+# are logged.
+#
+# You will also need to un-comment the 'reply_log' line
+# in the 'post-auth' section, below.
+#
+detail reply_log {
+ filename = ${radacctdir}/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/reply-detail-%Y%m%d
+
+ permissions = 0600
+}
+
+#
+# This module logs packets proxied to a home server.
+#
+# You will also need to un-comment the 'pre_proxy_log' line
+# in the 'pre-proxy' section, below.
+#
+detail pre_proxy_log {
+ filename = ${radacctdir}/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/pre-proxy-detail-%Y%m%d
+
+ #
+ # This MUST be 0600, otherwise anyone can read
+ # the users passwords!
+ permissions = 0600
+
+ # You may also strip out passwords completely
+ #suppress {
+ # User-Password
+ #}
+}
+
+#
+# This module logs response packets from a home server.
+#
+# You will also need to un-comment the 'post_proxy_log' line
+# in the 'post-proxy' section, below.
+#
+detail post_proxy_log {
+ filename = ${radacctdir}/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/post-proxy-detail-%Y%m%d
+
+ permissions = 0600
+}
diff --git a/raddb/mods-available/dhcp b/raddb/mods-available/dhcp
new file mode 100644
index 0000000..a431633
--- /dev/null
+++ b/raddb/mods-available/dhcp
@@ -0,0 +1,19 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# This module is useful only for 'xlat'. To use it,
+# put 'dhcp' into the 'instantiate' section.
+#
+# %{dhcp_options:<Attribute-ref>} may be used to decode
+# DHCP options data included in RADIUS packets by vendors
+# of DHCP to RADIUS gateways.
+#
+# This is known to work with the following VSAs:
+# * Juniper - ERX-Dhcp-Options
+# * Alcatel lucent SR - Alc-ToServer-Dhcp-Options
+# - Alc-ToClient-Dhcp-Options
+#
+dhcp {
+}
diff --git a/raddb/mods-available/dhcp_files b/raddb/mods-available/dhcp_files
new file mode 100644
index 0000000..243a241
--- /dev/null
+++ b/raddb/mods-available/dhcp_files
@@ -0,0 +1,56 @@
+# -*- text -*-
+#
+# $Id$
+
+# Instances of the "files" module for managing DHCP options
+#
+files dhcp_network {
+ # The file containing network-specific DHCP options mapping
+ filename = ${modconfdir}/files/dhcp
+
+ # For network lookups we use a fixed key. Matching
+ # actual networks is done by additional filtering within
+ # the file
+ key = "network"
+}
+
+files dhcp_subnet {
+ # The file containing subnet-specific DHCP options mapping
+ filename = ${modconfdir}/files/dhcp
+
+ # For subnet lookups we use a fixed key. Matching
+ # actual subnets is done by additional filtering within
+ # the file
+ key = "subnet"
+}
+
+files dhcp_set_group_options {
+ # An example of looking up DHCP group options. This
+ # is designed to be called from a policy configured in
+ # policy.d/dhcp.
+ #
+ # If clients are never members of more than one group,
+ # then this could be simplified such that DHCP-Group-Name
+ # is used here in place of Foreach-Variable-0 and this
+ # module instance called directly rather than the policy
+
+ # Use the same file as for subnets - could be split
+ # for large, complex installations
+ filename = ${modconfdir}/files/dhcp
+
+ # The key is a temporary string populated by the calling policy
+ # which uses a foreach loop.
+ key = "%{Foreach-Variable-0}"
+}
+
+files dhcp_hosts {
+ # An example of a DHCP host mapping for option setting
+
+ # Use the same file as for subnets - could be split
+ # for large, complex installations
+ filename = ${modconfdir}/files/dhcp
+
+ # If a different identifier is needed for looking up
+ # host specific entries then amend this key.
+ key = "host-%{DHCP-Client-Hardware-Address}"
+}
diff --git a/raddb/mods-available/dhcp_passwd b/raddb/mods-available/dhcp_passwd
new file mode 100644
index 0000000..7884a00
--- /dev/null
+++ b/raddb/mods-available/dhcp_passwd
@@ -0,0 +1,20 @@
+# -*- text -*-
+#
+# $Id$
+
+# An instance of the passwd module designed for looking up
+# DHCP client membership. This example is based on hardware
+# address.
+# The "groups" file should be of the format:
+# <group name>|<hardware address>,<hardware address>,<hardware address>
+# <group name>|<hardware address>,<hardware address>,<hardware address>
+#
+# See the passwd module for more details.
+
+passwd dhcp_group_membership {
+ filename = "${modconfdir}/files/dhcp_groups"
+ format = "~DHCP-Group-Name:*,DHCP-Client-Hardware-Address"
+ hash_size = 100
+ allow_multiple_keys = yes
+ delimiter = "|"
+}
diff --git a/raddb/mods-available/dhcp_sql b/raddb/mods-available/dhcp_sql
new file mode 100644
index 0000000..20dbe3a
--- /dev/null
+++ b/raddb/mods-available/dhcp_sql
@@ -0,0 +1,92 @@
+# -*- text -*-
+##
+## mods-available/sql -- SQL modules
+##
+## $Id$
+
+######################################################################
+#
+# Configuration for the DHCP-specific instance of the SQL module
+#
+# The database schemas and queries are located in subdirectories:
+#
+# sql/dhcp/<DB>/schema.sql Schema
+# sql/dhcp/<DB>/queries.conf Reply options lookup queries
+#
+# Where "DB" is mysql, mssql, oracle, or postgresql.
+#
+
+#
+# See raddb/mods-available/sql for a description of the configuration items
+# for the sql module.
+#
+sql dhcp_sql {
+ dialect = "sqlite"
+ driver = "rlm_sql_null"
+# driver = "rlm_sql_${dialect}"
+
+ sqlite {
+ filename = "/tmp/freeradius.db"
+ busy_timeout = 200
+ bootstrap = "${modconfdir}/${..:name}/dhcp/sqlite/schema.sql"
+ }
+
+ mysql {
+ tls {
+ ca_file = "/etc/ssl/certs/my_ca.crt"
+ ca_path = "/etc/ssl/certs/"
+ certificate_file = "/etc/ssl/certs/private/client.crt"
+ private_key_file = "/etc/ssl/certs/private/client.key"
+ cipher = "DHE-RSA-AES256-SHA:AES128-SHA"
+
+ tls_required = yes
+ tls_check_cert = no
+ tls_check_cert_cn = no
+ }
+ warnings = auto
+ }
+
+ postgresql {
+ send_application_name = yes
+ }
+
+ mongo {
+ appname = "freeradius"
+ tls {
+ certificate_file = /path/to/file
+ certificate_password = "password"
+ ca_file = /path/to/file
+ ca_dir = /path/to/directory
+ crl_file = /path/to/file
+ weak_cert_validation = false
+ allow_invalid_hostname = false
+ }
+ }
+
+# server = "localhost"
+# port = 3306
+# login = "radius"
+# password = "radpass"
+
+ radius_db = "radius"
+
+ dhcpreply_table = "dhcpreply"
+ groupreply_table = "dhcpgroupreply"
+ dhcpgroup_table = "dhcpgroup"
+ read_groups = no
+
+ pool {
+ start = ${thread[pool].start_servers}
+ min = ${thread[pool].min_spare_servers}
+ max = ${thread[pool].max_servers}
+ spare = ${thread[pool].max_spare_servers}
+ uses = 0
+ retry_delay = 30
+ lifetime = 0
+ idle_timeout = 60
+ }
+
+ group_attribute = "${.:instance}-SQL-Group"
+
+ $INCLUDE ${modconfdir}/${.:name}/dhcp/${dialect}/queries.conf
+}
diff --git a/raddb/mods-available/dhcp_sqlippool b/raddb/mods-available/dhcp_sqlippool
new file mode 100644
index 0000000..909b93c
--- /dev/null
+++ b/raddb/mods-available/dhcp_sqlippool
@@ -0,0 +1,101 @@
+# Configuration for DHCP for the SQL based IP Pools module (rlm_sqlippool).
+#
+# See raddb/mods-available/sqlippool for common configuration explanation
+#
+# See raddb/policy.d/dhcp_sqlippool for the "glue" code that allows
+# the RADIUS based "sqlippool" module to be used for DHCP.
+#
+# See raddb/sites-available/dhcp for instructions on how to configure
+# the DHCP server.
+#
+# The database schemas are available at:
+#
+# raddb/mods-config/sql/ippool-dhcp/<DB>/schema.sql
+#
+# $Id$
+
+sqlippool dhcp_sqlippool {
+ # SQL instance to use (from mods-available/sql)
+ #
+ # If you have multiple sql instances, such as "sql sql1 {...}",
+ # use the *instance* name here: sql1.
+ sql_module_instance = "dhcp_sql"
+
+ # This is duplicative of info available in the SQL module, but
+ # we have to list it here as we do not yet support nested
+ # reference expansions.
+ dialect = "mysql"
+
+ # Name of the check item attribute to be used as a key in the SQL queries
+ pool_name = "Pool-Name"
+
+ # SQL table to use for ippool range and lease info
+ ippool_table = "dhcpippool"
+
+ # The duration for which a lease is reserved whilst under offer
+ offer_duration = 10
+
+ # IP lease duration. (Leases expire even if no DHCP-Release packet is received)
+ # Either use the value to be sent to the client or a hard coded one.
+ lease_duration = "%{reply:DHCP-IP-Address-Lease-Time}"
+ #lease_duration = 7200
+
+ # The attribute in which the IP address is returned in the reply
+ attribute_name = "DHCP-Your-IP-Address"
+
+ # Assign the IP address, even if the above attribute already exists in
+ # the reply.
+ #
+# allow_duplicates = no
+
+ # The attribute in which an IP address hint may be supplied
+ req_attribute_name = "DHCP-Requested-IP-Address"
+
+ #
+ # RFC 2132 allows the DHCP client to supply a unique
+ # identifier ("uid") using Option 61 (DHCP-Client-Identifier)
+ # in which case it must be used as the lookup key for
+ # configuration data.
+ #
+ pool_key = "%{%{DHCP-Client-Identifier}:-%{DHCP-Client-Hardware-Address}}"
+ #
+ # The "uid" is generated by the OS which means that clients
+ # whose BMC piggybacks on the main interface (sharing its MAC,
+ # but generating a distinct uid) and dual-booting clients can
+ # be allocated multiple IPs, consuming more pool entries. To
+ # avoid this you can ignore the RFCs and key the configuration
+ # data based only on the client MAC address.
+ #
+ # pool_key = "%{DHCP-Client-Hardware-Address}"
+
+ ################################################################
+ #
+ # WARNING: MySQL (MyISAM) has certain limitations that means it can
+ # hand out the same IP address to 2 different users.
+ #
+ # We suggest using an SQL DB with proper transaction
+ # support, such as PostgreSQL, or using MySQL
+ # with InnoDB.
+ #
+ ################################################################
+
+ # These messages are added to the "control" items, as
+ # Module-Success-Message. They are not logged anywhere else,
+ # unlike previous versions. If you want to have them logged
+ # to a file, see the "linelog" module, and create an entry
+ # which writes Module-Success-Message message.
+ #
+ messages {
+ exists = "DHCP: Existing IP: %{reply:${..attribute_name}} (cid %{DHCP-Client-Identifier} chaddr %{DHCP-Client-Hardware-Address} giaddr %{DHCP-Gateway-IP-Address})"
+
+ success = "DHCP: Allocated IP: %{reply:${..attribute_name}} from %{control:${..pool_name}} (cid %{DHCP-Client-Identifier} chaddr %{DHCP-Client-Hardware-Address} giaddr %{DHCP-Gateway-IP-Address})"
+
+ clear = "DHCP: Released IP %{DHCP-Client-IP-Address} (cid %{DHCP-Client-Identifier} chaddr %{DHCP-Client-Hardware-Address} giaddr %{DHCP-Gateway-IP-Address})"
+
+ failed = "DHCP: IP Allocation FAILED from %{control:${..pool_name}} (cid %{DHCP-Client-Identifier} chaddr %{DHCP-Client-Hardware-Address} giaddr %{DHCP-Gateway-IP-Address})"
+
+ nopool = "DHCP: No ${..pool_name} defined (cid %{DHCP-Client-Identifier} chaddr %{DHCP-Client-Hardware-Address} giaddr %{DHCP-Gateway-IP-Address})"
+ }
+
+ $INCLUDE ${modconfdir}/sql/ippool-dhcp/${dialect}/queries.conf
+}
diff --git a/raddb/mods-available/digest b/raddb/mods-available/digest
new file mode 100644
index 0000000..f0aa9ed
--- /dev/null
+++ b/raddb/mods-available/digest
@@ -0,0 +1,13 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# The 'digest' module currently has no configuration.
+#
+# "Digest" authentication against a Cisco SIP server.
+# See 'doc/rfc/draft-sterman-aaa-sip-00.txt' for details
+# on performing digest authentication for Cisco SIP servers.
+#
+digest {
+}
diff --git a/raddb/mods-available/dynamic_clients b/raddb/mods-available/dynamic_clients
new file mode 100644
index 0000000..cc2bd5f
--- /dev/null
+++ b/raddb/mods-available/dynamic_clients
@@ -0,0 +1,32 @@
+# -*- text -*-
+#
+# $Id$
+
+# This module loads RADIUS clients as needed, rather than when the server
+# starts.
+#
+# There are no configuration entries for this module. Instead, it
+# relies on the "client" configuration. You must:
+#
+# 1) link raddb/sites-enabled/dynamic_clients to
+# raddb/sites-available/dynamic_clients
+#
+# 2) Define a client network/mask (see top of the above file)
+#
+# 3) uncomment the "directory" entry in that client definition
+#
+# 4) list "dynamic_clients" in the "authorize" section of the
+# "dynamic_clients' virtual server. The default example already
+# does this.
+#
+# 5) put files into the above directory, one per IP.
+# e.g. file "192.0.2.1" should contain a normal client definition
+# for a client with IP address 192.0.2.1.
+#
+# For more documentation, see the file:
+#
+# raddb/sites-available/dynamic-clients
+#
+dynamic_clients {
+
+}
diff --git a/raddb/mods-available/eap b/raddb/mods-available/eap
new file mode 100644
index 0000000..ee9e539
--- /dev/null
+++ b/raddb/mods-available/eap
@@ -0,0 +1,1115 @@
+# -*- text -*-
+##
+## eap.conf -- Configuration for EAP types (PEAP, TTLS, etc.)
+##
+## $Id$
+
+#######################################################################
+#
+# Whatever you do, do NOT set 'Auth-Type := EAP'. The server
+# is smart enough to figure this out on its own. The most
+# common side effect of setting 'Auth-Type := EAP' is that the
+# users then cannot use ANY other authentication method.
+#
+eap {
+ # Invoke the default supported EAP type when
+ # EAP-Identity response is received.
+ #
+ # The incoming EAP messages DO NOT specify which EAP
+ # type they will be using, so it MUST be set here.
+ #
+ # For now, only one default EAP type may be used at a time.
+ #
+ # If the EAP-Type attribute is set by another module,
+ # then that EAP type takes precedence over the
+ # default type configured here.
+ #
+ default_eap_type = md5
+
+ # A list is maintained to correlate EAP-Response
+ # packets with EAP-Request packets. After a
+ # configurable length of time, entries in the list
+ # expire, and are deleted.
+ #
+ timer_expire = 60
+
+ # There are many EAP types, but the server has support
+ # for only a limited subset. If the server receives
+ # a request for an EAP type it does not support, then
+ # it normally rejects the request. By setting this
+ # configuration to "yes", you can tell the server to
+ # instead keep processing the request. Another module
+ # MUST then be configured to proxy the request to
+ # another RADIUS server which supports that EAP type.
+ #
+ # If another module is NOT configured to handle the
+ # request, then the request will still end up being
+ # rejected.
+ #
+ ignore_unknown_eap_types = no
+
+ # Cisco AP1230B firmware 12.2(13)JA1 has a bug. When given
+ # a User-Name attribute in an Access-Accept, it copies one
+ # more byte than it should.
+ #
+ # We can work around it by configurably adding an extra
+ # zero byte.
+ #
+ cisco_accounting_username_bug = no
+
+ # Help prevent DoS attacks by limiting the number of
+ # sessions that the server is tracking. For simplicity,
+ # this is taken from the "max_requests" directive in
+ # radiusd.conf.
+ #
+ max_sessions = ${max_requests}
+
+
+ ############################################################
+ #
+ # Supported EAP-types
+ #
+
+
+ # EAP-MD5
+ #
+ # We do NOT recommend using EAP-MD5 authentication
+ # for wireless connections. It is insecure, and does
+ # not provide for dynamic WEP keys.
+ #
+ md5 {
+ }
+
+
+ # EAP-pwd -- secure password-based authentication
+ #
+ #pwd {
+ # group = 19
+
+ # server_id = theserver@example.com
+
+ # This has the same meaning as for TLS.
+ #
+ # fragment_size = 1020
+
+ # The virtual server which determines the
+ # "known good" password for the user.
+ # Note that unlike TLS, only the "authorize"
+ # section is processed. EAP-PWD requests can be
+ # distinguished by having a User-Name, but
+ # no User-Password, CHAP-Password, EAP-Message, etc.
+ #
+ # virtual_server = "inner-tunnel"
+ #}
+
+
+ # Cisco LEAP
+ #
+ # We do not recommend using LEAP in new deployments. See:
+ # http://www.securiteam.com/tools/5TP012ACKE.html
+ #
+ # LEAP is not supported.
+ # It is insecure, and no one should be using it.
+ #
+
+
+ # EAP-GTC -- Generic Token Card
+ #
+ # Currently, this is only permitted inside of EAP-TTLS,
+ # or EAP-PEAP. The module "challenges" the user with
+ # text, and the response from the user is taken to be
+ # the User-Password.
+ #
+ # Proxying the tunneled EAP-GTC session is a bad idea,
+ # the users password will go over the wire in plain-text,
+ # for anyone to see.
+ #
+ gtc {
+ # The default challenge, which many clients
+ # ignore..
+ #
+ # challenge = "Password: "
+
+ # The plain-text response which comes back
+ # is put into a User-Password attribute,
+ # and passed to another module for
+ # authentication. This allows the EAP-GTC
+ # response to be checked against plain-text,
+ # or crypt'd passwords.
+ #
+ # If you say "Local" instead of "PAP", then
+ # the module will look for a User-Password
+ # configured for the request, and do the
+ # authentication itself.
+ #
+ auth_type = PAP
+ }
+
+
+ # Common TLS configuration for TLS-based EAP types
+ # ------------------------------------------------
+ #
+ # See raddb/certs/README.md for additional comments
+ # on certificates.
+ #
+ # If OpenSSL was not found at the time the server was
+ # built, the "tls", "ttls", and "peap" sections will
+ # be ignored.
+ #
+ # If you do not currently have certificates signed by
+ # a trusted CA you may use the 'snakeoil' certificates.
+ # Included with the server in raddb/certs.
+ #
+ # If these certificates have not been auto-generated:
+ # cd raddb/certs
+ # make
+ #
+ # These test certificates SHOULD NOT be used in a normal
+ # deployment. They are created only to make it easier
+ # to install the server, and to perform some simple
+ # tests with EAP-TLS, TTLS, or PEAP.
+ #
+ # Note that you should NOT use a globally known CA here!
+ # e.g. using a Verisign cert as a "known CA" means that
+ # ANYONE who has a certificate signed by them can
+ # authenticate via EAP-TLS! This is likely not what you want.
+ #
+ tls-config tls-common {
+ 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
+ # name.
+ #
+ # If ca_file (below) is not used, then the
+ # certificate_file below SHOULD also include all of
+ # the intermediate CA certificates used to sign the
+ # server certificate, but NOT the root CA.
+ #
+ # Including the ROOT CA certificate is not useful and
+ # merely inflates the exchanged data volume during
+ # the TLS negotiation.
+ #
+ # This file should contain the server certificate,
+ # followed by intermediate certificates, in order.
+ # i.e. If we have a server certificate signed by CA1,
+ # which is signed by CA2, which is signed by a root
+ # CA, then the "certificate_file" should contain
+ # server.pem, followed by CA1.pem, followed by
+ # CA2.pem.
+ #
+ # When using "ca_file" or "ca_path", the
+ # "certificate_file" should contain only
+ # "server.pem". And then you may (or may not) need
+ # to set "auto_chain", depending on your version of
+ # OpenSSL.
+ #
+ # In short, SSL / TLS certificates are complex.
+ # There are many versions of software, each of which
+ # behave slightly differently. It is impossible to
+ # give advice which will work everywhere. Instead,
+ # we give general guidelines.
+ #
+ certificate_file = ${certdir}/server.pem
+
+ # Trusted Root CA list
+ #
+ # This file can contain multiple CA certificates.
+ # ALL of the CA's in this list will be trusted to
+ # issue client certificates for authentication.
+ #
+ # In general, you should use self-signed
+ # certificates for 802.1x (EAP) authentication.
+ # In that case, this CA file should contain
+ # *one* CA certificate.
+ #
+ ca_file = ${cadir}/ca.pem
+
+ #
+ # Directory where multiple CAs are stored. Both
+ # "ca_file" and "ca_path" can be used at the same time.
+ #
+ ca_path = ${cadir}
+
+ # OpenSSL does not reload contents of ca_path dir over time.
+ # That means that if check_crl is enabled and CRLs are loaded
+ # from ca_path dir, at some point CRLs will expire and
+ # the server will stop authenticating users.
+ #
+ # If ca_path_reload_interval is non-zero, it will force OpenSSL
+ # to reload all data from ca_path periodically
+ #
+ # Flush ca_path each hour
+ # ca_path_reload_interval = 3600
+
+ # OpenSSL will automatically create certificate chains,
+ # unless we tell it to not do that. The problem is that
+ # it sometimes gets the chains right from a certificate
+ # signature view, but wrong from the clients view.
+ #
+ # When setting "auto_chain = no", the server certificate
+ # file MUST include the full certificate chain.
+ #
+ # auto_chain = yes
+
+ # If OpenSSL supports TLS-PSK, then we can use a
+ # fixed PSK identity and (hex) password. These can
+ # be used at the same time as the certificate
+ # configuration, but only for TLS 1.0 through 1.2.
+ #
+ # If PSK and certificates are configured at the same
+ # time for TLS 1.3, then the server will warn you,
+ # and will disable TLS 1.3, as it will not work.
+ #
+ # The work around is to have two modules (or for
+ # RadSec, two listen sections). One will have PSK
+ # configured, and the other will have certificates
+ # configured.
+ #
+ # psk_identity = "test"
+ # psk_hexphrase = "036363823"
+
+ # Dynamic queries for the PSK. If TLS-PSK is used,
+ # and psk_query is set, then you MUST NOT use
+ # psk_identity or psk_hexphrase.
+ #
+ # Instead, use a dynamic expansion similar to the one
+ # below. It keys off of TLS-PSK-Identity. It should
+ # return a of string no more than 512 hex characters.
+ # That string will be converted to binary, and will
+ # be used as the dynamic PSK hexphrase.
+ #
+ # Note that this query is just an example. You will
+ # need to customize it for your installation.
+ #
+ # psk_query = "%{sql:select hex(key) from psk_keys where keyid = '%{TLS-PSK-Identity}'}"
+
+ # For DH cipher suites to work in OpenSSL < 1.1.0,
+ # you have to run OpenSSL to create the DH file
+ # first:
+ #
+ # openssl dhparam -out certs/dh 2048
+ #
+ # For OpenSSL >= 1.1.0, just leave this commented
+ # out, and OpenSSL will do the right thing.
+ #
+ # dh_file = ${certdir}/dh
+
+ # If your system doesn't have /dev/urandom,
+ # you will need to create this file, and
+ # periodically change its contents.
+ #
+ # For security reasons, FreeRADIUS doesn't
+ # write to files in its configuration
+ # directory.
+ #
+ # random_file = /dev/urandom
+
+ # This can never exceed the size of a RADIUS
+ # packet (4096 bytes), and is preferably half
+ # that, to accommodate other attributes in
+ # RADIUS packet. On most APs the MAX packet
+ # length is configured between 1500 - 1600
+ # In these cases, fragment size should be
+ # 1024 or less.
+ #
+ # fragment_size = 1024
+
+ # include_length is a flag which is
+ # by default set to yes If set to
+ # yes, Total Length of the message is
+ # included in EVERY packet we send.
+ # If set to no, Total Length of the
+ # message is included ONLY in the
+ # First packet of a fragment series.
+ #
+ # include_length = yes
+
+
+ # Check the Certificate Revocation List
+ #
+ # 1) Copy CA certificates and CRLs to same directory.
+ # 2) Execute 'c_rehash <CA certs&CRLs Directory>'.
+ # 'c_rehash' is OpenSSL's command.
+ # 3) uncomment the lines below.
+ # 5) Restart radiusd
+ # check_crl = yes
+
+ # Check if intermediate CAs have been revoked.
+ # check_all_crl = yes
+
+ # Accept an expired Certificate Revocation List
+ #
+ # allow_expired_crl = no
+
+ # If check_cert_issuer is set, the value will
+ # be checked against the DN of the issuer in
+ # the client certificate. If the values do not
+ # match, the certificate verification will fail,
+ # rejecting the user.
+ #
+ # This check can be done more generally by checking
+ # the value of the TLS-Client-Cert-Issuer attribute.
+ # This check can be done via any mechanism you
+ # choose.
+ #
+ # check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd"
+
+ # If check_cert_cn is set, the value will
+ # be xlat'ed and checked against the CN
+ # in the client certificate. If the values
+ # do not match, the certificate verification
+ # will fail rejecting the user.
+ #
+ # This check is done only if the previous
+ # "check_cert_issuer" is not set, or if
+ # the check succeeds.
+ #
+ # This check can be done more generally by writing
+ # "unlang" statements to examine the value of the
+ # TLS-Client-Cert-Common-Name attribute.
+ #
+ # check_cert_cn = %{User-Name}
+
+ #
+ # This configuration item only applies when there is
+ # an intermediate CA between the "root" CA, and the
+ # client certificate. If we trust the root CA, then
+ # by definition we also trust ANY intermediate CA
+ # which is signed by that root. This means ANOTHER
+ # intermediate CA can issue client certificates, and
+ # have them accepted by the EAP module.
+ #
+ # The solution is to list ONLY the trusted CAs in the
+ # FreeRADIUS configuration, and then set this
+ # configuration item to "yes".
+ #
+ # Then, when the server receives a client certificate
+ # from an untrusted CA, that authentication request
+ # can be rejected.
+ #
+ # It is possible to do these checks in "unlang", by
+ # checking for unknown names in the
+ # TLS-Cert-Common-Name attribute, but that is
+ # more complex. So we add a configuration option
+ # which can be set once, and which works for all
+ # possible intermediate CAs, no matter what their
+ # value.
+ #
+ # reject_unknown_intermediate_ca = no
+
+ # Set this option to specify the allowed
+ # TLS cipher suites. The format is listed
+ # in "man 1 ciphers".
+ #
+ cipher_list = "DEFAULT"
+
+ # Set this option to specify the allowed
+ # TLS signature algorithms for OpenSSL 1.1.1 and above.
+ # The format and available signature algorithms are listed
+ # in "man 3 SSL_CTX_set1_sigalgs_list".
+ #
+ # sigalgs_list = ""
+
+ # 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. Setting this to "yes" means that OpenSSL
+ # will choose the servers ciphers, even if they do not
+ # best match what the client sends.
+ #
+ # TLS negotiation is usually good, but can be imperfect.
+ # This setting allows administrators to "fine tune" it
+ # if necessary.
+ #
+ cipher_server_preference = no
+
+ # You can selectively disable TLS versions for
+ # compatability with old client devices.
+ #
+ # If your system has OpenSSL 1.1.0 or greater, do NOT
+ # use these. Instead, set tls_min_version and
+ # tls_max_version.
+ #
+# disable_tlsv1_2 = yes
+# disable_tlsv1_1 = yes
+# disable_tlsv1 = yes
+
+
+ # Set min / max TLS version.
+ #
+ # Generally speaking you should NOT use TLS 1.0 or
+ # TLS 1.1. They are old, possibly insecure, and
+ # deprecated. However, it is sometimes necessary to
+ # enable it for compatibility with legact systems.
+ # We recommend replacing those legacy systems, and
+ # using at least TLS 1.2.
+ #
+ # Some Debian versions disable older versions of TLS,
+ # and requires the application to manually enable
+ # them.
+ #
+ # If you are running such a distribution, you should
+ # set these options, otherwise older clients will not
+ # be able to connect.
+ #
+ # Allowed values are "1.0", "1.1", "1.2", and "1.3".
+ #
+ # As of 2021, it is STRONGLY RECOMMENDED to set
+ #
+ # tls_min_version = "1.2"
+ #
+ # Older TLS versions are insecure and deprecated.
+ #
+ # In order to enable TLS 1.0 and TLS 1.1, you may
+ # also need to update cipher_list below to:
+ #
+ # * OpenSSL >= 3.x
+ #
+ # cipher_list = "DEFAULT@SECLEVEL=0"
+ #
+ # * OpenSSL < 3.x
+ #
+ # cipher_list = "DEFAULT@SECLEVEL=1"
+ #
+ # The values must be in quotes.
+ #
+ # We also STRONGLY RECOMMEND to set
+ #
+ # tls_max_version = "1.2"
+ #
+ # While the server will accept "1.3" as a value,
+ # most EAP supplicants WILL NOT DO TLS 1.3 PROPERLY.
+ #
+ # i.e. they WILL NOT WORK, SO DO NOT ASK QUESTIONS ON
+ # THE LIST ABOUT WHY IT DOES NOT WORK.
+ #
+ # The TLS 1.3 support is here for future
+ # compatibility, as clients get upgraded, and people
+ # don't upgrade their copies of FreeRADIUS.
+ #
+ # Also note that we only support TLS 1.3 for EAP-TLS,
+ # TTLS, and PEAP. It is not supported for EAP-FAST.
+ #
+ tls_min_version = "1.2"
+ tls_max_version = "1.2"
+
+ # Elliptical cryptography configuration
+ #
+ # This configuration should be one of the following:
+ #
+ # * a name of the curve to use, e.g. "prime256v1".
+ #
+ # * a colon separated list of curve NIDs or names.
+ #
+ # * an empty string, in which case OpenSSL will choose
+ # the "best" curve for the situation.
+ #
+ # For supported curve names, please run
+ #
+ # openssl ecparam -list_curves
+ #
+ ecdh_curve = ""
+
+ # Session resumption / fast reauthentication
+ # cache.
+ #
+ # The cache contains the following information:
+ #
+ # session Id - unique identifier, managed by SSL
+ # User-Name - from the Access-Accept
+ # Stripped-User-Name - from the Access-Request
+ # Cached-Session-Policy - from the Access-Accept
+ #
+ # See also the "store" subsection below for
+ # additional attributes which can be cached.
+ #
+ # The "Cached-Session-Policy" is the name of a
+ # policy which should be applied to the cached
+ # session. This policy can be used to assign
+ # VLANs, IP addresses, etc. It serves as a useful
+ # way to re-apply the policy from the original
+ # Access-Accept to the subsequent Access-Accept
+ # for the cached session.
+ #
+ # On session resumption, these attributes are
+ # copied from the cache, and placed into the
+ # reply list.
+ #
+ # You probably also want "use_tunneled_reply = yes"
+ # when using fast session resumption.
+ #
+ # You can check if a session has been resumed by
+ # looking for the existence of the EAP-Session-Resumed
+ # attribute. Note that this attribute will *only*
+ # exist in the "post-auth" section.
+ #
+ # CAVEATS: The cache is stored and reloaded BEFORE
+ # the "post-auth" section is run. This limitation
+ # makes caching more difficult than it should be. In
+ # practice, it means that the first authentication
+ # session must set the reply attributes before the
+ # post-auth section is run.
+ #
+ # When the session is resumed, the attributes are
+ # restored and placed into the session-state list.
+ #
+ cache {
+ # Enable it. The default is "no". Deleting the entire "cache"
+ # subsection also disables caching.
+ #
+ # The session cache requires the use of the
+ # "name" and "persist_dir" configuration
+ # items, below.
+ #
+ # The internal OpenSSL session cache has been permanently
+ # disabled.
+ #
+ # You can disallow resumption for a particular user by adding the
+ # following attribute to the control item list:
+ #
+ # Allow-Session-Resumption = No
+ #
+ # If "enable = no" below, you CANNOT enable resumption for just one
+ # user by setting the above attribute to "yes".
+ #
+ enable = no
+
+ # Lifetime of the cached entries, in hours. The sessions will be
+ # deleted/invalidated after this time.
+ #
+ lifetime = 24 # hours
+
+ # Internal "name" of the session cache. Used to
+ # distinguish which TLS context sessions belong to.
+ #
+ # The server will generate a random value if unset.
+ # This will change across server restart so you MUST
+ # set the "name" if you want to persist sessions (see
+ # below).
+ #
+ # name = "EAP module"
+
+ # Simple directory-based storage of sessions.
+ # Two files per session will be written, the SSL
+ # state and the cached VPs. This will persist session
+ # across server restarts.
+ #
+ # The default directory is ${logdir}, for historical
+ # reasons. You should ${db_dir} instead. And check
+ # the value of db_dir in the main radiusd.conf file.
+ # It should not point to ${raddb}
+ #
+ # The server will need write perms, and the directory
+ # should be secured from anyone else. You might want
+ # a script to remove old files from here periodically:
+ #
+ # find ${logdir}/tlscache -mtime +2 -exec rm -f {} \;
+ #
+ # This feature REQUIRES "name" option be set above.
+ #
+ # persist_dir = "${logdir}/tlscache"
+
+ #
+ # It is possible to partially
+ # control which attributes exist in the
+ # session cache. This subsection lists
+ # attributes which are taken from the reply,
+ # and saved to the on-disk cache. When the
+ # session is resumed, these attributes are
+ # added to the "session-state" list. The
+ # default configuration will then take care
+ # of copying them to the reply.
+ #
+ store {
+ Tunnel-Private-Group-Id
+ }
+ }
+
+ # Client certificates can be validated via an
+ # external command. This allows dynamic CRLs or OCSP
+ # to be used.
+ #
+ # This configuration is commented out in the
+ # default configuration. Uncomment it, and configure
+ # the correct paths below to enable it.
+ #
+ # If OCSP checking is enabled, and the OCSP checks fail,
+ # the verify section is not run.
+ #
+ # If OCSP checking is disabled, the verify section is
+ # run on successful certificate validation.
+ #
+ verify {
+ # If the OCSP checks succeed, the verify section
+ # is run to allow additional checks.
+ #
+ # If you want to skip verify on OCSP success,
+ # uncomment this configuration item, and set it
+ # to "yes".
+ #
+ # skip_if_ocsp_ok = no
+
+ # A temporary directory where the client
+ # certificates are stored. This directory
+ # MUST be owned by the UID of the server,
+ # and MUST not be accessible by any other
+ # users. When the server starts, it will do
+ # "chmod go-rwx" on the directory, for
+ # security reasons. The directory MUST
+ # exist when the server starts.
+ #
+ # You should also delete all of the files
+ # in the directory when the server starts.
+ #
+ # tmpdir = /tmp/radiusd
+
+ # The command used to verify the client cert.
+ # We recommend using the OpenSSL command-line
+ # tool.
+ #
+ # The ${..ca_path} text is a reference to
+ # the ca_path variable defined above.
+ #
+ # The %{TLS-Client-Cert-Filename} is the name
+ # of the temporary file containing the cert
+ # in PEM format. This file is automatically
+ # deleted by the server when the command
+ # returns.
+ #
+ # client = "/path/to/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}"
+ }
+
+ # OCSP Configuration
+ #
+ # Certificates can be verified against an OCSP
+ # Responder. This makes it possible to immediately
+ # revoke certificates without the distribution of
+ # new Certificate Revocation Lists (CRLs).
+ #
+ ocsp {
+ # Enable it. The default is "no".
+ # Deleting the entire "ocsp" subsection
+ # also disables ocsp checking
+ #
+ enable = no
+
+ # The OCSP Responder URL can be automatically
+ # extracted from the certificate in question.
+ # To override the OCSP Responder URL set
+ # "override_cert_url = yes".
+ #
+ override_cert_url = yes
+
+ # If the OCSP Responder address is not extracted from
+ # the certificate, the URL can be defined here.
+ #
+ url = "http://127.0.0.1/ocsp/"
+
+ # If the OCSP Responder can not cope with nonce
+ # in the request, then it can be disabled here.
+ #
+ # For security reasons, disabling this option
+ # is not recommended as nonce protects against
+ # replay attacks.
+ #
+ # Note that Microsoft AD Certificate Services OCSP
+ # Responder does not enable nonce by default. It is
+ # more secure to enable nonce on the responder than
+ # to disable it in the query here.
+ # See http://technet.microsoft.com/en-us/library/cc770413%28WS.10%29.aspx
+ #
+ # use_nonce = yes
+
+ # Number of seconds before giving up waiting
+ # for OCSP response. 0 uses system default.
+ #
+ # timeout = 0
+
+ # Normally an error in querying the OCSP
+ # responder (no response from server, server did
+ # not understand the request, etc) will result in
+ # a validation failure.
+ #
+ # To treat these errors as 'soft' failures and
+ # still accept the certificate, enable this
+ # option.
+ #
+ # Warning: this may enable clients with revoked
+ # certificates to connect if the OCSP responder
+ # is not available. Use with caution.
+ #
+ # softfail = no
+ }
+
+ #
+ # The server can present different certificates based
+ # on the realm presented in EAP. See
+ # raddb/certs/realms/README.md for examples of how to
+ # configure this.
+ #
+ # Note that the default is to use the same set of
+ # realm certificates for both EAP and RadSec! If
+ # this is not what you want, you should use different
+ # subdirectories or each, e.g. ${certdir}/realms/radsec/,
+ # and ${certdir}/realms/eap/
+ #
+ # realm_dir = ${certdir}/realms/
+ }
+
+
+ # EAP-TLS
+ #
+ # The TLS configuration for TLS-based EAP types is held in
+ # the "tls-config" section, above.
+ #
+ tls {
+ # Point to the common TLS configuration
+ #
+ tls = tls-common
+
+ # As part of checking a client certificate, the EAP-TLS
+ # sets some attributes such as TLS-Client-Cert-Common-Name. This
+ # virtual server has access to these attributes, and can
+ # be used to accept or reject the request.
+ #
+ # virtual_server = check-eap-tls
+
+ # You can control whether or not EAP-TLS requires a
+ # client certificate by setting
+ #
+ # configurable_client_cert = yes
+ #
+ # Once that setting has been changed, you can then set
+ #
+ # EAP-TLS-Require-Client-Cert = No
+ #
+ # in the control items for a request, and the EAP-TLS
+ # module will not require a client certificate from
+ # the supplicant.
+ #
+ # WARNING: This configuration should only be used
+ # when the users are placed into a "captive portal"
+ # or "walled garden", where they have limited network
+ # access. Otherwise the configuraton will allow
+ # anyone on the network, without authenticating them!
+ #
+# configurable_client_cert = no
+ }
+
+
+ # EAP-TTLS -- Tunneled TLS
+ #
+ # The TTLS module implements the EAP-TTLS protocol,
+ # which can be described as EAP inside of Diameter,
+ # inside of TLS, inside of EAP, inside of RADIUS...
+ #
+ # Surprisingly, it works quite well.
+ #
+ ttls {
+ # Which tls-config section the TLS negotiation parameters
+ # are in - see EAP-TLS above for an explanation.
+ #
+ # In the case that an old configuration from FreeRADIUS
+ # v2.x is being used, all the options of the tls-config
+ # section may also appear instead in the 'tls' section
+ # above. If that is done, the tls= option here (and in
+ # tls above) MUST be commented out.
+ #
+ tls = tls-common
+
+ # The tunneled EAP session needs a default EAP type
+ # which is separate from the one for the non-tunneled
+ # EAP module. Inside of the TTLS tunnel, we recommend
+ # using EAP-MD5. If the request does not contain an
+ # EAP conversation, then this configuration entry is
+ # ignored.
+ #
+ default_eap_type = md5
+
+ # The tunneled authentication request does not usually
+ # contain useful attributes like 'Calling-Station-Id',
+ # etc. These attributes are outside of the tunnel,
+ # and normally unavailable to the tunneled
+ # authentication request.
+ #
+ # By setting this configuration entry to 'yes',
+ # any attribute which is NOT in the tunneled
+ # authentication request, but which IS available
+ # outside of the tunnel, is copied to the tunneled
+ # request.
+ #
+ # allowed values: {no, yes}
+ #
+ copy_request_to_tunnel = no
+
+ # This configuration item is deprecated. Instead,
+ # you should use:
+ #
+ # update outer.session-state {
+ # ...
+ # }
+ #
+ # This will cache attributes for the final Access-Accept.
+ #
+ # See "update outer.session-state" in the "post-auth"
+ # sections of sites-available/default, and of
+ # sites-available/inner-tunnel
+ #
+ # The reply attributes sent to the NAS are usually
+ # based on the name of the user 'outside' of the
+ # tunnel (usually 'anonymous'). If you want to send
+ # the reply attributes based on the user name inside
+ # of the tunnel, then set this configuration entry to
+ # 'yes', and the reply to the NAS will be taken from
+ # the reply to the tunneled request.
+ #
+ # allowed values: {no, yes}
+ #
+ use_tunneled_reply = no
+
+ # The inner tunneled request can be sent
+ # through a virtual server constructed
+ # specifically for this purpose.
+ #
+ # A virtual server MUST be specified.
+ #
+ virtual_server = "inner-tunnel"
+
+ # This has the same meaning, and overwrites, the
+ # same field in the "tls" configuration, above.
+ # The default value here is "yes".
+ #
+ # include_length = yes
+
+ # Unlike EAP-TLS, EAP-TTLS does not require a client
+ # certificate. However, you can require one by setting the
+ # following option. You can also override this option by
+ # setting
+ #
+ # EAP-TLS-Require-Client-Cert = Yes
+ #
+ # in the control items for a request.
+ #
+ # Note that the majority of supplicants do not support using a
+ # client certificate with EAP-TTLS, so this option is unlikely
+ # to be usable for most people.
+ #
+ # require_client_cert = yes
+ }
+
+
+ # EAP-PEAP
+ #
+
+ ##################################################
+ #
+ # !!!!! WARNINGS for Windows compatibility !!!!!
+ #
+ ##################################################
+ #
+ # If you see the server send an Access-Challenge,
+ # and the client never sends another Access-Request,
+ # then
+ #
+ # STOP!
+ #
+ # The server certificate has to have special OID's
+ # in it, or else the Microsoft clients will silently
+ # fail. See the "scripts/xpextensions" file for
+ # details, and the following page:
+ #
+ # https://support.microsoft.com/en-us/help/814394/
+ #
+ # If is still doesn't work, and you're using Samba,
+ # you may be encountering a Samba bug. See:
+ #
+ # https://bugzilla.samba.org/show_bug.cgi?id=6563
+ #
+ # Note that we do not necessarily agree with their
+ # explanation... but the fix does appear to work.
+ #
+ ##################################################
+
+ # The tunneled EAP session needs a default EAP type
+ # which is separate from the one for the non-tunneled
+ # EAP module. Inside of the TLS/PEAP tunnel, we
+ # recommend using EAP-MS-CHAPv2.
+ #
+ peap {
+ # Which tls-config section the TLS negotiation parameters
+ # are in - see EAP-TLS above for an explanation.
+ #
+ # In the case that an old configuration from FreeRADIUS
+ # v2.x is being used, all the options of the tls-config
+ # section may also appear instead in the 'tls' section
+ # above. If that is done, the tls= option here (and in
+ # tls above) MUST be commented out.
+ #
+ tls = tls-common
+
+ # The tunneled EAP session needs a default
+ # EAP type which is separate from the one for
+ # the non-tunneled EAP module. Inside of the
+ # PEAP tunnel, we recommend using MS-CHAPv2,
+ # as that is the default type supported by
+ # Windows clients.
+ #
+ default_eap_type = mschapv2
+
+ # The PEAP module also has these configuration
+ # items, which are the same as for TTLS.
+ #
+ copy_request_to_tunnel = no
+
+ # This configuration item is deprecated. Instead,
+ # you should use:
+ #
+ # update outer.session-state {
+ # ...
+ # }
+ #
+ # This will cache attributes for the final Access-Accept.
+ #
+ # See "update outer.session-state" in the "post-auth"
+ # sections of sites-available/default, and of
+ # sites-available/inner-tunnel
+ #
+ use_tunneled_reply = no
+
+ # When the tunneled session is proxied, the
+ # home server may not understand EAP-MSCHAP-V2.
+ # Set this entry to "no" to proxy the tunneled
+ # EAP-MSCHAP-V2 as normal MSCHAPv2.
+ #
+ # This setting can be over-ridden on a packet by
+ # packet basis by setting
+ #
+ # &control:Proxy-Tunneled-Request-As-EAP = yes
+ #
+ # proxy_tunneled_request_as_eap = yes
+
+ # The inner tunneled request can be sent
+ # through a virtual server constructed
+ # specifically for this purpose.
+ #
+ # A virtual server MUST be specified.
+ #
+ virtual_server = "inner-tunnel"
+
+ # This option enables support for MS-SoH
+ # see doc/SoH.txt for more info.
+ # It is disabled by default.
+ #
+ # soh = yes
+
+ # The SoH reply will be turned into a request which
+ # can be sent to a specific virtual server:
+ #
+ # soh_virtual_server = "soh-server"
+
+ # Unlike EAP-TLS, PEAP does not require a client certificate.
+ # However, you can require one by setting the following
+ # option. You can also override this option by setting
+ #
+ # EAP-TLS-Require-Client-Cert = Yes
+ #
+ # in the control items for a request.
+ #
+ # Note that the majority of supplicants do not support using a
+ # client certificate with PEAP, so this option is unlikely to
+ # be usable for most people.
+ #
+ # require_client_cert = yes
+ }
+
+
+ # EAP-MSCHAPv2
+ #
+ # Note that it is the EAP MS-CHAPv2 sub-module, not
+ # the main 'mschap' module.
+ #
+ # Note also that in order for this sub-module to work,
+ # the main 'mschap' module MUST ALSO be configured.
+ #
+ # This module is the *Microsoft* implementation of MS-CHAPv2
+ # in EAP. There is another (incompatible) implementation
+ # of MS-CHAPv2 in EAP by Cisco, which FreeRADIUS does not
+ # currently support.
+ #
+ mschapv2 {
+ # In earlier versions of the server, this module
+ # never sent the MS-CHAP-Error message to the client.
+ # This worked, but it had issues when the cached
+ # password was wrong. The server *should* send
+ # "E=691 R=0" to the client, which tells it to prompt
+ # the user for a new password.
+ #
+ # The default is to use that functionality. which is
+ # known to work. If you set "send_error = yes", then
+ # the error message will be sent back to the client.
+ # This *may* help some clients work better, but *may*
+ # also cause other clients to stop working.
+ #
+ # send_error = no
+
+ # Server identifier to send back in the challenge.
+ # This should generally be the host name of the
+ # RADIUS server. Or, some information to uniquely
+ # identify it.
+ #
+ # identity = "FreeRADIUS"
+ }
+
+
+ # EAP-FAST
+ #
+ # The FAST module implements the EAP-FAST protocol
+ #
+ #fast {
+ # Point to the common TLS configuration
+ #
+ # tls = tls-common
+
+ # If 'cipher_list' is set here, it will over-ride the
+ # 'cipher_list' configuration from the 'tls-common'
+ # configuration. The EAP-FAST module has it's own
+ # over-ride for 'cipher_list' because the
+ # specifications mandata a different set of ciphers
+ # than are used by the other EAP methods.
+ #
+ # cipher_list though must include "ADH" for anonymous provisioning.
+ # This is not as straight forward as appending "ADH" alongside
+ # "DEFAULT" as "DEFAULT" contains "!aNULL" so instead it is
+ # recommended "ALL:!EXPORT:!eNULL:!SSLv2" is used
+ #
+ # cipher_list = "ALL:!EXPORT:!eNULL:!SSLv2"
+
+ # PAC lifetime in seconds (default: seven days)
+ #
+ # pac_lifetime = 604800
+
+ # Authority ID of the server
+ #
+ # If you are running a cluster of RADIUS servers, you should make
+ # the value chosen here (and for "pac_opaque_key") the same on all
+ # your RADIUS servers. This value should be unique to your
+ # installation. We suggest using a domain name.
+ #
+ # authority_identity = "1234"
+
+ # PAC Opaque encryption key (must be exactly 32 bytes in size)
+ #
+ # This value MUST be secret, and MUST be generated using
+ # a secure method, such as via 'openssl rand -hex 32'
+ #
+ # pac_opaque_key = "0123456789abcdef0123456789ABCDEF"
+
+ # Same as for TTLS, PEAP, etc.
+ #
+ # virtual_server = inner-tunnel
+ #}
+}
diff --git a/raddb/mods-available/echo b/raddb/mods-available/echo
new file mode 100644
index 0000000..ad3e159
--- /dev/null
+++ b/raddb/mods-available/echo
@@ -0,0 +1,123 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# This is a more general example of the execute module.
+#
+# This one is called "echo".
+#
+# Attribute-Name = `%{echo:/path/to/program args}`
+#
+# If you wish to execute an external program in more than
+# one section (e.g. 'authorize', 'pre_proxy', etc), then it
+# is probably best to define a different instance of the
+# 'exec' module for every section.
+#
+# The return value of the program run determines the result
+# of the exec instance call as follows:
+# (See doc/configurable_failover for details)
+#
+# < 0 : fail the module failed
+# = 0 : ok the module succeeded
+# = 1 : reject the module rejected the user
+# = 2 : fail the module failed
+# = 3 : ok the module succeeded
+# = 4 : handled the module has done everything to handle the request
+# = 5 : invalid the user's configuration entry was invalid
+# = 6 : userlock the user was locked out
+# = 7 : notfound the user was not found
+# = 8 : noop the module did nothing
+# = 9 : updated the module updated information in the request
+# > 9 : fail the module failed
+#
+exec echo {
+ #
+ # Wait for the program to finish.
+ #
+ # If we do NOT wait, then the program is "fire and
+ # forget", and any output attributes from it are ignored.
+ #
+ # If we are looking for the program to output
+ # attributes, and want to add those attributes to the
+ # request, then we MUST wait for the program to
+ # finish, and therefore set 'wait=yes'
+ #
+ # allowed values: {no, yes}
+ wait = yes
+
+ #
+ # The name of the program to execute, and it's
+ # arguments. Dynamic translation is done on this
+ # field, so things like the following example will
+ # work.
+ #
+ program = "/bin/echo %{User-Name}"
+
+ #
+ # The attributes which are placed into the
+ # environment variables for the program.
+ #
+ # Allowed values are:
+ #
+ # request attributes from the request
+ # config attributes from the configuration items list
+ # reply attributes from the reply
+ # proxy-request attributes from the proxy request
+ # proxy-reply attributes from the proxy reply
+ #
+ # Note that some attributes may not exist at some
+ # stages. e.g. There may be no proxy-reply
+ # attributes if this module is used in the
+ # 'authorize' section.
+ #
+ input_pairs = request
+
+ #
+ # Where to place the output attributes (if any) from
+ # the executed program. The values allowed, and the
+ # restrictions as to availability, are the same as
+ # for the input_pairs.
+ #
+ output_pairs = reply
+
+ #
+ # When to execute the program. If the packet
+ # type does NOT match what's listed here, then
+ # the module does NOT execute the program.
+ #
+ # For a list of allowed packet types, see
+ # the 'dictionary' file, and look for VALUEs
+ # of the Packet-Type attribute.
+ #
+ # By default, the module executes on ANY packet.
+ # Un-comment out the following line to tell the
+ # module to execute only if an Access-Accept is
+ # being sent to the NAS.
+ #
+ #packet_type = Access-Accept
+
+ #
+ # Should we escape the environment variables?
+ #
+ # If this is set, all the RADIUS attributes
+ # are capitalised and dashes replaced with
+ # underscores. Also, RADIUS values are surrounded
+ # with double-quotes.
+ #
+ # That is to say: User-Name=BobUser => USER_NAME="BobUser"
+ shell_escape = yes
+
+ #
+ # How long should we wait for the program to finish?
+ #
+ # Default is 10 seconds, which should be plenty for nearly
+ # anything. Range is 1 to 30 seconds. You are strongly
+ # encouraged to NOT increase this value. Decreasing can
+ # be used to cause authentication to fail sooner when you
+ # know it's going to fail anyway due to the time taken,
+ # thereby saving resources.
+ #
+ #timeout = 10
+
+}
diff --git a/raddb/mods-available/etc_group b/raddb/mods-available/etc_group
new file mode 100644
index 0000000..114f24a
--- /dev/null
+++ b/raddb/mods-available/etc_group
@@ -0,0 +1,32 @@
+# -*- text -*-
+#
+# $Id$
+
+# "passwd" configuration, for the /etc/group file. Adds a Etc-Group-Name
+# attribute for every group that the user is member of.
+#
+# You will have to define the Etc-Group-Name in the 'dictionary' file
+# as a 'string' type.
+#
+# The module name "etc_group" should also be listed in the "authorize"
+# section. Make sure it's listed before any other part of the server
+# tries to use the Etc-Group-Name attribute.
+#
+# The Group and Group-Name attributes are automatically created by
+# the Unix module, and do checking against /etc/group automatically.
+# This means that you CANNOT use Group or Group-Name to do any other
+# kind of grouping in the server. You MUST define a new group
+# attribute.
+#
+# i.e. this module should NOT be used as-is, but should be edited to
+# point to a different group file.
+#
+passwd etc_group {
+ filename = /etc/group
+ format = "=Etc-Group-Name:::*,User-Name"
+ hash_size = 50
+ ignore_nislike = yes
+ allow_multiple_keys = yes
+ delimiter = ":"
+}
+
diff --git a/raddb/mods-available/exec b/raddb/mods-available/exec
new file mode 100644
index 0000000..bb1d437
--- /dev/null
+++ b/raddb/mods-available/exec
@@ -0,0 +1,29 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Execute external programs
+#
+# This module is useful only for 'xlat'. To use it,
+# put 'exec' into the 'instantiate' section. You can then
+# do dynamic translation of attributes like:
+#
+# Attribute-Name = `%{exec:/path/to/program args}`
+#
+# The value of the attribute will be replaced with the output
+# of the program which is executed. Due to RADIUS protocol
+# limitations, any output over 253 bytes will be ignored.
+#
+# The RADIUS attributes from the user request will be placed
+# into environment variables of the executed program, as
+# described in "man unlang" and in doc/configuration/variables.rst
+#
+# See also "echo" for more sample configuration.
+#
+exec {
+ wait = no
+ input_pairs = request
+ shell_escape = yes
+ timeout = 10
+}
diff --git a/raddb/mods-available/expiration b/raddb/mods-available/expiration
new file mode 100644
index 0000000..5d06454
--- /dev/null
+++ b/raddb/mods-available/expiration
@@ -0,0 +1,13 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# The expiration module. This handles the Expiration attribute
+# It should be included in the *end* of the authorize section
+# in order to handle user Expiration. It should also be included
+# in the instantiate section in order to register the Expiration
+# compare function
+#
+expiration {
+}
diff --git a/raddb/mods-available/expr b/raddb/mods-available/expr
new file mode 100644
index 0000000..ca0b3bf
--- /dev/null
+++ b/raddb/mods-available/expr
@@ -0,0 +1,148 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# This module performs mathematical calculations:
+#
+# Attribute-Name = "%{expr:2 + 3 + &NAS-Port}"
+#
+# It supports the following operators (in order of precedence)
+#
+# & binary AND
+# | binary OR
+# << left shift
+# >> right shift
+# + addition
+# - subtraction
+# * multiply
+# / divide
+# %% remainder
+# ^ exponentiation
+# (...) sub-expression
+#
+# Operator precedence follows the normal rules.
+# Division by zero means that the entire expression is invalid.
+#
+# It also allows unary negation: -1
+# And twos complement: ~1
+#
+# All calculations are done on signed 63-bit integers.
+# e.g. int64_t. This should be sufficient for all normal
+# purposes.
+#
+# Hex numbers are supported: 0xabcdef
+#
+# As with all string expansions, you can nest the expansions:
+#
+# %{expr: %{NAS-Port} + 1}
+# %{expr: %{sql:SELECT ... } + 1}
+#
+# Attribute references are supported for integer attributes.
+# e.g. &NAS-Port. The benefit of using attribute references
+# is that the expression is calculated directly on the
+# attribute. It skips the step of "print to string, and then
+# parse to number". This means it's a little faster.
+#
+# Otherwise, all numbers are decimal.
+#
+
+#
+# The module also registers a few paircompare functions, and
+# many string manipulation functions, including:
+#
+# rand get random number from 0 to n-1
+# "%{rand:10}" == "9"
+#
+# randstr get random string built from character classes:
+# c lowercase letters
+# C uppercase letters
+# n numbers
+# a alphanumeric
+# ! punctuation
+# . alphanumeric + punctuation
+# s alphanumeric + "./"
+# o characters suitable for OTP (easily confused removed)
+# h binary data as lowercase hex
+# H binary data as uppercase hex
+#
+# "%{randstr:CCCC!!cccnnn}" == "IPFL>{saf874"
+# "%{randstr:oooooooo}" == "rfVzyA4y"
+# "%{randstr:hhhh}" == "68d60de3"
+#
+# urlquote quote special characters in URI
+# "%{urlquote:http://example.org/}" == "http%3A%47%47example.org%47"
+#
+# urlunquote unquote URL special characters
+# "%{urlunquote:http%%3A%%47%%47example.org%%47}" == "http://example.org/"
+#
+# escape escape string similar to rlm_sql safe_characters
+# "%{escape:<img>foo.jpg</img>}" == "=60img=62foo.jpg=60/img=62"
+#
+# unescape reverse of escape
+# "%{unescape:=60img=62foo.jpg=60/img=62}" == "<img>foo.jpg</img>"
+#
+# tolower convert to lowercase
+# "%{tolower:Bar}" == "bar"
+#
+# toupper convert to uppercase
+# "%{toupper:Foo}" == "FOO"
+#
+# md5 get md5sum hash
+# "%{md5:foo}" == "acbd18db4cc2f85cedef654fccc4a4d8"
+#
+# sha1 get sha1 hash
+# "%{sha1:foo}" == "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
+#
+# sha256 get sha256 hash
+# "%{sha256:foo}" == "2c26b46b68ffc68ff99b453c1d30413413422d706..."
+#
+# sha512 get sha512 hash
+# "%{sha512:foo}" == "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae29838..."
+#
+# hmacmd5 generate HMAC-MD5 of string
+# "%{hmacmd5:foo bar}" == "31b6db9e5eb4addb42f1a6ca07367adc"
+#
+# hmacsha1 generate HMAC-SHA1 of string
+# "%{hmacsha1:foo bar}" == "85d155c55ed286a300bd1cf124de08d87e914f3a"
+#
+# crypt encrypt with a salt: %{crypt:salt:password}
+# "%{crypt:aa:foo}" == "aaKNIEDOaueR6"
+# "%{crypt:$1$abcdefgh:foo}" == "$1$abcdefgh$XxzGe9Muun7wTYbZO4sdr0"
+# "%{crypt:$5$%{randstr:aaaaaaaaaaaaaaaa}:foo}" == "$1$fu4P2fcAdo9gM..."
+#
+# pairs serialize attributes as comma-delimited string
+# "%{pairs:request:}" == "User-Name = 'foo', User-Password = 'bar', ..."
+#
+# base64 encode string as base64
+# "%{base64:foo}" == "Zm9v"
+#
+# base64tohex convert base64 to hex
+# "%{base64tohex:Zm9v}" == "666f6f"
+#
+# explode split an attribute into multiple new attributes based on a delimiter
+# "%{explode:&ref <delim>}"
+#
+# nexttime calculate number of seconds until next n hour(s), day(s), week(s), year(s)
+# if it were 16:18, %{nexttime:1h} would expand to 2520
+#
+# lasttime calculate number of seconds until last n hour(s), day(s), week(s), year(s)
+# if it were 16:18, %{lasttime:1h} would expand to 4680
+#
+# lpad left-pad a string
+# if User-Name is "foo": "%{lpad:&User-Name 6 x}" == "xxxfoo"
+#
+# rpad right-pad a string
+# if User-Name is "foo": "%{rpad:&User-Name 5 -}" == "foo--"
+#
+# concat concatenate a set of attributes, separated by a character.
+# "%{concat:foo[*] ;}"
+#
+
+expr {
+ #
+ # Characters that will not be encoded by the %{escape}
+ # xlat function.
+ #
+ safe_characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /äéöüàâæçèéêëîïôœùûüaÿÄÉÖÜßÀÂÆÇÈÉÊËÎÏÔŒÙÛÜŸ"
+}
diff --git a/raddb/mods-available/files b/raddb/mods-available/files
new file mode 100644
index 0000000..e3f3bf5
--- /dev/null
+++ b/raddb/mods-available/files
@@ -0,0 +1,30 @@
+# -*- text -*-
+#
+# $Id$
+
+# Livingston-style 'users' file
+#
+# See "man users" for more information.
+#
+files {
+ # Search for files in a subdirectory of mods-config which
+ # matches this instance of the files module.
+ moddir = ${modconfdir}/${.:instance}
+
+ # The default key attribute to use for matches. The content
+ # of this attribute is used to match the "name" of the
+ # entry.
+ #key = "%{%{Stripped-User-Name}:-%{User-Name}}"
+
+ # The old "users" style file is now located here.
+ filename = ${moddir}/authorize
+
+ # This is accepted for backwards compatibility
+ # It will be removed in a future release.
+# usersfile = ${moddir}/authorize
+
+ # These are accepted for backwards compatibility.
+ # They will be renamed in a future release.
+ acctusersfile = ${moddir}/accounting
+ preproxy_usersfile = ${moddir}/pre-proxy
+}
diff --git a/raddb/mods-available/idn b/raddb/mods-available/idn
new file mode 100644
index 0000000..5340540
--- /dev/null
+++ b/raddb/mods-available/idn
@@ -0,0 +1,28 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Internationalised domain names.
+#
+
+# The expansion string: %{idn: example.com} results in an ASCII
+# punycode version of the domain name. That version can then be used
+# for name comparisons. Using an i18n version of the name is NOT
+# RECOMMENDED, as that version is not canonical.
+#
+# i.e. the "same" domain name can be represented in many, many,
+# different ways. Only the idn version has *one* representation.
+#
+idn {
+ #
+ # Allow use of unassigned Unicode code points.
+ #
+ allow_unassigned = no
+
+ #
+ # Prohibit underscores and other invalid characters in domain
+ # names.
+ use_std3_ascii_rules = yes
+
+} \ No newline at end of file
diff --git a/raddb/mods-available/inner-eap b/raddb/mods-available/inner-eap
new file mode 100644
index 0000000..576eb77
--- /dev/null
+++ b/raddb/mods-available/inner-eap
@@ -0,0 +1,107 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Sample configuration for an EAP module that occurs *inside*
+# of a tunneled method. It is used to limit the EAP types that
+# can occur inside of the inner tunnel.
+#
+# See also raddb/sites-available/inner-tunnel
+#
+# See raddb/mods-available/eap for full documentation on the meaning of these
+# configuration entries.
+#
+eap inner-eap {
+ # This is the best choice for PEAP.
+ default_eap_type = mschapv2
+
+ timer_expire = 60
+
+ # This should be the same as the outer eap "max sessions"
+ max_sessions = 2048
+
+ # Supported EAP-types
+ md5 {
+ }
+
+ gtc {
+ # The default challenge, which many clients
+ # ignore..
+ #challenge = "Password: "
+
+ auth_type = PAP
+ }
+
+ mschapv2 {
+ # See eap for documentation
+# send_error = no
+ }
+
+ # No TTLS or PEAP configuration should be listed here.
+
+ ## EAP-TLS
+ #
+ # You SHOULD use different certificates than are used
+ # for the outer EAP configuration!
+ #
+ # You can create the "inner-server.pem" file by doing:
+ #
+ # cd raddb/certs
+ # vi inner-server.cnf
+ # make inner-server
+ #
+ # The certificate MUST be different from the "server.cnf"
+ # file.
+ #
+ # Support for PEAP/TLS and RFC 5176 TLS/TLS is experimental.
+ # It might work, or it might not.
+ #
+ tls {
+ private_key_password = whatever
+ private_key_file = ${certdir}/inner-server.pem
+
+ # If Private key & Certificate are located in
+ # the same file, then private_key_file &
+ # certificate_file must contain the same file
+ # name.
+ #
+ # If ca_file (below) is not used, then the
+ # certificate_file below MUST include not
+ # only the server certificate, but ALSO all
+ # of the CA certificates used to sign the
+ # server certificate.
+ certificate_file = ${certdir}/inner-server.pem
+
+ # You may want different CAs for inner and outer
+ # certificates. If so, edit this file.
+ ca_file = ${cadir}/ca.pem
+
+ cipher_list = "DEFAULT"
+
+ # You may want to set a very small fragment size.
+ # The TLS data here needs to go inside of the
+ # outer EAP-TLS protocol.
+ #
+ # Try values and see if they work...
+ # fragment_size = 1024
+
+ # Other needful things
+ dh_file = ${certdir}/dh
+ random_file = /dev/urandom
+
+ # CRL and OCSP things go here. See the main "eap"
+ # file for details.
+ # check_crl = yes
+ # ca_path = /path/to/directory/with/ca_certs/and/crls/
+
+ # Accept an expired Certificate Revocation List
+ #
+# allow_expired_crl = no
+
+ #
+ # The session resumption / fast re-authentication
+ # cache CANNOT be used for inner sessions.
+ #
+ }
+}
diff --git a/raddb/mods-available/ippool b/raddb/mods-available/ippool
new file mode 100644
index 0000000..1d3305b
--- /dev/null
+++ b/raddb/mods-available/ippool
@@ -0,0 +1,66 @@
+# -*- text -*-
+#
+# $Id$
+
+# Do server side ip pool management. Should be added in
+# post-auth and accounting sections.
+#
+# The module also requires the existence of the Pool-Name
+# attribute. That way the administrator can add the Pool-Name
+# attribute in the user profiles and use different pools for
+# different users. The Pool-Name attribute is a *check* item
+# not a reply item.
+#
+# The Pool-Name should be set to the ippool module instance
+# name or to DEFAULT to match any module.
+
+#
+# Example:
+# radiusd.conf: ippool students { [...] }
+# ippool teachers { [...] }
+# users file : DEFAULT Group == students, Pool-Name := "students"
+# DEFAULT Group == teachers, Pool-Name := "teachers"
+# DEFAULT Group == other, Pool-Name := "DEFAULT"
+#
+# Note: If you change the range parameters you must then erase the
+# db files.
+#
+ippool main_pool {
+ # The main db file used to allocate addresses.
+ filename = ${db_dir}/db.ippool
+
+ # The start and end ip addresses for this pool.
+ range_start = 192.0.2.1
+ range_stop = 192.0.2.254
+
+ # The network mask used for this pool.
+ netmask = 255.255.255.0
+
+ # The gdbm cache size for the db files. Should
+ # be equal to the number of ip's available in
+ # the ip pool
+ cache_size = 800
+
+ # Helper db index file used in multilink
+ ip_index = ${db_dir}/db.ipindex
+
+ # If set, the Framed-IP-Address already in the
+ # reply (if any) will be discarded, and replaced
+ # ith a Framed-IP-Address assigned here.
+ override = no
+
+ # Specifies the maximum time in seconds that an
+ # entry may be active. If set to zero, means
+ # "no timeout". The default value is 0
+ maximum_timeout = 0
+
+ # The key to use for the session database (which
+ # holds the allocated ip's) normally it should
+ # just be the nas ip/port (which is the default).
+ #
+ # If your NAS sends the same value of NAS-Port
+ # all requests, the key should be based on some
+ # other attribute that is in ALL requests, AND
+ # is unique to each machine needing an IP address.
+# key = "%{NAS-IP-Address} %{NAS-Port}"
+}
diff --git a/raddb/mods-available/json b/raddb/mods-available/json
new file mode 100644
index 0000000..02a62ae
--- /dev/null
+++ b/raddb/mods-available/json
@@ -0,0 +1,271 @@
+# -*- text -*-
+#
+#
+# $Id$
+
+#######################################################################
+#
+# = JSON Module
+#
+# The `json` module provides the `json_encode` XLAT, which may be
+# used to encode a given list of attributes into different
+# formats of JSON object.
+#
+
+#
+# ## Configuration Settings
+#
+json {
+
+ #
+ # The only options for the JSON module are to control the output
+ # format of the `json_encode` xlat.
+ #
+ encode {
+
+ #
+ # output_mode:: set the format of JSON documenta
+ # that should be created. This may be one of:
+ #
+ # - object
+ # - object_simple
+ # - array
+ # - array_of_names
+ # - array_of_values
+ #
+ # Examples of each format are given below.
+ #
+# output_mode = object
+
+ #
+ # ### Formatting options for attribute names
+ #
+ attribute {
+ #
+ # prefix:: Add a colon-delimited prefix to all
+ # attribute names in the output document. For example,
+ # with a prefix of "foo", `User-Name` will be output as
+ # `foo:User-Name`.
+ #
+# prefix =
+ }
+
+ #
+ # ### Formatting options for attribute values
+ #
+ value {
+
+ #
+ # single_value_as_array:: always put values in an array
+ #
+ # Output formats will by default put single values as a
+ # JSON object (string, integer, etc). More than one
+ # value will, depending on the output format, be added
+ # as an array.
+ #
+ # When this option is enabled, values will always be
+ # added as an array.
+ #
+# single_value_as_array = no
+
+ #
+ # enum_as_integer:: output the integer value of
+ # enumerated attributes
+ #
+ # Where an attribute has enum values, the textual
+ # representation of the value will normally be output.
+ # Enable this option to force the numeric value
+ # instead.
+ #
+# enum_as_integer = no
+
+ #
+ # always_string:: force all values to be strings
+ #
+ # Integer values are normally written to the JSON
+ # document as numbers (i.e. without quotes). Enable
+ # this option to force all values to be as quoted
+ # strings.
+ #
+# always_string = no
+ }
+
+ }
+
+}
+
+
+#
+# ## Expansions
+#
+# rlm_json provides the below xlat function.
+#
+# ### %{json_encode:...}
+#
+# Generates a JSON document from a given list of attribute templates. The
+# format of document generated can be controlled with the 'encode' section in
+# the module configuration. Attribute values will automatically be escaped so
+# they are JSON-safe.
+#
+# NOTE: The name of the xlat is based on the instance name of this module. If
+# the module was defined as `json jdoc {...}`, then the xlat name will be
+# `jdoc_encode`.
+#
+# The xlat should be passed a list of attributes to encode. Each attribute
+# (after template expansion) will be added to a list of attributes to include
+# in the JSON document. If any of the attributes given are preceeded with a `!`
+# then they are removed from the list. Once all attributes have been processed,
+# the JSON document will be created using this list.
+#
+# For example, the following will produce a JSON document with two attributes in
+# it, `User-Name` and `Calling-Station-Id`, from the RADIUS request:
+#
+# .Example
+#
+# ```
+# %{json_encode:&User-Name &Calling-Station-Id}
+# ```
+#
+# The following will include all attributes in the RADIUS request, except for
+# `User-Password`:
+#
+# .Example
+#
+# ```
+# %{json_encode:&request[*] !&User-Password}
+# ```
+#
+# In another (contrived) example, all the attributes in the RADIUS request will
+# be included in the document, _except_ any attributes in the RADIUS reply.
+# `&User-Name` will be included from the control list, too, if it exists:
+#
+# .Example
+#
+# ```
+# %{json_encode:&request[*] !&reply[*] &control.User-Name}
+# ```
+#
+# #### Output format modes
+#
+# There are a number of output modes, each generating a different format of
+# JSON document.
+#
+# NOTE: In the JSON document, "type" is the type of the _attribute_, which is
+# not necessarily the same as the type of the "value" in the document. See e.g.
+# `Login-Service` above, an enumerated value.
+#
+# The following examples assume the three attributes are being added to the
+# JSON document:
+#
+# ```
+# User-Name = bob
+# Filter-Id = ab
+# Filter-Id += cd
+# ```
+#
+# #### Object output mode examples
+#
+# These modes output a JSON object.
+#
+# .Output mode "object"
+#
+# [source,json]
+# ----
+# {
+# "User-Name": {
+# "type": "string",
+# "value": "bob"
+# },
+# "Filter-Id": {
+# "type": "string",
+# "value": ["ab","cd"]
+# }
+# }
+# ----
+#
+# .Output mode "object_simple"
+#
+# [source,json]
+# ----
+# {
+# "User-Name": "bob",
+# "Filter-Id": ["ab","cd"]
+# }
+# ----
+#
+# #### Array output mode examples
+#
+# The "array" mode is a list of objects, each containing an attribute. If the
+# "single_value_as_array" value option is set then each attribute will only
+# appear once in the array, and "value" will be a list of all the values from
+# the same attribute.
+#
+# .Output mode "array"
+#
+# [source,json]
+# ----
+# [
+# {
+# "name": "User-Name",
+# "type": "string",
+# "value": "bob"
+# },
+# {
+# "name": "Filter-Id",
+# "type": "string",
+# "value": "ab"
+# },
+# {
+# "name": "Filter-Id",
+# "type": "string",
+# "value": "cd"
+# }
+# ]
+# ----
+#
+# .Output mode "array" when "single_value_as_array" is also set
+#
+# [source,json]
+# ----
+# [
+# {
+# "name": "User-Name",
+# "type": "string",
+# "value": ["bob"]
+# },
+# {
+# "name": "Filter-Id",
+# "type": "string",
+# "value": ["ab","cd"]
+# }
+# ]
+# ----
+#
+# The following output modes either do not include the attribute names or
+# values. They are likely to be useful only when the attributes are
+# individually specified and _guaranteed to exist_. In this case the attribute
+# names in `array_of_names` will have corresponding indexes to the values in
+# `array_of_values`.
+#
+# .Output mode "array_of_names"
+#
+# [source,json]
+# ----
+# [
+# "User-Name",
+# "Filter-Id",
+# "Filter-Id"
+# ]
+# ----
+#
+# .Output mode "array_of_values"
+#
+# [source,json]
+# ----
+# [
+# "bob",
+# "ab",
+# "cd"
+# ]
+# ----
+#
diff --git a/raddb/mods-available/krb5 b/raddb/mods-available/krb5
new file mode 100644
index 0000000..c88b5fb
--- /dev/null
+++ b/raddb/mods-available/krb5
@@ -0,0 +1,82 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Kerberos. See doc/modules/rlm_krb5 for minimal docs.
+#
+krb5 {
+ #
+ # The keytab file MUST be owned by the UID/GID used by the server.
+ # The keytab file MUST be writable by the server.
+ # The keytab file MUST NOT be readable by other users on the system.
+ # The keytab file MUST exist before the server is started.
+ #
+ keytab = ${localstatedir}/lib/radiusd/keytab
+ service_principal = name_of_principle
+
+ # Pool of krb5 contexts, 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.
+ #
+ # The context pool is only used if the underlying libkrb5 reported
+ # that it was thread safe at compile time.
+ #
+ pool {
+ # 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
+ # KDC being available.
+ start = ${thread[pool].start_servers}
+
+ # Minimum number of connections to keep open
+ min = ${thread[pool].min_spare_servers}
+
+ # 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.
+ max = ${thread[pool].max_servers}
+
+ # 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.
+ spare = ${thread[pool].max_spare_servers}
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ uses = 0
+
+ # The lifetime (in seconds) of the connection
+ #
+ # NOTE: A setting of 0 means infinite (no limit).
+ lifetime = 0
+
+ # 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).
+ idle_timeout = 0
+
+ # 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.
+ }
+}
diff --git a/raddb/mods-available/ldap b/raddb/mods-available/ldap
new file mode 100644
index 0000000..997d41e
--- /dev/null
+++ b/raddb/mods-available/ldap
@@ -0,0 +1,712 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Lightweight Directory Access Protocol (LDAP)
+#
+ldap {
+ # Note that this needs to match the name(s) in the LDAP server
+ # certificate, if you're using ldaps. See OpenLDAP documentation
+ # for the behavioral semantics of specifying more than one host.
+ #
+ # Depending on the libldap in use, server may be an LDAP URI.
+ # In the case of OpenLDAP this allows additional the following
+ # additional schemes:
+ # - ldaps:// (LDAP over SSL)
+ # - ldapi:// (LDAP over Unix socket)
+ # - ldapc:// (Connectionless LDAP)
+ server = 'localhost'
+# server = 'ldap.rrdns.example.org'
+# server = 'ldap.rrdns.example.org'
+
+ # Port to connect on, defaults to 389, will be ignored for LDAP URIs.
+# port = 389
+
+ # Administrator account for searching and possibly modifying.
+ # If using SASL + KRB5 these should be commented out.
+# identity = 'cn=admin,dc=example,dc=org'
+# password = mypass
+
+ # Unless overridden in another section, the dn from which all
+ # searches will start from.
+ base_dn = 'dc=example,dc=org'
+
+ #
+ # You can run the 'ldapsearch' command line tool using the
+ # parameters from this module's configuration.
+ #
+ # ldapsearch -D ${identity} -w ${password} -h ${server} -b 'CN=user,${base_dn}'
+ #
+ # That will give you the LDAP information for 'user'.
+ #
+ # Group membership can be queried by using the above "ldapsearch" string,
+ # and adding "memberof" qualifiers. For ActiveDirectory, use:
+ #
+ # ldapsearch ... '(&(objectClass=user)(sAMAccountName=user)(memberof=CN=group,${base_dn}))'
+ #
+ # Where 'user' is the user as above, and 'group' is the group you are querying for.
+ #
+
+ #
+ # SASL parameters to use for admin binds
+ #
+ # When we're prompted by the SASL library, these control
+ # the responses given, as well as the identity and password
+ # directives above.
+ #
+ # If any directive is commented out, a NULL response will be
+ # provided to cyrus-sasl.
+ #
+ # Unfortunately the only way to control Keberos here is through
+ # environmental variables, as cyrus-sasl provides no API to
+ # set the krb5 config directly.
+ #
+ # Full documentation for MIT krb5 can be found here:
+ #
+ # http://web.mit.edu/kerberos/krb5-devel/doc/admin/env_variables.html
+ #
+ # At a minimum you probably want to set KRB5_CLIENT_KTNAME.
+ #
+ sasl {
+ # SASL mechanism
+# mech = 'PLAIN'
+
+ # SASL authorisation identity to proxy.
+# proxy = 'autz_id'
+
+ # SASL realm. Used for kerberos.
+# realm = 'example.org'
+ }
+
+ #
+ # Generic valuepair attribute
+ #
+
+ # If set, this will attribute will be retrieved in addition to any
+ # mapped attributes.
+ #
+ # Values should be in the format:
+ # <radius attr> <op> <value>
+ #
+ # Where:
+ # <radius attr>: Is the attribute you wish to create
+ # with any valid list and request qualifiers.
+ # <op>: Is any assignment operator (=, :=, +=).
+ # <value>: Is the value to parse into the new valuepair.
+ # If the value is wrapped in double quotes it
+ # will be xlat expanded.
+# valuepair_attribute = 'radiusAttribute'
+
+ #
+ # Mapping of LDAP directory attributes to RADIUS dictionary attributes.
+ #
+
+ # WARNING: Although this format is almost identical to the unlang
+ # update section format, it does *NOT* mean that you can use other
+ # unlang constructs in module configuration files.
+ #
+ # Configuration items are in the format:
+ # <radius attr> <op> <ldap attr>
+ #
+ # Where:
+ # <radius attr>: Is the destination RADIUS attribute
+ # with any valid list and request qualifiers.
+ # <op>: Is any assignment attribute (=, :=, +=, -=).
+ # <ldap attr>: Is the attribute associated with user or
+ # profile objects in the LDAP directory.
+ # If the attribute name is wrapped in double
+ # quotes it will be xlat expanded.
+ #
+ # Request and list qualifiers may also be placed after the 'update'
+ # section name to set defaults destination requests/lists
+ # for unqualified RADIUS attributes.
+ #
+ # Note: LDAP attribute names should be single quoted unless you want
+ # the name value to be derived from an xlat expansion, or an
+ # attribute ref.
+ update {
+ control:Password-With-Header += 'userPassword'
+# control:NT-Password := 'ntPassword'
+# reply:Reply-Message := 'radiusReplyMessage'
+# reply:Tunnel-Type := 'radiusTunnelType'
+# reply:Tunnel-Medium-Type := 'radiusTunnelMediumType'
+# reply:Tunnel-Private-Group-ID := 'radiusTunnelPrivategroupId'
+
+ # Where only a list is specified as the RADIUS attribute,
+ # the value of the LDAP attribute is parsed as a valuepair
+ # in the same format as the 'valuepair_attribute' (above).
+ control: += 'radiusControlAttribute'
+ request: += 'radiusRequestAttribute'
+ reply: += 'radiusReplyAttribute'
+ }
+
+ # Set to yes if you have eDirectory and want to use the universal
+ # password mechanism.
+# edir = no
+
+ # Set to yes if you want to bind as the user after retrieving the
+ # Cleartext-Password. This will consume the login grace, and
+ # verify user authorization.
+# edir_autz = no
+
+ # LDAP "bind as user" configuration to check PAP passwords.
+ #
+ # Active Directory needs "bind as user", which can be done by
+ # adding the following "if" statement to the authorize {} section
+ # of the virtual server, after the "ldap" module. For
+ # example:
+ #
+ # ...
+ # ldap
+ # if ((ok || updated) && User-Password && !control:Auth-Type) {
+ # update {
+ # control:Auth-Type := ldap
+ # }
+ # }
+ # ...
+ #
+ # You will also need to uncomment the "Auth-Type LDAP" block in the
+ # "authenticate" section.
+ #
+ # This configuration is required because AD will not return the users
+ # "known good" password to FreeRADIUS. Instead, FreeRADIUS has to run
+ # "Auth-Type LDAP" in order to do an LDAP "bind as user", which will hand
+ # the user name / password to AD for verification.
+ #
+
+ #
+ # Name of the attribute that contains the user DN.
+ # The default name is LDAP-UserDn.
+ #
+ # If you have multiple LDAP instances, you should
+ # change this configuration item to:
+ #
+ # ${.:instance}-LDAP-UserDn
+ #
+ # That change allows the modules to set their own
+ # User DN, and to not conflict with each other.
+ #
+ user_dn = "LDAP-UserDn"
+
+ #
+ # User object identification.
+ #
+ user {
+ # Where to start searching in the tree for users
+ base_dn = "${..base_dn}"
+
+ # Filter for user objects, should be specific enough
+ # to identify a single user object.
+ #
+ # For Active Directory, you should use
+ # "samaccountname=" instead of "uid="
+ #
+ filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
+
+ # For Active Directory nested group, you should comment out the previous 'filter = ...'
+ # and use the below. Where 'group' is the group you are querying for.
+ #
+ # NOTE: The string '1.2.840.113556.1.4.1941' specifies LDAP_MATCHING_RULE_IN_CHAIN.
+ # This applies only to DN attributes. This is an extended match operator that walks
+ # the chain of ancestry in objects all the way to the root until it finds a match.
+ # This reveals group nesting. It is available only on domain controllers with
+ # Windows Server 2003 SP2 or Windows Server 2008 (or above).
+ #
+ # See: https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx
+ #
+# filter = "(&(objectClass=user)(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}})(memberOf:1.2.840.113556.1.4.1941:=cn=group,${..base_dn}))"
+
+ # SASL parameters to use for user binds
+ #
+ # When we're prompted by the SASL library, these control
+ # the responses given.
+ #
+ # Any of the config items below may be an attribute ref
+ # or and expansion, so different SASL mechs, proxy IDs
+ # and realms may be used for different users.
+ sasl {
+ # SASL mechanism
+# mech = 'PLAIN'
+
+ # SASL authorisation identity to proxy.
+# proxy = &User-Name
+
+ # SASL realm. Used for kerberos.
+# realm = 'example.org'
+ }
+
+ # Search scope, may be 'base', 'one', sub' or 'children'
+# scope = 'sub'
+
+ # Server side result sorting
+ #
+ # A list of space delimited attributes to order the result
+ # set by, if the filter matches multiple objects.
+ # Only the first result in the set will be processed.
+ #
+ # 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
+ # the search will fail.
+# sort_by = '-uid'
+
+ # If this is undefined, anyone is authorised.
+ # If it is defined, the contents of this attribute
+ # determine whether or not the user is authorised
+# access_attribute = 'dialupAccess'
+
+ # Control whether the presence of 'access_attribute'
+ # allows access, or denys access.
+ #
+ # If 'yes', and the access_attribute is present, or
+ # 'no' and the access_attribute is absent then access
+ # will be allowed.
+ #
+ # If 'yes', and the access_attribute is absent, or
+ # 'no' and the access_attribute is present, then
+ # access will not be allowed.
+ #
+ # If the value of the access_attribute is 'false', it
+ # will negate the result.
+ #
+ # e.g.
+ # access_positive = yes
+ # access_attribute = userAccessAllowed
+ #
+ # With an LDAP object containing:
+ # userAccessAllowed: false
+ #
+ # Will result in the user being locked out.
+# access_positive = yes
+ }
+
+ #
+ # User membership checking.
+ #
+ group {
+ # Where to start searching in the tree for groups
+ base_dn = "${..base_dn}"
+
+ # Filter for group objects, should match all available
+ # group objects a user might be a member of.
+ #
+ # If using Active Directory you are likely to need "group"
+ # instead of "posixGroup".
+ filter = '(objectClass=posixGroup)'
+
+ # Search scope, may be 'base', 'one', sub' or 'children'
+# scope = 'sub'
+
+ # Attribute that uniquely identifies a group.
+ # Is used when converting group DNs to group
+ # names.
+# name_attribute = cn
+
+ # Filter to find all group objects a user is a member of.
+ # That is, group objects with attributes that
+ # identify members (the inverse of membership_attribute).
+ #
+ # Note that this configuration references the "user_dn"
+ # configuration defined above.
+ #
+# membership_filter = "(|(member=%{control:${..user_dn}})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
+
+ # The attribute, in user objects, which contain the names
+ # or DNs of groups a user is a member of.
+ #
+ # Unless a conversion between group name and group DN is
+ # needed, there's no requirement for the group objects
+ # referenced to actually exist.
+ #
+ # If the LDAP server does not support the "memberOf"
+ # attribute (or equivalent), then you will need to use the
+ # membership_filter option above instead. If you can't see
+ # the memberOf attribute then it is also possible that the
+ # LDAP bind user does not have the correct permissions to
+ # view it.
+ membership_attribute = 'memberOf'
+
+ # If cacheable_name or cacheable_dn are enabled,
+ # all group information for the user will be
+ # retrieved from the directory and written to LDAP-Group
+ # attributes appropriate for the instance of rlm_ldap.
+ #
+ # For group comparisons these attributes will be checked
+ # instead of querying the LDAP directory directly.
+ #
+ # This feature is intended to be used with rlm_cache.
+ #
+ # If you wish to use this feature, you should enable
+ # the type that matches the format of your check items
+ # i.e. if your groups are specified as DNs then enable
+ # cacheable_dn else enable cacheable_name.
+# cacheable_name = 'no'
+# cacheable_dn = 'no'
+
+ # Override the normal cache attribute (<inst>-LDAP-Group or
+ # LDAP-Group if using the default instance) and create a
+ # custom attribute. This can help if multiple module instances
+ # are used in fail-over.
+# cache_attribute = 'LDAP-Cached-Membership'
+
+ # If the group being checked is specified as a name, but
+ # the user's groups are referenced by DN, and one of those
+ # group DNs is invalid, the whole group check is treated as
+ # invalid, and a negative result will be returned.
+ # When set to 'yes', this option ignores invalid DN
+ # references.
+# allow_dangling_group_ref = 'no'
+ }
+
+ #
+ # User profiles. RADIUS profile objects contain sets of attributes
+ # to insert into the request. These attributes are mapped using
+ # the same mapping scheme applied to user objects (the update section above).
+ #
+ profile {
+ # Filter for RADIUS profile objects
+# filter = '(objectclass=radiusprofile)'
+
+ # The default profile. This may be a DN or an attribute
+ # reference.
+ # To get old v2.2.x style behaviour, or to use the
+ # &User-Profile attribute to specify the default profile,
+ # set this to &control:User-Profile.
+# default = 'cn=radprofile,dc=example,dc=org'
+
+ # The LDAP attribute containing profile DNs to apply
+ # in addition to the default profile above. These are
+ # retrieved from the user object, at the same time as the
+ # attributes from the update section, are are applied
+ # if authorization is successful.
+# attribute = 'radiusProfileDn'
+ }
+
+ #
+ # Bulk load clients from the directory
+ #
+ client {
+ # Where to start searching in the tree for clients
+ base_dn = "${..base_dn}"
+
+ #
+ # Filter to match client objects
+ #
+ filter = '(objectClass=radiusClient)'
+
+ # Search scope, may be 'base', 'one', 'sub' or 'children'
+# scope = 'sub'
+
+ #
+ # Sets default values (not obtained from LDAP) for new client entries
+ #
+ template {
+# login = 'test'
+# password = 'test'
+# proto = tcp
+# require_message_authenticator = yes
+
+ # Uncomment to add a home_server with the same
+ # attributes as the client.
+# coa_server {
+# response_window = 2.0
+# }
+ }
+
+ #
+ # Client attribute mappings are in the format:
+ # <client attribute> = <ldap attribute>
+ #
+ # The following attributes are required:
+ # * ipaddr | ipv4addr | ipv6addr - Client IP Address.
+ # * secret - RADIUS shared secret.
+ #
+ # All other attributes usually supported in a client
+ # definition are also supported here.
+ #
+ # Schemas are available in doc/schemas/ldap for openldap and eDirectory
+ #
+ attribute {
+ ipaddr = 'radiusClientIdentifier'
+ secret = 'radiusClientSecret'
+# shortname = 'radiusClientShortname'
+# nas_type = 'radiusClientType'
+# virtual_server = 'radiusClientVirtualServer'
+# require_message_authenticator = 'radiusClientRequireMa'
+ }
+ }
+
+ # Load clients on startup
+# read_clients = no
+
+ #
+ # Modify user object on receiving Accounting-Request
+ #
+
+ # Useful for recording things like the last time the user logged
+ # in, or the Acct-Session-ID for CoA/DM.
+ #
+ # LDAP modification items are in the format:
+ # <ldap attr> <op> <value>
+ #
+ # Where:
+ # <ldap attr>: The LDAP attribute to add modify or delete.
+ # <op>: One of the assignment operators:
+ # (:=, +=, -=, ++).
+ # Note: '=' is *not* supported.
+ # <value>: The value to add modify or delete.
+ #
+ # WARNING: If using the ':=' operator with a multi-valued LDAP
+ # attribute, all instances of the attribute will be removed and
+ # replaced with a single attribute.
+ accounting {
+ reference = "%{tolower:type.%{Acct-Status-Type}}"
+
+ type {
+ start {
+ update {
+ description := "Online at %S"
+ }
+ }
+
+ interim-update {
+ update {
+ description := "Last seen at %S"
+ }
+ }
+
+ stop {
+ update {
+ description := "Offline at %S"
+ }
+ }
+ }
+ }
+
+ #
+ # Post-Auth can modify LDAP objects too
+ #
+ post-auth {
+ update {
+ description := "Authenticated at %S"
+ }
+ }
+
+ #
+ # LDAP connection-specific options.
+ #
+ # These options set timeouts, keep-alives, etc. for the connections.
+ #
+ options {
+ # Control under which situations aliases are followed.
+ # May be one of 'never', 'searching', 'finding' or 'always'
+ # default: libldap's default which is usually 'never'.
+ #
+ # LDAP_OPT_DEREF is set to this value.
+# dereference = 'always'
+
+ #
+ # The following two configuration items control whether the
+ # server follows references returned by LDAP directory.
+ # They are mostly for Active Directory compatibility.
+ # If you set these to 'no', then searches will likely return
+ # 'operations error', instead of a useful result.
+ #
+ # 'rebind' causes any connections being established to follow
+ # referrals to be bound using the admin credentials defined
+ # for this module. If it is set to 'no' libldap will bind
+ # to those connections anonymously.
+ #
+ chase_referrals = yes
+ rebind = yes
+
+ # SASL Security Properties (see SASL_SECPROPS in ldap.conf man page).
+ # Note - uncomment when using GSS-API sasl mechanism along with TLS
+ # encryption against Active-Directory LDAP servers (this disables
+ # sealing and signing at the GSS level as required by AD).
+ #sasl_secprops = 'noanonymous,noplain,maxssf=0'
+
+ # Seconds to wait for LDAP query to finish. default: 20
+ res_timeout = 10
+
+ # Seconds LDAP server has to process the query (server-side
+ # time limit). default: 20
+ #
+ # LDAP_OPT_TIMELIMIT is set to this value.
+ srv_timelimit = 3
+
+ # Seconds to wait for response of the server. (network
+ # failures) default: 10
+ #
+ # LDAP_OPT_NETWORK_TIMEOUT is set to this value.
+ net_timeout = 1
+
+ # LDAP_OPT_X_KEEPALIVE_IDLE
+ idle = 60
+
+ # LDAP_OPT_X_KEEPALIVE_PROBES
+ probes = 3
+
+ # LDAP_OPT_X_KEEPALIVE_INTERVAL
+ interval = 3
+
+ # ldap_debug: debug flag for LDAP SDK
+ # (see OpenLDAP documentation). Set this to enable
+ # huge amounts of LDAP debugging on the screen.
+ # You should only use this if you are an LDAP expert.
+ #
+ # default: 0x0000 (no debugging messages)
+ # Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS)
+ ldap_debug = 0x0028
+ }
+
+ #
+ # This subsection configures the tls related items
+ # that control how FreeRADIUS connects to an LDAP
+ # server. It contains all of the 'tls_*' configuration
+ # entries used in older versions of FreeRADIUS. Those
+ # configuration entries can still be used, but we recommend
+ # using these.
+ #
+ # Note that some distributions use NSS for libldap instead
+ # of OpenSSL.
+ #
+ # If you see something like this in the debug output:
+ #
+ # TLSMC: MozNSS compatibility interception begins.
+ #
+ # Then there is a problem.
+ #
+ # THIS LDAP INSTALLATION WILL NOT WORK WITH FREERADIUS.
+ #
+ # You MUST install fixed LDAP libraries which use OpenSSL.
+ #
+ # For more details, see:
+ #
+ # http://packages.networkradius.com
+ #
+ tls {
+ # Set this to 'yes' to use TLS encrypted connections
+ # to the LDAP database by using the StartTLS extended
+ # operation.
+ #
+ # The StartTLS operation is supposed to be
+ # used with normal ldap connections instead of
+ # using ldaps (port 636) connections
+# start_tls = yes
+
+# ca_file = ${certdir}/cacert.pem
+
+# ca_path = ${certdir}
+# certificate_file = /path/to/radius.crt
+# private_key_file = /path/to/radius.key
+# random_file = /dev/urandom
+
+ # Certificate Verification requirements. Can be:
+ # 'never' (do not even bother trying)
+ # 'allow' (try, but don't fail if the certificate
+ # cannot be verified)
+ # 'demand' (fail if the certificate does not verify)
+ # 'hard' (similar to 'demand' but fails if TLS
+ # cannot negotiate)
+ #
+ # The default is libldap's default, which varies based
+ # on the contents of ldap.conf.
+
+# require_cert = 'demand'
+
+ #
+ # Check the CRL, as with the EAP module.
+ #
+ # The default is "no".
+ #
+# check_crl = yes
+
+ #
+ # Minimum TLS version to accept. We STRONGLY recommend
+ # setting this to "1.2"
+ #
+# tls_min_version = "1.2"
+
+ # Set this option to specify the allowed
+ # TLS cipher suites. The format is listed
+ # in "man 1 ciphers".
+ #
+ cipher_list = "DEFAULT"
+ }
+
+ # As of v3, the 'pool' section has replaced the
+ # following v2 configuration items:
+ #
+ # ldap_connections_number
+
+ #
+ # The connection pool is used to pool outgoing connections.
+ #
+ # When the server is not threaded, the connection pool
+ # limits are ignored, and only one connection is used.
+ pool {
+ # 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
+ # directory being available.
+ start = ${thread[pool].start_servers}
+
+ # Minimum number of connections to keep open
+ min = ${thread[pool].min_spare_servers}
+
+ # 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.
+ max = ${thread[pool].max_servers}
+
+ # 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.
+ spare = ${thread[pool].max_spare_servers}
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ uses = 0
+
+ # 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.
+ retry_delay = 30
+
+ # The lifetime (in seconds) of the connection
+ lifetime = 0
+
+ # Idle timeout (in seconds). A connection which is
+ # unused for this length of time will be closed.
+ idle_timeout = 60
+
+ # 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.
+
+ # Maximum number of times an operation can be retried
+ # if it returns an error which indicates the connection
+ # needs to be restarted. This includes timeouts.
+ max_retries = 5
+ }
+}
diff --git a/raddb/mods-available/ldap_google b/raddb/mods-available/ldap_google
new file mode 100644
index 0000000..03c98d3
--- /dev/null
+++ b/raddb/mods-available/ldap_google
@@ -0,0 +1,262 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# This file contains an instance of the ldap module which has been
+# configured for the G Suite / Google Workspace Secure LDAP server.
+# There are a few steps which still need to be taken, but they are
+# documented clearly below.
+#
+# In order to use the Google LDAP server, a client must first be
+# created. See Google's documentation for doing this:
+#
+# https://support.google.com/a/answer/9048434?hl=en&ref_topic=9173976
+#
+# Google LDAP requires that any system connecting to it use a client
+# certificate. However, FreeRADIUS also requires a username and
+# password in the "ldap" module configuration. Therere before
+# downloading the client certificate from Google, you should choose
+# the option to generate access credentials in order to obtain a
+# username and password. That username and password should be used
+# below.
+#
+# Ensure the Goolge client configuration which is used for FreeRADIUS
+# has sufficient permissions to read user information, and, if group
+# membership is part of the FreeRADIUS policy, ensure that the client
+# can read group information. This configuration is done on Google's
+# systems. Please see the Google documentation for more information.
+#
+# NOTE: The Google LDAP database does NOT return user passwords in
+# the search results!
+#
+# Therefore, if Google LDAP is being used for authentication, it will
+# ONLY work when using "LDAP bind as user". The authentication
+# method used there MUST also provide the user password in plain
+# text. This limits the use of Google LDAP to PAP, and TTLS+PAP.
+# Anything else simply will not work, and nothing you do will ever
+# make it work.
+#
+# The Google LDAP service has been observed to have poor
+# performance compared to a dedicated / local LDAP server like
+# OpenLDAP. In order to improve performance, we simply bypass it
+# completely by caching things associated with accept and reject.
+# See mods-available/cache_auth for the cache configuration, and
+# sites-available/google-ldap-auth for a sample virtual server which
+# uses this module, and the cache.
+#
+# In addition, if you are using Google LDAP service as part of WiFi
+# authentication (remember, only TTLS+PAP will work!), then we also
+# recommend enabling the "cache" configuration in mods-available/eap.
+# That cache is a separate one from mods-available/cache_auth, and
+# both caches can be used at the same time.
+#
+#
+# The comments in this file are specific to using the Google Secure
+# LDAP service. For more general LDAP module configuration, see the
+# mods-available/ldap.
+#
+ldap ldap_google {
+ # The standard Google LDAP server URL
+ server = 'ldaps://ldap.google.com:636/'
+
+ # Google LDAP client username and password as generated during
+ # client creation.
+# identity = 'myuser'
+# password = 'mypass'
+
+ # Base dn for your organisation.
+ base_dn = 'dc=example,dc=org'
+
+ #
+ # The default Google LDAP schema can be seen here
+ #
+ # https://support.google.com/a/answer/9188164
+ #
+ # Custom attributes can be added to user profiles, and those
+ # custom attributes can then be accessed in the LDAP
+ # directory:
+ #
+ # https://support.google.com/a/answer/6208725
+ #
+ # You can run the 'ldapsearch' command line tool using the
+ # parameters from this module's configuration.
+ #
+ # LDAPTLS_REQCERT=ALLOW \
+ # LDAPTLS_CERT="<Google certificate file>" \
+ # LDAPTLS_KEY="<Google key file>" \
+ # ldapsearch -H ${server} -b '${base_dn}' '(uid=user)'
+ #
+ # That command will return the LDAP information for 'user'.
+ #
+ # Group membership can be queried by using the above "ldapsearch" string,
+ # and adding "memberof" qualifiers.
+ #
+
+# valuepair_attribute = 'radiusAttribute'
+
+ update {
+# reply:Reply-Message := 'radiusReplyMessage'
+# reply:Tunnel-Type := 'radiusTunnelType'
+# reply:Tunnel-Medium-Type := 'radiusTunnelMediumType'
+# reply:Tunnel-Private-Group-ID := 'radiusTunnelPrivategroupId'
+
+ control: += 'radiusControlAttribute'
+ request: += 'radiusRequestAttribute'
+ reply: += 'radiusReplyAttribute'
+ }
+
+ #
+ # In order to use LDAP "bind as user" authentication, you
+ # should add following "if" statement to the authorize {}
+ # section of the virtual server, after the "ldap" module.
+ # For example:
+ #
+ # ...
+ # ldap_google
+ # if ((ok || updated) && User-Password && !control:Auth-Type) {
+ # update {
+ # &control:Auth-Type := ldap
+ # }
+ # }
+ # ...
+ #
+ # You will also need to uncomment the "Auth-Type LDAP" block in the
+ # "authenticate" section.
+ #
+ # Note that these configuration steps have already been done
+ # in the sample virtual server, in
+ # sites-available/google-ldap-auth.
+ #
+
+ #
+ # If you change this, you will also need to update the
+ # "cache_ldap_user_dn" module in mods-available/cache_auth.
+ #
+ user_dn = "LDAP-UserDn"
+
+ #
+ # User object identification.
+ #
+ user {
+ # The typical Google LDAP configuration has users under "ou=Users..."
+ base_dn = "ou=Users,${..base_dn}"
+
+ filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
+
+ scope = 'sub'
+
+# sort_by = '-uid'
+
+# access_attribute = 'dialupAccess'
+
+# access_positive = yes
+ }
+
+ #
+ # User membership checking.
+ #
+ group {
+ # The typical Google LDAP configuration has groups under "ou=Groups..."
+ base_dn = "ou=Groups,${..base_dn}"
+
+ filter = '(objectClass=posixGroup)'
+
+ scope = 'sub'
+
+ name_attribute = cn
+
+ #
+ # Google Secure LDAP supports the "memberOf"
+ # attribute, which is more efficient than using this
+ # filter.
+ #
+ # You should also check the permissions of the client
+ # in Google's systems to ensure that it is allowed to
+ # read group information.
+ #
+# membership_filter = "(|(member=%{control:${..user_dn}})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
+
+ membership_attribute = 'memberOf'
+
+ #
+ # If the "memberOf" attribute is used for retrieving group membership,
+ # then you should also use "cacheable_dn", in orser to cache the group details.
+ # "memberOf" is a list of fully quallified group DNs which the user belongs to,
+ # so using the DN for the cache avoids further lookups to retrieve group names.
+ #
+# cacheable_name = 'no'
+# cacheable_dn = 'no'
+
+# cache_attribute = 'LDAP-Cached-Membership'
+
+# allow_dangling_group_ref = 'no'
+ }
+
+ options {
+# dereference = 'always'
+
+ # Google Secure LDAP does not appear to do referrals, so we might as well
+ # turn this off.
+ chase_referrals = no
+# rebind = yes
+
+ # Some reasonable defaults for use with Google Secure LDAP
+ #
+ # See mods-available/ldap for a complete description
+ # of what these configuration options mean.
+ #
+ res_timeout = 10
+ srv_timelimit = 3
+ net_timeout = 3
+ idle = 60
+ probes = 3
+ interval = 3
+
+ ldap_debug = 0x0000
+ }
+
+ tls {
+
+ #
+ # The certificate and key which were downloaded from the Google
+ # client tools are configured here.
+ #
+ # By default ${certdir} is raddb/certs/. You can
+ # please these files anywhere you want. The only
+ # requirement is that they are readable by
+ # FreeRADIUS, and NOT readable by anyone else on the
+ # system!
+ #
+# certificate_file = ${certdir}/google/certificate.crt
+# private_key_file = ${certdir}/google/key.key
+# random_file = /dev/urandom
+
+ #
+ # Google Secure LDAP uses a self signed certificate
+ # so this configuration needs to be set to 'allow'
+ #
+ require_cert = 'allow'
+
+ #
+ # We recommend not using TLS 1.0 or 1.1.
+ #
+# tls_min_version = "1.2"
+ }
+
+ #
+ # See mods-available/ldap for documentation on the "pool"
+ # section and its configuration items.
+ #
+ pool {
+ start = ${thread[pool].start_servers}
+ min = ${thread[pool].min_spare_servers}
+ max = ${thread[pool].max_servers}
+ spare = ${thread[pool].max_spare_servers}
+
+ uses = 0
+ retry_delay = 30
+ lifetime = 0
+ idle_timeout = 60
+ }
+}
diff --git a/raddb/mods-available/linelog b/raddb/mods-available/linelog
new file mode 100644
index 0000000..66d2682
--- /dev/null
+++ b/raddb/mods-available/linelog
@@ -0,0 +1,170 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# The "linelog" module will log one line of text to a file.
+# Both the filename and the line of text are dynamically expanded.
+#
+# We STRONGLY suggest that you do not use data from the
+# packet as part of the filename.
+#
+linelog {
+ #
+ # The file where the logs will go.
+ #
+ # If the filename is "syslog", then the log messages will
+ # go to syslog.
+ #
+ # The output can be directed to stdout by using /dev/stdout
+ #
+ filename = ${logdir}/linelog
+
+ #
+ # Most file systems can handly nearly the full range of UTF-8
+ # characters. Ones that can deal with a limited range should
+ # set this to "yes".
+ #
+ escape_filenames = no
+
+ #
+ # The Unix-style permissions on the log file.
+ #
+ # Depending on format string, the log file may contain secret or
+ # private information about users. Keep the file permissions as
+ # restrictive as possible.
+ permissions = 0600
+
+ # The Unix group which owns the log file.
+ #
+ # The user that freeradius runs as must be in the specified
+ # group, otherwise it will not be possible to set the group.
+# group = ${security.group}
+
+ # Syslog facility (if logging via syslog).
+ # Defaults to the syslog_facility config item in radiusd.conf.
+ # Standard facilities are:
+ # - kern Messages generated by the kernel. These cannot
+ # be generated by any user processes.
+ # - user Messages generated by random user processes.
+ # This is the default facility identifier if
+ # none is specified.
+ # - mail The mail system.
+ # - daemon System daemons, such as routed(8), that are not
+ # provided for explicitly by other facilities.
+ # - auth The authorization system: login(1), su(1),
+ # getty(8), etc.
+ # - lpr The line printer spooling system: cups-lpd(8),
+ # cupsd(8), etc.
+ # - news The network news system.
+ # - uucp The uucp system.
+ # - cron The cron daemon: cron(8).
+ # - authpriv The same as LOG_AUTH, but logged to a file
+ # readable only by selected individuals.
+ # - ftp The file transfer protocol daemons: ftpd(8),
+ # tftpd(8).
+ # - local[0-7] Reserved for local use.
+# syslog_facility = daemon
+
+ # Syslog severity (if logging via syslog). Defaults to info.
+ # Possible values are:
+ # - emergency A panic condition. This is normally broadcast
+ # to all users.
+ # - alert A condition that should be corrected immediately,
+ # such as a corrupted system database.
+ # - critical Critical conditions, e.g., hard device errors.
+ # - error Errors.
+ # - warning Warning messages.
+ # - notice Conditions that are not error conditions, but
+ # should possibly be handled specially.
+ # - info Informational messages.
+ # - debug Messages that contain information normally of use
+ # only when debugging a program.
+# syslog_severity = info
+
+ # If logging via syslog, the severity can be set here.
+ # Defaults to info.
+
+ #
+ # Optional header format string.
+ # Written to the first line of any newly created log file
+# header = "This is a header line"
+
+ #
+ # The default format string.
+ format = "This is a log message for %{User-Name}"
+
+ #
+ # This next line can be omitted. If it is omitted, then
+ # the log message is static, and is always given by "format",
+ # above.
+ #
+ # If it is defined, then the string is dynamically expanded,
+ # and the result is used to find another configuration entry
+ # here, with the given name. That name is then used as the
+ # format string.
+ #
+ # If the configuration entry cannot be found, then no log
+ # message is printed.
+ #
+ # i.e. You can have many log messages in one "linelog" module.
+ # If this two-step expansion did not exist, you would have
+ # needed to configure one "linelog" module for each log message.
+
+ #
+ # Reference the Packet-Type (Access-Accept, etc.) If it doesn't
+ # exist, reference the "default" entry.
+ #
+ # This is for "linelog" being used in the post-auth section
+ # If you want to use it in "authorize", you need to change
+ # the reference to "messages.%{%{Packet-Type}:-default}",
+ # and then add the appropriate messages.
+ #
+ reference = "messages.%{%{reply:Packet-Type}:-default}"
+
+ #
+ # The messages defined here are taken from the "reference"
+ # expansion, above.
+ #
+ messages {
+ default = "Unknown packet type %{Packet-Type}"
+
+ Access-Accept = "Accepted user: %{User-Name}"
+ Access-Reject = "Rejected user: %{User-Name}"
+ Access-Challenge = "Sent challenge: %{User-Name}"
+ }
+}
+
+#
+# Another example, for accounting packets.
+#
+linelog log_accounting {
+ #
+ # Used if the expansion of "reference" fails.
+ #
+ format = ""
+
+ filename = ${logdir}/linelog-accounting
+
+ permissions = 0600
+
+ reference = "Accounting-Request.%{%{Acct-Status-Type}:-unknown}"
+
+ #
+ # Another example:
+ #
+ #
+ Accounting-Request {
+ Start = "Connect: [%{User-Name}] (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} ip %{Framed-IP-Address})"
+ Stop = "Disconnect: [%{User-Name}] (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} ip %{Framed-IP-Address}) %{Acct-Session-Time} seconds"
+
+ # Don't log anything for these packets.
+ Alive = ""
+
+ Accounting-On = "NAS %{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}} (%{%{NAS-IP-Address}:-%{NAS-IPv6-Address}}) just came online"
+ Accounting-Off = "NAS %{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}} (%{%{NAS-IP-Address}:-%{NAS-IPv6-Address}}) just went offline"
+
+ # don't log anything for other Acct-Status-Types.
+ unknown = "NAS %{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}} (%{%{NAS-IP-Address}:-%{NAS-IPv6-Address}}) sent unknown Acct-Status-Type %{Acct-Status-Type}"
+ }
+}
diff --git a/raddb/mods-available/logintime b/raddb/mods-available/logintime
new file mode 100644
index 0000000..2534452
--- /dev/null
+++ b/raddb/mods-available/logintime
@@ -0,0 +1,23 @@
+# -*- text -*-
+#
+# $Id$
+
+# The logintime module. This handles the Login-Time,
+# Current-Time, and Time-Of-Day attributes. It should be
+# included in the *end* of the authorize section in order to
+# handle Login-Time checks. It should also be included in the
+# instantiate section in order to register the Current-Time
+# and Time-Of-Day comparison functions.
+#
+# When the Login-Time attribute is set to some value, and the
+# user has been permitted to log in, a Session-Timeout is
+# calculated based on the remaining time. See "doc/README".
+#
+logintime {
+ # The minimum timeout (in seconds) a user is allowed
+ # to have. If the calculated timeout is lower we don't
+ # allow the login. Some NAS do not handle values
+ # lower than 60 seconds well.
+ minimum_timeout = 60
+}
+
diff --git a/raddb/mods-available/mac2ip b/raddb/mods-available/mac2ip
new file mode 100644
index 0000000..a4ead1d
--- /dev/null
+++ b/raddb/mods-available/mac2ip
@@ -0,0 +1,25 @@
+# -*- text -*-
+#
+# $Id$
+
+######################################################################
+#
+# This next section is a sample configuration for the "passwd"
+# module, that reads flat-text files.
+#
+# 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 assignments from a flat-text
+# file. You will have to define lease times yourself.
+#
+######################################################################
+
+passwd mac2ip {
+ filename = ${modconfdir}/${.:name}/${.:instance}
+ format = "*DHCP-Client-Hardware-Address:=DHCP-Your-IP-Address"
+ delimiter = ","
+}
diff --git a/raddb/mods-available/mac2vlan b/raddb/mods-available/mac2vlan
new file mode 100644
index 0000000..a1db803
--- /dev/null
+++ b/raddb/mods-available/mac2vlan
@@ -0,0 +1,18 @@
+# -*- text -*-
+#
+# $Id$
+
+# A simple file to map a MAC address to a VLAN.
+#
+# The file should be in the format MAC,VLAN
+# the VLAN name cannot have spaces in it, for example:
+#
+# 00:01:02:03:04:05,VLAN1
+# 03:04:05:06:07:08,VLAN2
+# ...
+#
+passwd mac2vlan {
+ filename = ${modconfdir}/${.:name}/${.:instance}
+ format = "*VMPS-Mac:=VMPS-VLAN-Name"
+ delimiter = ","
+}
diff --git a/raddb/mods-available/moonshot-targeted-ids b/raddb/mods-available/moonshot-targeted-ids
new file mode 100644
index 0000000..1b27b44
--- /dev/null
+++ b/raddb/mods-available/moonshot-targeted-ids
@@ -0,0 +1,57 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Write Moonshot-*-TargetedId (MSTID) to the database.
+#
+# Schema raddb/mods-config/sql/moonshot-targeted-ids/<DB>/schema.sql
+# Queries raddb/mods-config/sql/moonshot-targeted-ids/<DB>/queries.conf
+#
+sql moonshot_tid_sql {
+
+ # The dialect of SQL you want to use, this should usually match
+ # the driver below.
+ #
+ # If you're using rlm_sql_null, then it should be the type of
+ # database the logged queries are going to be executed against.
+ dialect = "sqlite"
+
+ # The sub-module to use to execute queries. This should match
+ # the database you're attempting to connect to.
+ #
+ # There are MSTID queries available for:
+ # * rlm_sql_mysql
+ # * rlm_sql_postgresql
+ # * rlm_sql_sqlite
+ # * rlm_sql_null (log queries to disk)
+ #
+ driver = "rlm_sql_${dialect}"
+
+ sqlite {
+ filename = ${radacctdir}/moonshot-targeted-ids.sqlite
+ bootstrap = ${modconfdir}/${..:name}/moonshot-targeted-ids/sqlite/schema.sql
+ }
+
+ # Write MSTID queries to a logfile. Useful for debugging.
+# logfile = ${logdir}/moonshot-targeted-id-log.sql
+
+ pool {
+ start = 5
+ min = 4
+ max = 10
+ spare = 3
+ uses = 0
+ lifetime = 0
+ idle_timeout = 60
+ }
+
+ # If you adjust the table name here, you must also modify the table name in
+ # the moonshot_get_targeted_id.post-auth policy in policy.d/moonshot-targeted-ids
+ # and the schema.sql files in the mods-config/sql/moonshot-targeted-ids tree.
+ #
+ moonshot_tid_table = "moonshot_targeted_ids"
+ sql_user_name = "%{User-Name}"
+
+ $INCLUDE ${modconfdir}/${.:name}/moonshot-targeted-ids/${dialect}/queries.conf
+}
diff --git a/raddb/mods-available/mschap b/raddb/mods-available/mschap
new file mode 100644
index 0000000..1748d57
--- /dev/null
+++ b/raddb/mods-available/mschap
@@ -0,0 +1,253 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Microsoft CHAP authentication
+#
+# This module supports MS-CHAP and MS-CHAPv2 authentication.
+# It also enforces the SMB-Account-Ctrl attribute.
+#
+mschap {
+ #
+ # If you are using /etc/smbpasswd, see the 'passwd'
+ # module for an example of how to use /etc/smbpasswd
+ #
+
+ #
+ # If use_mppe is not set to no mschap, will
+ # add MS-CHAP-MPPE-Keys for MS-CHAPv1 and
+ # MS-MPPE-Recv-Key/MS-MPPE-Send-Key for MS-CHAPv2
+ #
+# use_mppe = no
+
+ #
+ # If MPPE is enabled, require_encryption makes
+ # encryption moderate
+ #
+# require_encryption = yes
+
+ #
+ # require_strong always requires 128 bit key
+ # encryption
+ #
+# require_strong = yes
+
+ #
+ # This module can perform authentication itself, OR
+ # use a Windows Domain Controller. This configuration
+ # directive tells the module to call the ntlm_auth
+ # program, which will do the authentication, and return
+ # the NT-Key. Note that you MUST have "winbindd" and
+ # "nmbd" running on the local machine for ntlm_auth
+ # to work. See the ntlm_auth program documentation
+ # for details.
+ #
+ # If ntlm_auth is configured below, then the mschap
+ # module will call ntlm_auth for every MS-CHAP
+ # authentication request. If there is a cleartext
+ # or NT hashed password available, you can set
+ # "MS-CHAP-Use-NTLM-Auth := No" in the control items,
+ # and the mschap module will do the authentication itself,
+ # without calling ntlm_auth.
+ #
+ # Be VERY careful when editing the following line!
+ #
+ # You can also try setting the user name as:
+ #
+ # ... --username=%{mschap:User-Name} ...
+ #
+ # In that case, the mschap module will look at the User-Name
+ # attribute, and do prefix/suffix checks in order to obtain
+ # the "best" user name for the request.
+ #
+ # For Samba 4, you should also set the "ntlm auth" parameter
+ # in the Samba configuration:
+ #
+ # ntlm auth = yes
+ #
+ # or
+ #
+ # ntlm auth = mschapv2-and-ntlmv2-only
+ #
+ # This will let Samba 4 accept the MS-CHAP authentication
+ # method that is needed by FreeRADIUS.
+ #
+ # Depending on the Samba version, you may also need to add:
+ #
+ # --allow-mschapv2
+ #
+ # to the command-line parameters.
+ #
+# ntlm_auth = "/path/to/ntlm_auth --request-nt-key --allow-mschapv2 --username=%{%{Stripped-User-Name}:-%{%{User-Name}:-None}} --challenge=%{%{mschap:Challenge}:-00} --nt-response=%{%{mschap:NT-Response}:-00}"
+
+ #
+ # The default is to wait 10 seconds for ntlm_auth to
+ # complete. This is a long time, and if it's taking that
+ # long then you likely have other problems in your domain.
+ # The length of time can be decreased with the following
+ # option, which can save clients waiting if your ntlm_auth
+ # usually finishes quicker. Range 1 to 10 seconds.
+ #
+# ntlm_auth_timeout = 10
+
+ #
+ # An alternative to using ntlm_auth is to connect to the
+ # winbind daemon directly for authentication. This option
+ # is likely to be faster and may be useful on busy systems,
+ # but is less well tested.
+ #
+ # Using this option requires libwbclient from Samba 4.2.1
+ # or later to be installed. Make sure that ntlm_auth above is
+ # commented out.
+ #
+# winbind_username = "%{mschap:User-Name}"
+# winbind_domain = "%{mschap:NT-Domain}"
+
+ #
+ # When using single sign-on with a winbind connection and the
+ # client uses a different casing for the username than the
+ # casing is according to the backend, reauth may fail because
+ # of some Windows internals. This switch tries to find the
+ # user in the correct casing in the backend, and retry
+ # authentication with that username.
+ #
+# winbind_retry_with_normalised_username = no
+
+ #
+ # Information for the winbind connection pool. The configuration
+ # items below are the same for all modules which use the new
+ # connection pool.
+ #
+ pool {
+ #
+ # 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
+ # winbind daemon being available.
+ #
+ start = ${thread[pool].start_servers}
+
+ #
+ # Minimum number of connections to keep open
+ #
+ min = ${thread[pool].min_spare_servers}
+
+ #
+ # 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.
+ #
+ max = ${thread[pool].max_servers}
+
+ #
+ # 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.
+ #
+ spare = ${thread[pool].max_spare_servers}
+
+ #
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ #
+ uses = 0
+
+ #
+ # 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.
+ #
+ retry_delay = 30
+
+ #
+ # The lifetime (in seconds) of the connection
+ #
+ # NOTE: A setting of 0 means infinite (no limit).
+ #
+ lifetime = 86400
+
+ #
+ # The pool is checked for free connections every
+ # "cleanup_interval". If there are free connections,
+ # then one of them is closed.
+ #
+ cleanup_interval = 300
+
+ #
+ # 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).
+ #
+ idle_timeout = 600
+
+ #
+ # 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.
+ #
+ }
+
+ passchange {
+ #
+ # This support MS-CHAPv2 (not v1) password change
+ # requests. See doc/mschap.rst for more IMPORTANT
+ # information.
+ #
+ # Samba/ntlm_auth - if you are using ntlm_auth to
+ # validate passwords, you will need to use ntlm_auth
+ # to change passwords. Uncomment the three lines
+ # below, and change the path to ntlm_auth.
+ #
+# ntlm_auth = "/usr/bin/ntlm_auth --helper-protocol=ntlm-change-password-1"
+# ntlm_auth_username = "username: %{mschap:User-Name}"
+# ntlm_auth_domain = "nt-domain: %{mschap:NT-Domain}"
+
+ #
+ # To implement a local password change, you need to
+ # supply a string which is then expanded, so that the
+ # password can be placed somewhere. e.g. passed to a
+ # script (exec), or written to SQL (UPDATE/INSERT).
+ # We give both examples here, but only one will be
+ # used.
+ #
+# local_cpw = "%{exec:/path/to/script %{mschap:User-Name} %{MS-CHAP-New-Cleartext-Password}}"
+ #
+# local_cpw = "%{sql:UPDATE radcheck set value='%{MS-CHAP-New-NT-Password}' where username='%{SQL-User-Name}' and attribute='NT-Password'}"
+ }
+
+ #
+ # For Apple Server, when running on the same machine as
+ # Open Directory. It has no effect on other systems.
+ #
+# use_open_directory = yes
+
+ #
+ # On failure, set (or not) the MS-CHAP error code saying
+ # "retries allowed".
+ #
+# allow_retry = yes
+
+ #
+ # An optional retry message.
+ #
+# retry_msg = "Re-enter (or reset) the password"
+}
diff --git a/raddb/mods-available/ntlm_auth b/raddb/mods-available/ntlm_auth
new file mode 100644
index 0000000..ab0017c
--- /dev/null
+++ b/raddb/mods-available/ntlm_auth
@@ -0,0 +1,18 @@
+#
+# For testing ntlm_auth authentication with PAP.
+#
+# If you have problems with authentication failing, even when the
+# password is good, it may be a bug in Samba:
+#
+# https://bugzilla.samba.org/show_bug.cgi?id=6563
+#
+# Depending on the AD / Samba configuration, you may also need to add:
+#
+# --allow-mschapv2
+#
+# to the list of command-line options.
+#
+exec ntlm_auth {
+ wait = yes
+ program = "/path/to/ntlm_auth --request-nt-key --domain=MYDOMAIN --username=%{mschap:User-Name} --password=%{User-Password}"
+}
diff --git a/raddb/mods-available/opendirectory b/raddb/mods-available/opendirectory
new file mode 100644
index 0000000..443d74d
--- /dev/null
+++ b/raddb/mods-available/opendirectory
@@ -0,0 +1,26 @@
+# -*- text -*-
+#
+# $Id$
+
+# This module is only used when the server is running on the same
+# system as OpenDirectory. The configuration of the module is hard-coded
+# by Apple, and cannot be changed here.
+#
+# There are no configuration entries for this module.
+#
+# The MS-CHAP module will automatically talk to OpenDirectory, if the
+# server is built on an OSX machine. However, you must also set
+# dsAttrTypeNative:apple-enabled-auth-mech attribute in the
+# /config/dirserv OpenDirectory record. You will probably also need
+# to change the user passwords in order to re-generate the
+# appropriate hashes.
+#
+# Complete OSX configuration information is available on Apple's web site:
+#
+# https://developer.apple.com/support/macos-server/macOS-Server-Service-Migration-Guide.pdf
+#
+# See also https://discussions.apple.com/thread/6053980?tstart=0
+#
+opendirectory {
+
+}
diff --git a/raddb/mods-available/pam b/raddb/mods-available/pam
new file mode 100644
index 0000000..f4a91a9
--- /dev/null
+++ b/raddb/mods-available/pam
@@ -0,0 +1,26 @@
+# -*- text -*-
+#
+# $Id$
+
+
+# Pluggable Authentication Modules
+#
+# For Linux, see:
+# http://www.kernel.org/pub/linux/libs/pam/index.html
+#
+# WARNING: On many systems, the system PAM libraries have
+# memory leaks! We STRONGLY SUGGEST that you do not
+# use PAM for authentication, due to those memory leaks.
+#
+pam {
+ #
+ # The name to use for PAM authentication.
+ # PAM looks in /etc/pam.d/${pam_auth_name}
+ # for it's configuration. See 'redhat/radiusd-pam'
+ # for a sample PAM configuration file.
+ #
+ # Note that any Pam-Auth attribute set in the 'authorize'
+ # section will over-ride this one.
+ #
+ pam_auth = radiusd
+}
diff --git a/raddb/mods-available/pap b/raddb/mods-available/pap
new file mode 100644
index 0000000..0038ecd
--- /dev/null
+++ b/raddb/mods-available/pap
@@ -0,0 +1,18 @@
+# -*- text -*-
+#
+# $Id$
+
+# PAP module to authenticate users based on their stored password
+#
+# Supports multiple encryption/hash schemes. See "man rlm_pap"
+# for details.
+#
+# For instructions on creating the various types of passwords, see:
+#
+# http://www.openldap.org/faq/data/cache/347.html
+pap {
+ # By default the server will use heuristics to try and automatically
+ # handle base64 or hex encoded passwords. This behaviour can be
+ # stopped by setting the following to "no".
+# normalise = yes
+}
diff --git a/raddb/mods-available/passwd b/raddb/mods-available/passwd
new file mode 100644
index 0000000..11bd224
--- /dev/null
+++ b/raddb/mods-available/passwd
@@ -0,0 +1,55 @@
+# -*- text -*-
+#
+# $Id$
+
+# passwd module allows to do authorization via any passwd-like
+# file and to extract any attributes from these files.
+#
+# See the "smbpasswd" and "etc_group" files for more examples.
+#
+# parameters are:
+# filename - path to file
+#
+# format - format for filename record. This parameters
+# correlates record in the passwd file and RADIUS
+# attributes.
+#
+# Field marked as '*' is a key field. That is, the parameter
+# with this name from the request is used to search for
+# the record from passwd file
+#
+# Attributes marked as '=' are added to reply_items instead
+# of default configure_items
+#
+# Attributes marked as '~' are added to request_items
+#
+# Field marked as ',' may contain a comma separated list
+# of attributes.
+#
+# hash_size - hashtable size. Setting it to 0 is no longer permitted
+# A future version of the server will have the module
+# automatically determine the hash size. Having it set
+# manually should not be necessary.
+#
+# allow_multiple_keys - if many records for a key are allowed
+#
+# ignore_nislike - ignore NIS-related records
+#
+# delimiter - symbol to use as a field separator in passwd file,
+# for format ':' symbol is always used. '\0', '\n' are
+# not allowed
+#
+
+# An example configuration for using /etc/passwd.
+#
+# This is an example which will NOT WORK if you have shadow passwords,
+# NIS, etc. The "unix" module is normally responsible for reading
+# system passwords. You should use it instead of this example.
+#
+passwd etc_passwd {
+ filename = /etc/passwd
+ format = "*User-Name:Crypt-Password:"
+ hash_size = 100
+ ignore_nislike = no
+ allow_multiple_keys = no
+}
diff --git a/raddb/mods-available/perl b/raddb/mods-available/perl
new file mode 100644
index 0000000..99215b8
--- /dev/null
+++ b/raddb/mods-available/perl
@@ -0,0 +1,94 @@
+# -*- text -*-
+#
+# $Id$
+
+# Persistent, embedded Perl interpreter.
+#
+perl {
+ #
+ # The Perl script to execute on authorize, authenticate,
+ # accounting, xlat, etc. This is very similar to using
+ # 'rlm_exec' module, but it is persistent, and therefore
+ # faster.
+ #
+ filename = ${modconfdir}/${.:instance}/example.pl
+
+ #
+ # Options which are passed to the Perl interpreter.
+ # These are (mostly) the same options as are passed
+ # to the "perl" command line.
+ #
+ # The most useful flag is "-T". This sets tainting on, which
+ # makes it impossible to leverage bad User-Names into local
+ # command execution.
+ #
+ perl_flags = "-T"
+
+ #
+ # The following hashes are given to the module and
+ # filled with value-pairs (Attribute names and values)
+ #
+ # %RAD_CHECK Check items
+ # %RAD_REQUEST Attributes from the request
+ # %RAD_REPLY Attributes for the reply
+ # %RAD_REQUEST_PROXY Attributes from the proxied request
+ # %RAD_REQUEST_PROXY_REPLY Attributes from the proxy reply
+ #
+ # The interface between FreeRADIUS and Perl is strings.
+ # That is, attributes of type "octets" are converted to
+ # printable strings, such as "0xabcdef". If you want to
+ # access the binary values of the attributes, you should
+ # call the Perl "pack" function. Then to send any binary
+ # data back to FreeRADIUS, call the Perl "unpack" function,
+ # so that the contents of the hashes are printable strings.
+ #
+ # IP addresses are sent as strings, e.g. "192.0.2.25", and
+ # not as a 4-byte binary value. The same applies to other
+ # attribute data types.
+ #
+ # Attributes of type "string" are copied to Perl as-is.
+ # They are not escaped or interpreted.
+ #
+ # The return codes from functions in the perl_script
+ # are passed directly back to the server. These
+ # codes are defined in mods-config/example.pl
+ #
+
+ # You can define configuration items (and nested sub-sections) in perl "config" section.
+ # These items will be accessible in the perl script through %RAD_PERLCONF hash.
+ # For instance: $RAD_PERLCONF{'name'} $RAD_PERLCONF{'sub-config'}->{'name'}
+ #
+ #config {
+ # name = "value"
+ # sub-config {
+ # name = "value of name from config.sub-config"
+ # }
+ #}
+
+ #
+ # List of functions in the module to call.
+ # Uncomment and change if you want to use function
+ # names other than the defaults.
+ #
+ #func_authenticate = authenticate
+ #func_authorize = authorize
+ #func_preacct = preacct
+ #func_accounting = accounting
+ #func_checksimul = checksimul
+ #func_pre_proxy = pre_proxy
+ #func_post_proxy = post_proxy
+ #func_post_auth = post_auth
+ #func_recv_coa = recv_coa
+ #func_send_coa = send_coa
+ #func_xlat = xlat
+ #func_detach = detach
+
+ #
+ # Uncomment the following lines if you wish
+ # to use separate functions for Start and Stop
+ # accounting packets. In that case, the
+ # func_accounting function is not called.
+ #
+ #func_start_accounting = accounting_start
+ #func_stop_accounting = accounting_stop
+}
diff --git a/raddb/mods-available/preprocess b/raddb/mods-available/preprocess
new file mode 100644
index 0000000..8baec79
--- /dev/null
+++ b/raddb/mods-available/preprocess
@@ -0,0 +1,62 @@
+# -*- text -*-
+#
+# $Id$
+
+# Preprocess the incoming RADIUS request, before handing it off
+# to other modules.
+#
+# This module processes the 'huntgroups' and 'hints' files.
+# In addition, it re-writes some weird attributes created
+# by some NAS, and converts the attributes into a form which
+# is a little more standard.
+#
+preprocess {
+ # Search for files in a subdirectory of mods-config which
+ # matches this instance of the preprocess module.
+ moddir = ${modconfdir}/${.:instance}
+
+ huntgroups = ${moddir}/huntgroups
+ hints = ${moddir}/hints
+
+ # This hack changes Ascend's weird port numbering
+ # to standard 0-??? port numbers so that the "+" works
+ # for IP address assignments.
+ with_ascend_hack = no
+ ascend_channels_per_line = 23
+
+ # Windows NT machines often authenticate themselves as
+ # NT_DOMAIN\username
+ #
+ # If this is set to 'yes', then the NT_DOMAIN portion
+ # of the user-name is silently discarded.
+ #
+ # This configuration entry SHOULD NOT be used.
+ # See the "realms" module for a better way to handle
+ # NT domains.
+ with_ntdomain_hack = no
+
+ # Specialix Jetstream 8500 24 port access server.
+ #
+ # If the user name is 10 characters or longer, a "/"
+ # and the excess characters after the 10th are
+ # appended to the user name.
+ #
+ # If you're not running that NAS, you don't need
+ # this hack.
+ with_specialix_jetstream_hack = no
+
+ # Cisco (and Quintum in Cisco mode) sends it's VSA attributes
+ # with the attribute name *again* in the string, like:
+ #
+ # H323-Attribute = "h323-attribute=value".
+ #
+ # If this configuration item is set to 'yes', then
+ # the redundant data in the the attribute text is stripped
+ # out. The result is:
+ #
+ # H323-Attribute = "value"
+ #
+ # If you're not running a Cisco or Quintum NAS, you don't
+ # need this hack.
+ with_cisco_vsa_hack = no
+}
diff --git a/raddb/mods-available/python b/raddb/mods-available/python
new file mode 100644
index 0000000..371a56d
--- /dev/null
+++ b/raddb/mods-available/python
@@ -0,0 +1,65 @@
+#
+# Make sure the PYTHONPATH environmental variable contains the
+# directory(s) for the modules listed below.
+#
+# Uncomment any func_* which are included in your module. If
+# rlm_python is called for a section which does not have
+# a function defined, it will return NOOP.
+#
+python {
+ # Path to the python modules
+ #
+ # Note that due to limitations on Python, this configuration
+ # item is GLOBAL TO THE SERVER. That is, you cannot have two
+ # instances of the python module, each with a different path.
+ #
+# python_path="${modconfdir}/${.:name}:/path/to/python/files:/another_path/to/python_files/"
+
+ module = example
+
+ # Pass all VPS lists as a 6-tuple to the callbacks
+ # (request, reply, config, state, proxy_req, proxy_reply)
+# pass_all_vps = no
+
+ # Pass all VPS lists as a dictionary to the callbacks
+ # Keys: "request", "reply", "config", "session-state", "proxy-request",
+ # "proxy-reply"
+ # This option prevales over "pass_all_vps"
+# pass_all_vps_dict = no
+
+# mod_instantiate = ${.module}
+# func_instantiate = instantiate
+
+# mod_detach = ${.module}
+# func_detach = detach
+
+# mod_authorize = ${.module}
+# func_authorize = authorize
+
+# mod_authenticate = ${.module}
+# func_authenticate = authenticate
+
+# mod_preacct = ${.module}
+# func_preacct = preacct
+
+# mod_accounting = ${.module}
+# func_accounting = accounting
+
+# mod_checksimul = ${.module}
+# func_checksimul = checksimul
+
+# mod_pre_proxy = ${.module}
+# func_pre_proxy = pre_proxy
+
+# mod_post_proxy = ${.module}
+# func_post_proxy = post_proxy
+
+# mod_post_auth = ${.module}
+# func_post_auth = post_auth
+
+# mod_recv_coa = ${.module}
+# func_recv_coa = recv_coa
+
+# mod_send_coa = ${.module}
+# func_send_coa = send_coa
+}
diff --git a/raddb/mods-available/python3 b/raddb/mods-available/python3
new file mode 100644
index 0000000..f0e0424
--- /dev/null
+++ b/raddb/mods-available/python3
@@ -0,0 +1,65 @@
+#
+# Make sure the PYTHONPATH environmental variable contains the
+# directory(s) for the modules listed below.
+#
+# Uncomment any func_* which are included in your module. If
+# rlm_python is called for a section which does not have
+# a function defined, it will return NOOP.
+#
+python3 {
+ # Path to the python modules
+ #
+ # Note that due to limitations on Python, this configuration
+ # item is GLOBAL TO THE SERVER. That is, you cannot have two
+ # instances of the python module, each with a different path.
+ #
+# python_path="${modconfdir}/${.:name}:/another_path/to/python_files"
+
+ module = example
+
+ # Pass all VPS lists as a 6-tuple to the callbacks
+ # (request, reply, config, state, proxy_req, proxy_reply)
+# pass_all_vps = no
+
+ # Pass all VPS lists as a dictionary to the callbacks
+ # Keys: "request", "reply", "config", "session-state", "proxy-request",
+ # "proxy-reply"
+ # This option prevales over "pass_all_vps"
+# pass_all_vps_dict = no
+
+# mod_instantiate = ${.module}
+# func_instantiate = instantiate
+
+# mod_detach = ${.module}
+# func_detach = detach
+
+# mod_authorize = ${.module}
+# func_authorize = authorize
+
+# mod_authenticate = ${.module}
+# func_authenticate = authenticate
+
+# mod_preacct = ${.module}
+# func_preacct = preacct
+
+# mod_accounting = ${.module}
+# func_accounting = accounting
+
+# mod_checksimul = ${.module}
+# func_checksimul = checksimul
+
+# mod_pre_proxy = ${.module}
+# func_pre_proxy = pre_proxy
+
+# mod_post_proxy = ${.module}
+# func_post_proxy = post_proxy
+
+# mod_post_auth = ${.module}
+# func_post_auth = post_auth
+
+# mod_recv_coa = ${.module}
+# func_recv_coa = recv_coa
+
+# mod_send_coa = ${.module}
+# func_send_coa = send_coa
+}
diff --git a/raddb/mods-available/radutmp b/raddb/mods-available/radutmp
new file mode 100644
index 0000000..82319c0
--- /dev/null
+++ b/raddb/mods-available/radutmp
@@ -0,0 +1,53 @@
+# -*- text -*-
+#
+# $Id$
+
+# Write a 'utmp' style file, of which users are currently
+# logged in, and where they've logged in from.
+#
+# This file is used mainly for Simultaneous-Use checking,
+# and also 'radwho', to see who's currently logged in.
+#
+radutmp {
+ # Where the file is stored. It's not a log file,
+ # so it doesn't need rotating.
+ #
+ filename = ${logdir}/radutmp
+
+ # The field in the packet to key on for the
+ # 'user' name, If you have other fields which you want
+ # to use to key on to control Simultaneous-Use,
+ # then you can use them here.
+ #
+ # Note, however, that the size of the field in the
+ # 'utmp' data structure is small, around 32
+ # characters, so that will limit the possible choices
+ # of keys.
+ #
+ # You may want instead: %{%{Stripped-User-Name}:-%{User-Name}}
+ username = %{User-Name}
+
+
+ # Whether or not we want to treat "user" the same
+ # as "USER", or "User". Some systems have problems
+ # with case sensitivity, so this should be set to
+ # 'no' to enable the comparisons of the key attribute
+ # to be case insensitive.
+ #
+ case_sensitive = yes
+
+ # Accounting information may be lost, so the user MAY
+ # have logged off of the NAS, but we haven't noticed.
+ # If so, we can verify this information with the NAS,
+ #
+ # If we want to believe the 'utmp' file, then this
+ # configuration entry can be set to 'no'.
+ #
+ check_with_nas = yes
+
+ # Set the file permissions, as the contents of this file
+ # are usually private.
+ permissions = 0600
+
+ caller_id = "yes"
+}
diff --git a/raddb/mods-available/realm b/raddb/mods-available/realm
new file mode 100644
index 0000000..947a42d
--- /dev/null
+++ b/raddb/mods-available/realm
@@ -0,0 +1,80 @@
+# -*- text -*-
+#
+# $Id$
+
+# Realm module, for proxying.
+#
+# You can have multiple instances of the realm module to
+# support multiple realm syntaxes at the same time. The
+# search order is defined by the order that the modules are listed
+# in the authorize and preacct sections.
+#
+# Four config options:
+# format - must be "prefix" or "suffix"
+# The special cases of "DEFAULT"
+# and "NULL" are allowed, too.
+# delimiter - must be a single character
+
+#
+# For dynamic home servers, see doc/configuration/dynamic_home_servers.md,
+# and the script in mods-config/realm/freeradius-naptr-to-home-server.sh
+#
+
+# 'realm/username'
+#
+# Using this entry, IPASS users have their realm set to "IPASS".
+realm IPASS {
+ format = prefix
+ delimiter = "/"
+}
+
+# 'username@realm'
+#
+realm suffix {
+ format = suffix
+ delimiter = "@"
+
+ # The next configuration items are valid ONLY for a trust-router.
+ # For all other realms, they are ignored.
+# trust_router = "localhost"
+# tr_port = 12309
+# rp_realm = "realm.example.com"
+# default_community = "apc.communities.example.com"
+# # if rekey_enabled is enabled, dynamic realms are automatically rekeyed
+# # before they expire to avoid having to recreate them from scrach on
+# # demand (implying lengthy authentications)
+# rekey_enabled = no
+# # if realm_lifetime is > 0, the rekey is scheduled to happen the
+# # specified number of seconds after its creation or rekeying. Otherwise,
+# # the key material expiration timestamp is used
+# realm_lifetime = 0
+}
+
+# 'realm!username'
+#
+realm bangpath {
+ format = prefix
+ delimiter = "!"
+
+# trust_router = "localhost"
+# tr_port = 12309
+# rp_realm = "realm.example.com"
+# default_community = "apc.communities.example.com"
+# rekey_enabled = no
+# realm_lifetime = 0
+}
+
+# 'username%realm'
+#
+realm realmpercent {
+ format = suffix
+ delimiter = "%"
+}
+
+#
+# 'domain\user'
+#
+realm ntdomain {
+ format = prefix
+ delimiter = "\\"
+}
diff --git a/raddb/mods-available/redis b/raddb/mods-available/redis
new file mode 100644
index 0000000..64789f5
--- /dev/null
+++ b/raddb/mods-available/redis
@@ -0,0 +1,99 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Configuration file for the "redis" module. This module does nothing
+# Other than provide connections to a redis database, and a %{redis: ...}
+# expansion.
+#
+redis {
+ # Host where the redis server is located.
+ # We recommend using ONLY 127.0.0.1 !
+ server = 127.0.0.1
+
+ # Select the Redis logical database having the specified zero-based numeric index.
+# database = 0
+
+ # The default port.
+ port = 6379
+
+ # The password used to authenticate to the server.
+ # We recommend using a strong password.
+# password = thisisreallysecretandhardtoguess
+
+ # Set connection and query timeout for rlm_redis
+ query_timeout = 5
+
+ #
+ # Information for the connection pool. The configuration items
+ # below are the same for all modules which use the new
+ # connection pool.
+ #
+ pool {
+ # 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
+ # web service being available.
+ start = ${thread[pool].start_servers}
+
+ # Minimum number of connections to keep open
+ min = ${thread[pool].min_spare_servers}
+
+ # 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.
+ max = ${thread[pool].max_servers}
+
+ # 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.
+ spare = ${thread[pool].max_spare_servers}
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ uses = 0
+
+ # 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.
+ retry_delay = 30
+
+ # The lifetime (in seconds) of the connection
+ #
+ # NOTE: A setting of 0 means infinite (no limit).
+ lifetime = 86400
+
+ # The pool is checked for free connections every
+ # "cleanup_interval". If there are free connections,
+ # then one of them is closed.
+ cleanup_interval = 300
+
+ # 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).
+ idle_timeout = 600
+
+ # 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.
+ }
+}
diff --git a/raddb/mods-available/rediswho b/raddb/mods-available/rediswho
new file mode 100644
index 0000000..d303550
--- /dev/null
+++ b/raddb/mods-available/rediswho
@@ -0,0 +1,52 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Configuration file for the "rediswho" module.
+#
+# This module tracks the last set of login sessions for a user.
+#
+rediswho {
+ # REDIS instance to use (from mods-available/redis)
+ #
+ # If you have multiple redis instances, such as "redis redis1 {...}",
+ # use the *instance* name here: redis1.
+# redis_module_instance = redis
+
+ # How many sessions to keep track of per user.
+ # If there are more than this number, older sessions are deleted.
+ trim_count = 15
+
+ # Expiry time in seconds. Any sessions which have not received
+ # an update in this time will be automatically expired.
+ expire_time = 86400
+
+ #
+ # Each subsection contains insert / trim / expire queries.
+ # The subsections are named after the contents of the
+ # Acct-Status-Type attribute. See dictionary.rfc2866 for names
+ # of the various Acct-Status-Type values, or look at the output
+ # of debug mode.
+ #
+ # This module supports *any* Acct-Status-Type. Just add a subsection
+ # of the appropriate name, along with insert / trim / expire queries.
+ #
+ Start {
+ insert = "LPUSH %{User-Name} %l,%{Acct-Session-Id},%{NAS-IP-Address},%{Acct-Session-Time},%{Framed-IP-Address},%{%{Acct-Input-Gigawords}:-0},%{%{Acct-Output-Gigawords}:-0},%{%{Acct-Input-Octets}:-0},%{%{Acct-Output-Octets}:-0}"
+ trim = "LTRIM %{User-Name} 0 ${..trim_count}"
+ expire = "EXPIRE %{User-Name} ${..expire_time}"
+ }
+
+ Interim-Update {
+ insert = "LPUSH %{User-Name} %l,%{Acct-Session-Id},%{NAS-IP-Address},%{Acct-Session-Time},%{Framed-IP-Address},%{%{Acct-Input-Gigawords}:-0},%{%{Acct-Output-Gigawords}:-0},%{%{Acct-Input-Octets}:-0},%{%{Acct-Output-Octets}:-0}"
+ trim = "LTRIM %{User-Name} 0 ${..trim_count}"
+ expire = "EXPIRE %{User-Name} ${..expire_time}"
+ }
+
+ Stop {
+ insert = "LPUSH %{User-Name} %l,%{Acct-Session-Id},%{NAS-IP-Address},%{Acct-Session-Time},%{Framed-IP-Address},%{%{Acct-Input-Gigawords}:-0},%{%{Acct-Output-Gigawords}:-0},%{%{Acct-Input-Octets}:-0},%{%{Acct-Output-Octets}:-0}"
+ trim = "LTRIM %{User-Name} 0 ${..trim_count}"
+ expire = "EXPIRE %{User-Name} ${..expire_time}"
+ }
+}
diff --git a/raddb/mods-available/replicate b/raddb/mods-available/replicate
new file mode 100644
index 0000000..3ba88c1
--- /dev/null
+++ b/raddb/mods-available/replicate
@@ -0,0 +1,42 @@
+# Replicate packet(s) to a home server.
+#
+# This module will open a new socket for each packet, and "clone"
+# the incoming packet to the destination realm (i.e. home server).
+# These packets are only sent to UDP home servers. TCP and TLS
+# are not supported.
+#
+# Use it by setting "Replicate-To-Realm = name" in the control list,
+# just like Proxy-To-Realm. The configurations for the two attributes
+# are identical. The realm must exist, the home_server_pool must exist,
+# and the home_server must exist.
+#
+# The only difference is that the "replicate" module sends requests
+# and does not expect a reply. Any reply is ignored.
+#
+# Both Replicate-To-Realm and Proxy-To-Realm can be used at the same time.
+#
+# To use this module, list "replicate" in the "authorize" or
+# "accounting" section. Then, ensure that Replicate-To-Realm is set.
+# The contents of the "packet" attribute list will be sent to the
+# home server. The usual load-balancing, etc. features of the home
+# server will be used.
+#
+# "radmin" can be used to mark home servers alive/dead, in order to
+# enable/disable replication to specific servers.
+#
+# Packets can be replicated to multiple destinations. Just set
+# Replicate-To-Realm multiple times. One packet will be sent for
+# each of the Replicate-To-Realm attribute in the "control" list.
+#
+# If no packets are sent, the module returns "noop". If at least one
+# packet is sent, the module returns "ok". If an error occurs, the
+# module returns "fail"
+#
+# Note that replication does NOT change any of the packet statistics.
+# If you use "radmin" to look at the statistics for a home server,
+# the replicated packets will cause NO counters to increment. This
+# is not a bug, this is how replication works.
+#
+replicate {
+
+}
diff --git a/raddb/mods-available/rest b/raddb/mods-available/rest
new file mode 100644
index 0000000..2c33acb
--- /dev/null
+++ b/raddb/mods-available/rest
@@ -0,0 +1,301 @@
+rest {
+ #
+ # This subsection configures the tls related items
+ # that control how FreeRADIUS connects to a HTTPS
+ # server.
+ #
+ tls {
+ # Certificate Authorities:
+ # "ca_file" (libcurl option CURLOPT_ISSUERCERT).
+ # File containing a single CA, which is the issuer of the server
+ # certificate.
+ # "ca_info_file" (libcurl option CURLOPT_CAINFO).
+ # File containing a bundle of certificates, which allow to handle
+ # certificate chain validation.
+ # "ca_path" (libcurl option CURLOPT_CAPATH).
+ # Directory holding CA certificates to verify the peer with.
+# ca_file = ${certdir}/cacert.pem
+# ca_info_file = ${certdir}/cacert_bundle.pem
+# ca_path = ${certdir}
+
+# certificate_file = /path/to/radius.crt
+# private_key_file = /path/to/radius.key
+# private_key_password = "supersecret"
+# random_file = /dev/urandom
+
+ # Server certificate verification requirements. Can be:
+ # "no" (don't even bother trying)
+ # "yes" (verify the cert was issued by one of the
+ # trusted CAs)
+ #
+ # The default is "yes"
+# check_cert = yes
+
+ # Server certificate CN verification requirements. Can be:
+ # "no" (don't even bother trying)
+ # "yes" (verify the CN in the certificate matches the host
+ # in the URI)
+ #
+ # The default is "yes"
+# check_cert_cn = yes
+ }
+
+ # rlm_rest will open a connection to the server specified in connect_uri
+ # to populate the connection cache, ready for the first request.
+ # The server will not start if the server specified is unreachable.
+ #
+ # If you wish to disable this pre-caching and reachability check,
+ # comment out the configuration item below.
+ connect_uri = "http://127.0.0.1/"
+
+ #
+ # How long before new connection attempts timeout, defaults to 4.0 seconds.
+ #
+# connect_timeout = 4.0
+
+ #
+ # Specify HTTP protocol version to use. one of '1.0', '1.1', '2.0', '2.0+auto',
+ # '2.0+tls' or 'default'. (libcurl option CURLOPT_HTTP_VERSION)
+ #
+# http_negotiation = 1.1
+
+ #
+ # The following config items can be used in each of the sections.
+ # The sections themselves reflect the sections in the server.
+ # For example if you list rest in the authorize section of a virtual server,
+ # the settings from the authorize section here will be used.
+ #
+ # The following config items may be listed in any of the sections:
+ # uri - to send the request to.
+ # method - HTTP method to use, one of 'get', 'post', 'put', 'patch',
+ # 'delete' or any custom HTTP method.
+ # body - The format of the HTTP body sent to the remote server.
+ # May be 'none', 'post' or 'json', defaults to 'none'.
+ # attr_num - If true, the attribute number is supplied for each attribute.
+ # Defaults to false.
+ # raw_value - If true, enumerated attribute values are provided as numeric
+ # values. Defaults to false.
+ # data - Send custom freeform data in the HTTP body. Content-type
+ # may be specified with 'body'. Will be expanded.
+ # Values from expansion will not be escaped, this should be
+ # done using the appropriate xlat method e.g. %{urlencode:<attr>}.
+ # force_to - Force the response to be decoded with this decoder.
+ # May be 'plain' (creates reply:REST-HTTP-Body), 'post'
+ # or 'json'.
+ # tls - TLS settings for HTTPS.
+ # auth - HTTP auth method to use, one of 'none', 'srp', 'basic',
+ # 'digest', 'digest-ie', 'gss-negotiate', 'ntlm',
+ # 'ntlm-winbind', 'any', 'safe'. defaults to 'none'.
+ # username - User to authenticate as, will be expanded.
+ # password - Password to use for authentication, will be expanded.
+ # require_auth - Require HTTP authentication.
+ # timeout - HTTP request timeout in seconds, defaults to 4.0.
+ # chunk - Chunk size to use. If set, HTTP chunked encoding is used to
+ # send data to the REST server. Make sure that this is large
+ # enough to fit your largest attribute value's text
+ #  representation.
+ # A number like 8192 is good.
+ #
+ # Additional HTTP headers may be specified with control:REST-HTTP-Header.
+ # The values of those attributes should be in the format:
+ #
+ # control:REST-HTTP-Header := "<HTTP attribute>: <value>"
+ #
+ # The control:REST-HTTP-Header attributes will be consumed
+ # (i.e. deleted) after each call to the rest module, and each
+ # %{rest:} expansion. This is so that headers from one REST
+ # call do not affect headers from a different REST call.
+ #
+ # Body encodings are the same for requests and responses
+ #
+ # POST - All attributes and values are urlencoded
+ # [outer.][<list>:]<attribute0>=<value0>&[outer.][<list>:]<attributeN>=<valueN>
+ #
+ # JSON - All attributes and values are escaped according to the JSON specification
+ # - attribute Name of the attribute.
+ # - attr_num Number of the attribute. Only available if the configuration item
+ # 'attr_num' is enabled.
+ # - type Type of the attribute (e.g. "integer", "string", "ipaddr", "octets", ...).
+ # - value Attribute value, for enumerated attributes the human readable value is
+ # provided and not the numeric value (Depends on the 'raw_value' config item).
+ # {
+ # "<attribute0>":{
+ # "attr_num":<attr_num0>,
+ # "type":"<type0>",
+ # "value":[<value0>,<value1>,<valueN>]
+ # },
+ # "<attribute1>":{
+ # "attr_num":<attr_num1>,
+ # "type":"<type1>",
+ # "value":[...]
+ # },
+ # "<attributeN>":{
+ # "attr_num":<attr_numN>,
+ # "type":"<typeN>",
+ # "value":[...]
+ # },
+ # }
+ #
+ # The response format adds three optional fields:
+ # - do_xlat If true, any values will be xlat expanded. Defaults to true.
+ # - is_json If true, any nested JSON data will be copied to the attribute
+ # in string form. Defaults to true.
+ # - op Controls how the attribute is inserted into the target list.
+ # Defaults to ':='. To create multiple attributes from multiple
+ # values, this should be set to '+=', otherwise only the last
+ # value will be used, and it will be assigned to a single
+ # attribute.
+ # {
+ # "<attribute0>":{
+ # "is_json":<bool>,
+ # "do_xlat":<bool>,
+ # "op":"<operator>",
+ # "value":[<value0>,<value1>,<valueN>]
+ # },
+ # "<attribute1>":"value",
+ # "<attributeN>":{
+ # "value":[<value0>,<value1>,<valueN>],
+ # "op":"+="
+ # }
+ # }
+
+ #
+ # Module return codes are determined by HTTP response codes. These vary depending on the
+ # section.
+ #
+ # If the body is processed and found to be malformed or unsupported fail will be returned.
+ # If the body is processed and found to contain attribute updated will be returned,
+ # except in the case of a 401 code.
+ #
+
+ # Authorize/Authenticate
+ #
+ # Code Meaning Process body Module code
+ # 404 not found no notfound
+ # 410 gone no notfound
+ # 403 forbidden no userlock
+ # 401 unauthorized yes reject
+ # 204 no content no ok
+ # 2xx successful yes ok/updated
+ # 5xx server error no fail
+ # xxx - no invalid
+ #
+ # The status code is held in %{reply:REST-HTTP-Status-Code}.
+ #
+ authorize {
+ uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=authorize"
+ method = 'get'
+ tls = ${..tls}
+ }
+ authenticate {
+ uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=authenticate"
+ method = 'get'
+ tls = ${..tls}
+ }
+
+ # Preacct/Accounting/Post-auth/Pre-Proxy/Post-Proxy
+ #
+ # Code Meaning Process body Module code
+ # 204 no content no ok
+ # 2xx successful yes ok/updated
+ # 5xx server error no fail
+ # xxx - no invalid
+ preacct {
+ uri = "${..connect_uri}/user/%{User-Name}/sessions/%{Acct-Unique-Session-ID}?action=preacct"
+ method = 'post'
+ tls = ${..tls}
+ }
+ accounting {
+ uri = "${..connect_uri}/user/%{User-Name}/sessions/%{Acct-Unique-Session-ID}?action=accounting"
+ method = 'post'
+ tls = ${..tls}
+ }
+ post-auth {
+ uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=post-auth"
+ method = 'post'
+ tls = ${..tls}
+ }
+ pre-proxy {
+ uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=pre-proxy"
+ method = 'post'
+ tls = ${..tls}
+ }
+ post-proxy {
+ uri = "${..connect_uri}/user/%{User-Name}/mac/%{Called-Station-ID}?action=post-proxy"
+ method = 'post'
+ tls = ${..tls}
+ }
+
+ # Options for calling rest xlats
+ # uri and method will be derived from the string provided to the xlat
+ xlat {
+ #
+ # The whole string passed to a REST xlat is URI encoded.
+ # With body_uri_encode = yes, any body data will remain encoded.
+ # With body_uri_encode = no, the body data will be decoded and sent as provided.
+ #
+ body_uri_encode = yes
+ tls = ${..tls}
+ }
+
+ #
+ # The connection pool is used to pool outgoing connections.
+ #
+ pool {
+ # 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
+ # web service being available.
+ start = ${thread[pool].start_servers}
+
+ # Minimum number of connections to keep open
+ min = ${thread[pool].min_spare_servers}
+
+ # 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.
+ max = ${thread[pool].max_servers}
+
+ # 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.
+ spare = ${thread[pool].max_spare_servers}
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ uses = 0
+
+ # 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.
+ retry_delay = 30
+
+ # The lifetime (in seconds) of the connection
+ lifetime = 0
+
+ # idle timeout (in seconds). A connection which is
+ # unused for this length of time will be closed.
+ idle_timeout = 60
+
+ # 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.
+ }
+}
diff --git a/raddb/mods-available/smbpasswd b/raddb/mods-available/smbpasswd
new file mode 100644
index 0000000..d5ad2a0
--- /dev/null
+++ b/raddb/mods-available/smbpasswd
@@ -0,0 +1,16 @@
+# -*- text -*-
+#
+# $Id$
+
+# An example configuration for using /etc/smbpasswd.
+#
+# See the "passwd" file for documentation on the configuration items
+# for this module.
+#
+passwd smbpasswd {
+ filename = /etc/smbpasswd
+ format = "*User-Name::LM-Password:NT-Password:SMB-Account-CTRL-TEXT::"
+ hash_size = 100
+ ignore_nislike = no
+ allow_multiple_keys = no
+}
diff --git a/raddb/mods-available/smsotp b/raddb/mods-available/smsotp
new file mode 100644
index 0000000..c594a9a
--- /dev/null
+++ b/raddb/mods-available/smsotp
@@ -0,0 +1,94 @@
+# -*- text -*-
+#
+# $Id$
+
+# SMS One-Time Password system
+#
+# This module extends FreeRADIUS with a socket interface to create and
+# validate One-Time-Passwords. The program for that creates the socket
+# and interacts with this module is not included here.
+#
+# The module does not check the User-Password, this should be done with
+# the "pap" module. See the example below.
+#
+# The module must be used in the "authorize" section to set
+# Auth-Type properly. The first time through, the module is called
+# in the "authenticate" section to authenticate the user password, and
+# to send the challenge. The second time through, it authenticates
+# the response to the challenge. e.g.:
+#
+# authorize {
+# ...
+# smsotp
+# ...
+# }
+#
+# authenticate {
+# ...
+# Auth-Type smsotp {
+# pap
+# smsotp
+# }
+#
+# Auth-Type smsotp-reply {
+# smsotp
+# }
+# ...
+# }
+#
+smsotp {
+ # The location of the socket.
+ socket = "/var/run/smsotp_socket"
+
+ # Defines the challenge message that will be send to the
+ # NAS. Default is "Enter Mobile PIN" }
+ challenge_message = "Enter Mobile PIN:"
+
+ # Defines the Auth-Type section that is run for the response to
+ # the challenge. Default is "smsotp-reply".
+ challenge_type = "smsotp-reply"
+
+ # Control how many sockets are used to talk to the SMSOTPd
+ #
+ pool {
+ # Number of connections to start
+ start = 5
+
+ # Minimum number of connections to keep open
+ min = 4
+
+ # Maximum number of connections
+ #
+ # If these connections are all in use and a new one
+ # is requested, the request will NOT get a connection.
+ max = 10
+
+ # Spare connections to be left idle
+ #
+ # NOTE: Idle connections WILL be closed if "idle_timeout"
+ # is set.
+ spare = 3
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ uses = 0
+
+ # The lifetime (in seconds) of the connection
+ lifetime = 0
+
+ # idle timeout (in seconds). A connection which is
+ # unused for this length of time will be closed.
+ idle_timeout = 60
+
+ # 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.
+ }
+}
diff --git a/raddb/mods-available/soh b/raddb/mods-available/soh
new file mode 100644
index 0000000..d125ce4
--- /dev/null
+++ b/raddb/mods-available/soh
@@ -0,0 +1,4 @@
+# SoH module
+soh {
+ dhcp = yes
+}
diff --git a/raddb/mods-available/sometimes b/raddb/mods-available/sometimes
new file mode 100644
index 0000000..3a96622
--- /dev/null
+++ b/raddb/mods-available/sometimes
@@ -0,0 +1,12 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# The "sometimes" module is here for debugging purposes. Each instance
+# randomly returns the configured result, or "noop".
+#
+# It is based on the "always" module.
+sometimes {
+ rcode = fail
+}
diff --git a/raddb/mods-available/sql b/raddb/mods-available/sql
new file mode 100644
index 0000000..0f435ad
--- /dev/null
+++ b/raddb/mods-available/sql
@@ -0,0 +1,376 @@
+# -*- text -*-
+##
+## mods-available/sql -- SQL modules
+##
+## $Id$
+
+######################################################################
+#
+# Configuration for the SQL module
+#
+# The database schemas and queries are located in subdirectories:
+#
+# sql/<DB>/main/schema.sql Schema
+# sql/<DB>/main/queries.conf Authorisation and Accounting queries
+#
+# Where "DB" is mysql, mssql, oracle, or postgresql.
+#
+# The name used to query SQL is sql_user_name, which is set in the file
+#
+# raddb/mods-config/sql/main/${dialect}/queries.conf
+#
+# If you are using realms, that configuration should be changed to use
+# the Stripped-User-Name attribute. See the comments around sql_user_name
+# for more information.
+#
+
+sql {
+ #
+ # The dialect of SQL being used.
+ #
+ # Allowed dialects are:
+ #
+ # mssql
+ # mysql
+ # oracle
+ # postgresql
+ # sqlite
+ # mongo
+ #
+ dialect = "sqlite"
+
+ #
+ # The driver module used to execute the queries. Since we
+ # don't know which SQL drivers are being used, the default is
+ # "rlm_sql_null", which just logs the queries to disk via the
+ # "logfile" directive, below.
+ #
+ # In order to talk to a real database, delete the next line,
+ # and uncomment the one after it.
+ #
+ # If the dialect is "mssql", then the driver should be set to
+ # one of the following values, depending on your system:
+ #
+ # rlm_sql_db2
+ # rlm_sql_firebird
+ # rlm_sql_freetds
+ # rlm_sql_iodbc
+ # rlm_sql_unixodbc
+ #
+ driver = "rlm_sql_null"
+# driver = "rlm_sql_${dialect}"
+
+ #
+ # Driver-specific subsections. They will only be loaded and
+ # used if "driver" is something other than "rlm_sql_null".
+ # When a real driver is used, the relevant driver
+ # configuration section is loaded, and all other driver
+ # configuration sections are ignored.
+ #
+ sqlite {
+ # Path to the sqlite database
+ filename = "/tmp/freeradius.db"
+
+ # How long to wait for write locks on the database to be
+ # released (in ms) before giving up.
+ busy_timeout = 200
+
+ # If the file above does not exist and bootstrap is set
+ # a new database file will be created, and the SQL statements
+ # contained within the bootstrap file will be executed.
+ bootstrap = "${modconfdir}/${..:name}/main/sqlite/schema.sql"
+ }
+
+ mysql {
+ # If any of the files below are set, TLS encryption is enabled
+ tls {
+ ca_file = "/etc/ssl/certs/my_ca.crt"
+ ca_path = "/etc/ssl/certs/"
+ certificate_file = "/etc/ssl/certs/private/client.crt"
+ private_key_file = "/etc/ssl/certs/private/client.key"
+ cipher = "DHE-RSA-AES256-SHA:AES128-SHA"
+
+ tls_required = yes
+ tls_check_cert = no
+ tls_check_cert_cn = no
+ }
+
+ # If yes, (or auto and libmysqlclient reports warnings are
+ # available), will retrieve and log additional warnings from
+ # the server if an error has occured. Defaults to 'auto'
+ warnings = auto
+ }
+
+ postgresql {
+
+ # unlike MySQL, which has a tls{} connection configuration, postgresql
+ # uses its connection parameters - see the radius_db option below in
+ # this file
+
+ # Send application_name to the postgres server
+ # Only supported in PG 9.0 and greater. Defaults to no.
+ send_application_name = yes
+
+ #
+ # The default application name is "FreeRADIUS - .." with the current version.
+ # The application name can be customized here to any non-zero value.
+ #
+# application_name = ""
+ }
+
+ #
+ # Configuration for Mongo.
+ #
+ # Note that the Mongo driver is experimental. The FreeRADIUS developers
+ # are unable to help with the syntax of the Mongo queries. Please see
+ # the Mongo documentation for that syntax.
+ #
+ # The Mongo driver supports only the following methods:
+ #
+ # aggregate
+ # findAndModify
+ # findOne
+ # insert
+ #
+ # For examples, see the query files:
+ #
+ # raddb/mods-config/sql/main/mongo/queries.conf
+ # raddb/mods-config/sql/main/ippool/queries.conf
+ #
+ # In order to use findAndModify with an aggretation pipleline, make
+ # sure that you are running MongoDB version 4.2 or greater. FreeRADIUS
+ # assumes that the paramaters passed to the methods are supported by the
+ # version of MongoDB which it is connected to.
+ #
+ mongo {
+ #
+ # The application name to use.
+ #
+ appname = "freeradius"
+
+ #
+ # The TLS parameters here map directly to the Mongo TLS configuration
+ #
+ tls {
+ certificate_file = /path/to/file
+ certificate_password = "password"
+ ca_file = /path/to/file
+ ca_dir = /path/to/directory
+ crl_file = /path/to/file
+ weak_cert_validation = false
+ allow_invalid_hostname = false
+ }
+ }
+
+ # Connection info:
+ #
+# server = "localhost"
+# port = 3306
+# login = "radius"
+# password = "radpass"
+
+ # Connection info for Mongo
+ # Authentication Without SSL
+ # server = "mongodb://USER:PASSWORD@192.16.0.2:PORT/DATABASE?authSource=admin&ssl=false"
+
+ # Authentication With SSL
+ # server = "mongodb://USER:PASSWORD@192.16.0.2:PORT/DATABASE?authSource=admin&ssl=true"
+
+ # Authentication with Certificate
+ # Use this command for retrieve Derived username:
+ # openssl x509 -in mycert.pem -inform PEM -subject -nameopt RFC2253
+ # server = mongodb://<DERIVED USERNAME>@192.168.0.2:PORT/DATABASE?authSource=$external&ssl=true&authMechanism=MONGODB-X509
+
+ # Database table configuration for everything except Oracle
+ radius_db = "radius"
+
+ # If you are using Oracle then use this instead
+# radius_db = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SID=your_sid)))"
+
+ # If you're using postgresql this can also be used instead of the connection info parameters
+# radius_db = "dbname=radius host=localhost user=radius password=raddpass"
+
+ # Postgreql doesn't take tls{} options in its module config like mysql does - if you want to
+ # use SSL connections then use this form of connection info parameter
+# radius_db = "host=localhost port=5432 dbname=radius user=radius password=raddpass sslmode=verify-full sslcert=/etc/ssl/client.crt sslkey=/etc/ssl/client.key sslrootcert=/etc/ssl/ca.crt"
+
+ # If you want both stop and start records logged to the
+ # same SQL table, leave this as is. If you want them in
+ # different tables, put the start table in acct_table1
+ # and stop table in acct_table2
+ acct_table1 = "radacct"
+ acct_table2 = "radacct"
+
+ # Allow for storing data after authentication
+ postauth_table = "radpostauth"
+
+ # Tables containing 'check' items
+ authcheck_table = "radcheck"
+ groupcheck_table = "radgroupcheck"
+
+ # Tables containing 'reply' items
+ authreply_table = "radreply"
+ groupreply_table = "radgroupreply"
+
+ # Table to keep group info
+ usergroup_table = "radusergroup"
+
+ # If set to 'yes' (default) we read the group tables unless Fall-Through = no in the reply table.
+ # If set to 'no' we do not read the group tables unless Fall-Through = yes in the reply table.
+# read_groups = yes
+
+ # If set to 'yes' (default) we read profiles unless Fall-Through = no in the groupreply table.
+ # If set to 'no' we do not read profiles unless Fall-Through = yes in the groupreply table.
+# read_profiles = yes
+
+ # Remove stale session if checkrad does not see a double login
+ delete_stale_sessions = yes
+
+ # Write SQL queries to a logfile. This is potentially useful for tracing
+ # issues with authorization queries. See also "logfile" directives in
+ # mods-config/sql/main/*/queries.conf. You can enable per-section logging
+ # by enabling "logfile" there, or global logging by enabling "logfile" here.
+ #
+ # Per-section logging can be disabled by setting "logfile = ''"
+# logfile = ${logdir}/sqllog.sql
+
+ # Set the maximum query duration and connection timeout
+ # for rlm_sql_mysql.
+# query_timeout = 5
+
+ # As of v3, the "pool" section has replaced the
+ # following v2 configuration items:
+ #
+ # num_sql_socks
+ # connect_failure_retry_delay
+ # lifetime
+ # max_queries
+
+ #
+ # The connection pool is used to pool outgoing connections.
+ #
+ # When the server is not threaded, the connection pool
+ # limits are ignored, and only one connection is used.
+ #
+ # If you want to have multiple SQL modules re-use the same
+ # connection pool, use "pool = name" instead of a "pool"
+ # section. e.g.
+ #
+ # sql sql1 {
+ # ...
+ # pool {
+ # ...
+ # }
+ # }
+ #
+ # # sql2 will use the connection pool from sql1
+ # sql sql2 {
+ # ...
+ # pool = sql1
+ # }
+ #
+ pool {
+ # 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
+ # database being available.
+ start = ${thread[pool].start_servers}
+
+ # Minimum number of connections to keep open
+ min = ${thread[pool].min_spare_servers}
+
+ # 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.
+ max = ${thread[pool].max_servers}
+
+ # 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.
+ spare = ${thread[pool].max_spare_servers}
+
+ # Number of uses before the connection is closed
+ #
+ # 0 means "infinite"
+ uses = 0
+
+ # 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.
+ retry_delay = 30
+
+ # The lifetime (in seconds) of the connection
+ lifetime = 0
+
+ # idle timeout (in seconds). A connection which is
+ # unused for this length of time will be closed.
+ idle_timeout = 60
+
+ # 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.
+
+ # Maximum number of times an operation can be retried
+ # if it returns an error which indicates the connection
+ # needs to be restarted. This includes timeouts.
+ max_retries = 5
+ }
+
+ # Set to 'yes' to read radius clients from the database ('nas' table)
+ # Clients will ONLY be read on server startup.
+ #
+ # A client can be link to a virtual server via the SQL
+ # module. This link is done via the following process:
+ #
+ # If there is no listener in a virtual server, SQL clients
+ # are added to the global list for that virtual server.
+ #
+ # If there is a listener, and the first listener does not
+ # have a "clients=..." configuration item, SQL clients are
+ # added to the global list.
+ #
+ # If there is a listener, and the first one does have a
+ # "clients=..." configuration item, SQL clients are added to
+ # that list. The client { ...} ` configured in that list are
+ # also added for that listener.
+ #
+ # The only issue is if you have multiple listeners in a
+ # virtual server, each with a different client list, then
+ # the SQL clients are added only to the first listener.
+ #
+# read_clients = yes
+
+ # Table to keep radius client info
+ client_table = "nas"
+
+ #
+ # The group attribute specific to this instance of rlm_sql
+ #
+
+ # This entry should be used for additional instances (sql foo {})
+ # of the SQL module.
+# group_attribute = "${.:instance}-SQL-Group"
+
+ # This entry should be used for the default instance (sql {})
+ # of the SQL module.
+ group_attribute = "SQL-Group"
+
+ # Read database-specific queries
+ $INCLUDE ${modconfdir}/${.:name}/main/${dialect}/queries.conf
+}
diff --git a/raddb/mods-available/sql_map b/raddb/mods-available/sql_map
new file mode 100644
index 0000000..93b2636
--- /dev/null
+++ b/raddb/mods-available/sql_map
@@ -0,0 +1,49 @@
+# Configuration for the SQL based Map (rlm_sql_map)
+sql_map {
+ # SQL instance to use (from mods-available/sql)
+ #
+ # If you have multiple sql instances, such as "sql sql1 {...}",
+ # use the *instance* name here: sql1.
+ sql_module_instance = "sql"
+
+ # This is duplicative of info available in the SQL module, but
+ # we have to list it here as we do not yet support nested
+ # reference expansions.
+ dialect = "mysql"
+
+ # Name of the check item attribute to be used as a key in the SQL queries
+ query = "SELECT ... FROM ... "
+
+ #
+ # Mapping of SQL columns to RADIUS dictionary attributes.
+ #
+
+ # WARNING: Although this format is almost identical to the unlang
+ # update section format, it does *NOT* mean that you can use other
+ # unlang constructs in module configuration files.
+ #
+ # Configuration items are in the format:
+ # <radius attr> <op> <sql column number>
+ #
+ # Where:
+ # <radius attr>: Is the destination RADIUS attribute
+ # with any valid list and request qualifiers.
+ # <op>: Is any assignment attribute (=, :=, +=, -=).
+ # <column num>: The column number (not name), starting from 0
+ #
+ # Request and list qualifiers may also be placed after the 'update'
+ # section name to set defaults destination requests/lists
+ # for unqualified RADIUS attributes.
+ #
+ update {
+ control:Password-With-Header += 0
+# control:NT-Password := 1
+# reply:Reply-Message := 2
+# reply:Tunnel-Type := 3
+# reply:Tunnel-Medium-Type := 4
+# reply:Tunnel-Private-Group-ID := 5
+ }
+
+ # If the 'query' results in multiple rows, it creates the <radius attr>[*] array entry.
+# multiple_rows = yes
+}
diff --git a/raddb/mods-available/sqlcounter b/raddb/mods-available/sqlcounter
new file mode 100644
index 0000000..a2b206e
--- /dev/null
+++ b/raddb/mods-available/sqlcounter
@@ -0,0 +1,122 @@
+# Rather than maintaining separate (GDBM) databases of
+# accounting info for each counter, this module uses the data
+# stored in the raddacct table by the sql modules. This
+# module NEVER does any database INSERTs or UPDATEs. It is
+# totally dependent on the SQL module to process Accounting
+# packets.
+#
+# The sql-module-instance' parameter holds the instance of the sql
+# module to use when querying the SQL database. Normally it
+# is just "sql". If you define more and one SQL module
+# instance (usually for failover situations), you can
+# specify which module has access to the Accounting Data
+# (radacct table).
+#
+# The 'reset' parameter defines when the counters are all
+# reset to zero. It can be hourly, daily, weekly, monthly or
+# never. It can also be user defined. It should be of the
+# form:
+# num[hdwm] where:
+# h: hours, d: days, w: weeks, m: months
+# If the letter is ommited days will be assumed. In example:
+# reset = 10h (reset every 10 hours)
+# reset = 12 (reset every 12 days)
+#
+# The 'reset_day' parameter defines which day of the month the
+# 'monthly' counter should be reset; valid values are 1 to 28.
+#
+# The 'key' parameter specifies the unique identifier for the
+# counter records (usually 'User-Name').
+#
+# The 'query' parameter specifies the SQL query used to get
+# the current Counter value from the database. There are four
+# parameters that can be used in the query:
+#
+# %%b unix time value of beginning of reset period.
+# %%e unix time value of end of reset period.
+# %%k value of 'key' parameter.
+# %%r day of month the counter should be reset.
+#
+# The 'check_name' parameter is the name of the 'check'
+# attribute to use to access the counter in the 'users' file
+# or SQL radcheck or radgroupcheck tables.
+#
+# DEFAULT Max-Daily-Session > 3600, Auth-Type = Reject
+# Reply-Message = "You've used up more than one hour today"
+#
+# The "dailycounter" (or any other sqlcounter module) should be added
+# to "post-auth" section. It will then update the Session-Timeout
+# attribute in the reply. If there is no Session-Timeout attribute,
+# the module will add one. If there is an attribute, the sqlcounter
+# module will make sure that the value is no higher than the limit.
+#
+sqlcounter dailycounter {
+ sql_module_instance = sql
+ dialect = ${modules.sql.dialect}
+
+ counter_name = Daily-Session-Time
+ check_name = Max-Daily-Session
+ reply_name = Session-Timeout
+
+ key = User-Name
+ reset = daily
+
+ $INCLUDE ${modconfdir}/sql/counter/${dialect}/${.:instance}.conf
+}
+
+sqlcounter weeklycounter {
+ sql_module_instance = sql
+ dialect = ${modules.sql.dialect}
+
+ counter_name = Weekly-Session-Time
+ check_name = Max-Weekly-Session
+ reply_name = Session-Timeout
+
+ key = User-Name
+ reset = weekly
+
+ $INCLUDE ${modconfdir}/sql/counter/${dialect}/${.:instance}.conf
+}
+
+sqlcounter monthlycounter {
+ sql_module_instance = sql
+ dialect = ${modules.sql.dialect}
+
+ counter_name = Monthly-Session-Time
+ check_name = Max-Monthly-Session
+ reply_name = Session-Timeout
+ key = User-Name
+ reset = monthly
+ reset_day = 1
+
+ $INCLUDE ${modconfdir}/sql/counter/${dialect}/${.:instance}.conf
+}
+
+sqlcounter noresetcounter {
+ sql_module_instance = sql
+ dialect = ${modules.sql.dialect}
+
+ counter_name = Max-All-Session-Time
+ check_name = Max-All-Session
+ key = User-Name
+ reset = never
+
+ $INCLUDE ${modconfdir}/sql/counter/${dialect}/${.:instance}.conf
+}
+
+#
+# Set an account to expire T seconds after first login.
+# Requires the Expire-After attribute to be set, in seconds.
+# You may need to edit raddb/dictionary to add the Expire-After
+# attribute.
+sqlcounter expire_on_login {
+ sql_module_instance = sql
+ dialect = ${modules.sql.dialect}
+
+ counter_name = Expire-After-Initial-Login
+ check_name = Expire-After
+ key = User-Name
+ reset = never
+
+ $INCLUDE ${modconfdir}/sql/counter/${dialect}/${.:instance}.conf
+}
diff --git a/raddb/mods-available/sqlippool b/raddb/mods-available/sqlippool
new file mode 100644
index 0000000..f17a989
--- /dev/null
+++ b/raddb/mods-available/sqlippool
@@ -0,0 +1,109 @@
+# Configuration for the SQL based IP Pool module (rlm_sqlippool)
+#
+# The database schemas are available at:
+#
+# raddb/mods-config/sql/ippool/<DB>/schema.sql
+#
+# $Id$
+
+sqlippool {
+ # SQL instance to use (from mods-available/sql)
+ #
+ # If you have multiple sql instances, such as "sql sql1 {...}",
+ # use the *instance* name here: sql1.
+ sql_module_instance = "sql"
+
+ # This is duplicative of info available in the SQL module, but
+ # we have to list it here as we do not yet support nested
+ # reference expansions.
+ dialect = "mysql"
+
+ # Name of the check item attribute to be used as a key in the SQL queries
+ pool_name = "Pool-Name"
+
+ # SQL table to use for ippool range and lease info
+ ippool_table = "radippool"
+
+ # IP lease duration. (Leases expire even if Acct Stop packet is lost)
+ #
+ # Note that you SHOULD also set Session-Timeout to this value!
+ # That way the NAS will automatically kick the user offline when the
+ # lease expires.
+ #
+ lease_duration = 3600
+
+ #
+ # Timeout between each consecutive 'allocate_clear' queries (default: 1s)
+ # This will avoid having too many deadlock issues, especially on MySQL backend.
+ #
+ allocate_clear_timeout = 1
+
+ #
+ # The attribute to use for IP address assignment. The
+ # default is Framed-IP-Address. You can change this to any
+ # attribute which is IPv4 or IPv6.
+ #
+ # e.g. Framed-IPv6-Prefix, or Delegated-IPv6-Prefix.
+ #
+ # All of the default queries use this attribute_name. So you
+ # can do IPv6 address assignment simply by putting IPv6
+ # addresses into the pool, and changing the following line to
+ # "Framed-IPv6-Prefix"
+ #
+ # Note that you MUST use separate pools for each attribute. i.e. one pool
+ # for Framed-IP-Address, a different one for Framed-IPv6-prefix, etc.
+ #
+ # This means configuring separate "sqlippool" instances, and different
+ # "ippool_table" in SQL. Then, populate the pool with addresses and
+ # it will all just work.
+ #
+ attribute_name = Framed-IP-Address
+
+ #
+ # Assign the IP address, even if the above attribute already exists
+ # in the reply.
+ #
+# allow_duplicates = no
+
+ # The attribute in which an IP address hint may be supplied
+ req_attribute_name = Framed-IP-Address
+
+ # Attribute which should be considered unique per NAS
+ #
+ # Using NAS-Port gives behaviour similar to rlm_ippool. (And ACS)
+ # Using Calling-Station-Id works for NAS that send fixed NAS-Port
+ # ONLY change this if you know what you are doing!
+ pool_key = "%{NAS-Port}"
+ # pool_key = "%{Calling-Station-Id}"
+
+ ################################################################
+ #
+ # WARNING: MySQL (MyISAM) has certain limitations that means it can
+ # hand out the same IP address to 2 different users.
+ #
+ # We suggest using an SQL DB with proper transaction
+ # support, such as PostgreSQL, or using MySQL
+ # with InnoDB.
+ #
+ ################################################################
+
+ # These messages are added to the "control" items, as
+ # Module-Success-Message. They are not logged anywhere else,
+ # unlike previous versions. If you want to have them logged
+ # to a file, see the "linelog" module, and create an entry
+ # which writes Module-Success-Message message.
+ #
+ messages {
+ exists = "Existing IP: %{reply:${..attribute_name}} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
+
+ success = "Allocated IP: %{reply:${..attribute_name}} from %{control:${..pool_name}} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
+
+ clear = "Released IP %{request:${..attribute_name}} (did %{Called-Station-Id} cli %{Calling-Station-Id} user %{User-Name})"
+
+ failed = "IP Allocation FAILED from %{control:${..pool_name}} (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
+
+ nopool = "No ${..pool_name} defined (did %{Called-Station-Id} cli %{Calling-Station-Id} port %{NAS-Port} user %{User-Name})"
+ }
+
+ $INCLUDE ${modconfdir}/sql/ippool/${dialect}/queries.conf
+}
diff --git a/raddb/mods-available/sradutmp b/raddb/mods-available/sradutmp
new file mode 100644
index 0000000..3a2a0e5
--- /dev/null
+++ b/raddb/mods-available/sradutmp
@@ -0,0 +1,16 @@
+# -*- text -*-
+#
+# $Id$
+
+# "Safe" radutmp - does not contain caller ID, so it can be
+# world-readable, and radwho can work for normal users, without
+# exposing any information that isn't already exposed by who(1).
+#
+# This is another 'instance' of the radutmp module, but it is given
+# then name "sradutmp" to identify it later in the "accounting"
+# section.
+radutmp sradutmp {
+ filename = ${logdir}/sradutmp
+ permissions = 0644
+ caller_id = "no"
+}
diff --git a/raddb/mods-available/totp b/raddb/mods-available/totp
new file mode 100644
index 0000000..695365f
--- /dev/null
+++ b/raddb/mods-available/totp
@@ -0,0 +1,40 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# Time-based One-Time Passwords (TOTP)
+#
+# Defined in RFC 6238, and used in Google Authenticator.
+#
+# This module can only be used in the "authenticate" section.
+#
+# The Base32-encoded secret should be placed into:
+#
+# &control:TOTP-Secret
+#
+# The TOTP password entered by the user should be placed into:
+#
+# &request:TOTP-Password
+#
+# The module will return "ok" if the passwords match, and "fail"
+# if the passwords do not match.
+#
+# Note that this module will NOT interact with Google. The module is
+# intended to be used where the local administrator knows the TOTP
+# secret key, and user has an authenticator app on their phone.
+#
+# Note also that while you can use the Google "chart" APIs to
+# generate a QR code, doing this will give the secret to Google!
+#
+# Administrators should instead install a tool such as "qrcode"
+#
+# https://linux.die.net/man/1/qrencode
+#
+# and then run that locally to get an image.
+#
+#
+# The module takes no configuration items.
+#
+totp {
+}
diff --git a/raddb/mods-available/unbound b/raddb/mods-available/unbound
new file mode 100644
index 0000000..43fbce5
--- /dev/null
+++ b/raddb/mods-available/unbound
@@ -0,0 +1,13 @@
+unbound dns {
+ # Configuration for libunbound
+ # filename = "${raddbdir}/mods-config/unbound/default.conf"
+
+ # File to load resolver details from.
+ # Without this set unbound will query root servers
+ # resolvconf = "/etc/resolv.conf"
+
+ # Hosts entries to load
+ # hosts = "/etc/hosts"
+
+ # timeout = 3000
+}
diff --git a/raddb/mods-available/unix b/raddb/mods-available/unix
new file mode 100644
index 0000000..5165139
--- /dev/null
+++ b/raddb/mods-available/unix
@@ -0,0 +1,25 @@
+# -*- text -*-
+#
+# $Id$
+
+# Unix /etc/passwd style authentication
+#
+# This module calls the system functions to get the "known good"
+# password. This password is usually in the "crypt" form, and is
+# incompatible with CHAP, MS-CHAP, PEAP, etc.
+#
+# If passwords are in /etc/shadow, you will need to set the "group"
+# configuration in radiusd.conf. Look for "shadow", and follow the
+# instructions there.
+#
+unix {
+ #
+ # The location of the "wtmp" file.
+ # The only use for 'radlast'. If you don't use
+ # 'radlast', then you can comment out this item.
+ #
+ # Note that the radwtmp file may get large! You should
+ # rotate it (cp /dev/null radwtmp), or just not use it.
+ #
+ radwtmp = ${logdir}/radwtmp
+}
diff --git a/raddb/mods-available/unpack b/raddb/mods-available/unpack
new file mode 100644
index 0000000..89ef169
--- /dev/null
+++ b/raddb/mods-available/unpack
@@ -0,0 +1,105 @@
+# -*- text -*-
+#
+# $Id$
+
+#
+# This module is useful only for 'xlat'.
+# To use it, add it to the raddb/mods-enabled/ directory.
+#
+# Two xlat functions are provided by this module:
+# - unpack
+# - substring
+#
+# Both are for use on the right-hand side of a variable assignment.
+#
+# unpack
+# ======
+#
+# ... = "%{unpack:data 1 integer}"
+#
+# The arguments are three fields:
+#
+# data
+# Either &Attribute-Name
+# the name of the attribute to unpack.
+# MUST be a "string" or "octets" type.
+#
+# or 0xabcdef
+# e.g. hex data.
+#
+# 1
+# The offset into the string from which
+# it starts unpacking. The offset starts
+# at zero, for the first attribute.
+#
+# integer
+# the data type to unpack at that offset.
+# e.g. integer, ipaddr, byte, short, etc.
+#
+# e.g. if we have Class = 0x0000000102030405, then
+#
+# %{unpack:&Class 4 short}
+#
+# will unpack octets 4 and 5 as a "short", which has
+# value 0x0304.
+#
+# This module is used when vendors put multiple fields
+# into one attribute of type "octets".
+#
+# The module can also be used to unpack substrings, by specifing a
+# data type of "string(len)" or "octets(len)". Where "len" is an
+# actual number. For example:
+#
+# %{unpack:&User-Name 1 string(2)}
+#
+# When given a User-Name of "hello", it will start taking the
+# substring at offset 1 (i.e. "e"), and it will take two characters
+# from that offset, i.e. "el".
+#
+# As a special case, you can unpack an entire string by specifying
+# the offset, and nothing for the length:
+#
+# %{unpack:&User-Name 1 string()}
+#
+# When "octets(len)" is used, the output is printed as hex. e.g. for
+# the above example with Class:
+#
+# %{unpack:&Class 4 octets(4)}
+#
+# Will return the hex string "02030405"
+#
+#
+# substring
+# =========
+#
+# substring will return a substring of a string or attribute using
+# the syntax
+#
+# %{substring:data start len}
+#
+# data
+# Either an attribute name or string data. String data
+# can have leading or trailing spaces. Only a single
+# space before "start" is taken as the separator.
+#
+# start
+# the zero based offset for the start of the substring.
+# A negative value will count in from the end of the
+# string.
+#
+# len
+# the number of characters to return. A Negative value
+# will remove that number of characters from the end.
+# If len is more than the available number of characters
+# then only the available number will be returned.
+#
+# Examples:
+#
+# "%{substring:foobar 2 3}" == "oba"
+# "%{substring:foobar -3 2}" == "ba"
+# "%{substring:foobar 1 -1}" == "ooba"
+# if User-Name is "foobar" "%{substring:&User-Name 1 -2}" == "oob"
+#
+
+unpack {
+}
diff --git a/raddb/mods-available/utf8 b/raddb/mods-available/utf8
new file mode 100644
index 0000000..00812fa
--- /dev/null
+++ b/raddb/mods-available/utf8
@@ -0,0 +1,14 @@
+#
+# Enforces UTF-8 on strings coming in from the NAS.
+#
+# An attribute of type "string" containing UTF-8 makes
+# the module return NOOP.
+#
+# An attribute of type "string" containing non-UTF-8 data
+# makes the module return FAIL.
+#
+# This module takes no configuration.
+#
+utf8 {
+
+}
diff --git a/raddb/mods-available/wimax b/raddb/mods-available/wimax
new file mode 100644
index 0000000..3add59e
--- /dev/null
+++ b/raddb/mods-available/wimax
@@ -0,0 +1,165 @@
+#
+# The WiMAX module currently takes no configuration.
+#
+# ## Instructions for v1 and v2.0 WiMAX
+#
+# It should be listed in the "authorize" and "preacct" sections.
+# This enables the module to fix the horrible binary version
+# of Calling-Station-Id to the normal format, as specified in
+# RFC 3580, Section 3.21.
+#
+# In order to calculate the various WiMAX keys, the module should
+# be listed in the "post-auth" section. If EAP authentication
+# has been used, AND the EAP method derives MSK and EMSK, then
+# the various WiMAX keys can be calculated.
+#
+# Some useful things to remember:
+#
+# WiMAX-MSK = EAP MSK, but is 64 octets.
+#
+# MIP-RK-1 = HMAC-SHA256(ESMK, "miprk@wimaxforum.org" | 0x00020001)
+# MIP-RK-2 = HMAC-SHA256(ESMK, MIP-RK-1 | "miprk@wimaxforum.org" | 0x00020002)
+# MIP-RK = MIP-RK-1 | MIP-RK-2
+#
+# MIP-SPI = first 4 octets of HMAC-SHA256(MIP-RK, "SPI CMIP PMIP")
+# plus some magic... you've got to track *all* MIP-SPI's
+# on your system!
+#
+# SPI-CMIP4 = MIP-SPI
+# SPI-PMIP4 = MIP-SPI + 1
+# SPI-CMIP6 = MIP-SPI + 2
+#
+# MN-NAI is the Mobile node NAI. You have to create it, and put
+# it into the request or reply as something like:
+#
+# WiMAX-MN-NAI = "%{User-Name}"
+#
+# You will also have to have the appropriate IP address (v4 or v6)
+# in order to calculate the keys below.
+#
+# Lifetimes are derived from Session-Timeout. It needs to be set
+# to some useful number.
+#
+# The hash function below H() is HMAC-SHA1.
+#
+#
+# MN-HA-CMIP4 = H(MIP-RK, "CMIP4 MN HA" | HA-IPv4 | MN-NAI)
+#
+# Where HA-IPv4 is WiMAX-hHA-IP-MIP4
+# or maybe WiMAX-vHA-IP-MIP4
+#
+# Which goes into WiMAX-MN-hHA-MIP4-Key
+# or maybe WiMAX-RRQ-MN-HA-Key
+# or maybe even WiMAX-vHA-MIP4-Key
+#
+# The corresponding SPI is SPI-CMIP4, which is MIP-SPI,
+#
+# which goes into WiMAX-MN-hHA-MIP4-SPI
+# or maybe WiMAX-RRQ-MN-HA-SPI
+# or even WiMAX-MN-vHA-MIP4-SPI
+#
+# MN-HA-PMIP4 = H(MIP-RK, "PMIP4 MN HA" | HA-IPv4 | MN-NAI)
+# MN-HA-CMIP6 = H(MIP-RK, "CMIP6 MN HA" | HA-IPv6 | MN-NAI)
+#
+# both with similar comments to above for MN-HA-CMIP4.
+#
+# In order to tell which one to use (CMIP4, PMIP4, or CMIP6),
+# you have to set WiMAX-IP-Technology in the reply to one of
+# the appropriate values.
+#
+#
+# FA-RK = H(MIP-RK, "FA-RK")
+#
+# MN-FA = H(FA-RK, "MN FA" | FA-IP | MN-NAI)
+#
+# Where does the FA-IP come from? No idea...
+#
+#
+# The next two keys (HA-RK and FA-HA) are not generated
+# for every authentication request, but only on demand.
+#
+# HA-RK = 160-bit random number assigned by the AAA server
+# to a specific HA.
+#
+# FA-HA = H(HA-RK, "FA-HA" | HA-IPv4 | FA-CoAv4 | SPI)
+#
+# where HA-IPv4 is as above.
+# and FA-CoAv4 address of the FA as seen by the HA
+# and SPI is the relevant SPI for the HA-RK.
+#
+# DHCP-RK = 160-bit random number assigned by the AAA server
+# to a specific DHCP server. vDHCP-RK is the same
+# thing.
+#
+#
+#
+# ## Instructions for v2.1 (LTE) WiMAX:
+#
+# When called from the "authorize" this module will detect the
+# presence of the following attributes:
+#
+# request:WiMAX-Re-synchronization-Info
+# control:WiMAX-SIM-Ki
+# control:WiMAX-SIM-OPc
+#
+# If all attributes are present, (i.e. a known SIM is requesting a
+# resync) then the module will attempt to extract the new SQN and
+# save it in control:WiMAX-SIM-SQN. It will also save a copy of
+# RAND from the request in control:WiMAX-SIM-RAND.
+#
+# The resulting value of SQN can then be saved in a database
+# e.g. via a call to the sql module using some unlang
+#
+# When called in the "post_auth" section it looks for:
+#
+# control:WiMAX-SIM-Ki
+# control:WiMAX-SIM-OPc
+# control:WiMAX-SIM-AMF
+# control:WiMAX-SIM-SQN
+# request:WiMAX-Visited-PLMN-ID
+#
+# If all these are present then it will attempt to generate the
+# keys for EPS AKA.
+#
+# First it checks for the presence of control:WiMAX-SIM-RAND and
+# if it is not present it generates a new RAND value which is
+# stored in reply:WiMAX-E-UTRAN-Vector-RAND. If it is present then
+# the value is simply copied to the reply attribute.
+#
+# Then it calls the Milenage algorithm to generate:
+#
+# reply:WiMAX-E-UTRAN-Vector-XRES
+# reply:WiMAX-E-UTRAN-Vector-AUTN
+#
+# And finally generates KASME which is stored in:
+# reply:WiMAX-E-UTRAN-Vector-KASME
+#
+#
+# NOTE: It is up to the system administrator to make sure that all
+# the necessary "control" attributes are populated with the
+# required values. The IMSI is likely to be found in User-Name in
+# the request and this can be used as the key to grab the values
+# from a database.
+#
+#
+wimax {
+ #
+ # Some WiMAX equipment requires that the MS-MPPE-*-Key
+ # attributes are sent in the Access-Accept, in addition to
+ # the WiMAX-MSK attribute.
+ #
+ # Other WiMAX equipment request that the MS-MPPE-*-Key
+ # attributes are NOT sent in the Access-Accept.
+ #
+ # By default, the EAP modules sends MS-MPPE-*-Key attributes.
+ # The default virtual server (raddb/sites-available/default)
+ # contains examples of adding the WiMAX-MSK.
+ #
+ # This configuration option makes the WiMAX module delete
+ # the MS-MPPE-*-Key attributes. The default is to leave
+ # them in place.
+ #
+ # If the keys are deleted (by setting this to "yes"), then
+ # the WiMAX-MSK attribute is automatically added to the reply.
+ delete_mppe_keys = no
+}
diff --git a/raddb/mods-available/yubikey b/raddb/mods-available/yubikey
new file mode 100644
index 0000000..9ba61ef
--- /dev/null
+++ b/raddb/mods-available/yubikey
@@ -0,0 +1,158 @@
+#
+# This module decrypts and validates Yubikey static and dynamic
+# OTP tokens.
+#
+yubikey {
+ #
+ # The length (number of ASCII bytes) of the Public-ID portion
+ # of the OTP string.
+ #
+ # Yubikey defaults to a 6 byte ID (2 * 6 = 12)
+# id_length = 12
+
+ #
+ # If true, the authorize method of rlm_yubikey will attempt to split the
+ # value of User-Password, into the user's password, and the OTP token.
+ #
+ # If enabled and successful, the value of &request:User-Password will be
+ # truncated and &request:Yubikey-OTP will be added.
+ #
+# split = yes
+
+ #
+ # Decrypt mode - Tokens will be decrypted and processed locally
+ #
+ # The module itself does not provide persistent storage as this
+ # would be duplicative of functionality already in the server.
+ #
+ # Yubikey authentication needs two attributes retrieved from
+ # persistent storage:
+ # * &control:Yubikey-Key - The AES key used to decrypt the OTP data.
+ # The Yubikey-Public-Id and/or User-Name
+ # attributes may be used to retrieve the key.
+ # * &control:Yubikey-Counter - This is compared with the counter in the OTP
+ # data and used to prevent replay attacks.
+ # This attribute will also be available in
+ # the request list after successful
+ # decryption.
+ #
+ # Yubikey-Counter isn't strictly required, but the server will
+ # generate warnings if it's not present when yubikey.authenticate
+ # is called.
+ #
+ # These attributes are available after authorization:
+ # * &request:Yubikey-Public-ID - The public portion of the OTP string.
+ # and additionally if 'split' is set:
+ # * &request:Yubikey-OTP - The OTP portion of User-Password.
+ #
+ # These attributes are available after authentication (if successful):
+ # * &request:Yubikey-Private-ID - The encrypted ID included in OTP data,
+ # must be verified if tokens share keys.
+ # * &request:Yubikey-Counter - The last counter value (should be recorded).
+ # * &request:Yubikey-Timestamp - Token's internal clock (mainly useful for
+ # debugging).
+ # * &request:Yubikey-Random - Randomly generated value from the token.
+ #
+ decrypt = no
+
+ #
+ # Validation mode - Tokens will be validated against a Yubicloud server
+ #
+ validate = no
+
+ #
+ # Settings for validation mode.
+ #
+ validation {
+ #
+ # URL of validation server, multiple URL config items may be used
+ # to list multiple servers.
+ #
+ # - %d is a placeholder for public ID of the token
+ # - %s is a placeholder for the token string itself
+ #
+ # If no URLs are listed, will default to the default URLs in the
+ # ykclient library, which point to the yubico validation servers.
+ servers {
+# uri = 'https://api.yubico.com/wsapi/2.0/verify?id=%d&otp=%s'
+# uri = 'https://api2.yubico.com/wsapi/2.0/verify?id=%d&otp=%s'
+ }
+
+ #
+ # API Client ID
+ #
+ # Must be set to your client id for the validation server.
+ #
+# client_id = 00000
+
+ #
+ # API Secret key (Base64 encoded)
+ #
+ # Must be set to your API key for the validation server.
+ #
+# api_key = '000000000000000000000000'
+
+ #
+ # Connection pool parameters
+ #
+ pool {
+ # 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
+ # yubikey server being available.
+ start = ${thread[pool].start_servers}
+
+ # Minimum number of connections to keep open
+ min = ${thread[pool].min_spare_servers}
+
+ # 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.
+ max = ${thread[pool].max_servers}
+
+ # Number of uses before the connection is closed
+ #
+ # NOTE: A setting of 0 means infinite (no limit).
+ uses = 0
+
+ # 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.
+ retry_delay = 30
+
+ # The lifetime (in seconds) of the connection
+ #
+ # NOTE: A setting of 0 means infinite (no limit).
+ lifetime = 0
+
+ # 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).
+ idle_timeout = 60
+
+ # Cycle over all connections in a pool instead of concentrating
+ # connection use on a few connections.
+ spread = yes
+
+ # 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.
+ }
+ }
+}