From af754e596a8dbb05ed8580c342e7fe02e08b28e0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 16:11:00 +0200 Subject: Adding upstream version 3.2.3+dfsg. Signed-off-by: Daniel Baumann --- raddb/sites-available/README | 333 +++++++ raddb/sites-available/abfab-tls | 118 +++ raddb/sites-available/abfab-tr-idp | 198 ++++ raddb/sites-available/aws-nlb | 46 + raddb/sites-available/buffered-sql | 161 ++++ raddb/sites-available/challenge | 123 +++ raddb/sites-available/channel_bindings | 17 + raddb/sites-available/check-eap-tls | 135 +++ raddb/sites-available/coa | 49 + raddb/sites-available/coa-relay | 366 ++++++++ raddb/sites-available/control-socket | 92 ++ raddb/sites-available/copy-acct-to-home-server | 202 +++++ raddb/sites-available/decoupled-accounting | 139 +++ raddb/sites-available/default | 1159 ++++++++++++++++++++++++ raddb/sites-available/dhcp | 595 ++++++++++++ raddb/sites-available/dhcp.relay | 44 + raddb/sites-available/dynamic-clients | 222 +++++ raddb/sites-available/example | 122 +++ raddb/sites-available/google-ldap-auth | 225 +++++ raddb/sites-available/inner-tunnel | 468 ++++++++++ raddb/sites-available/originate-coa | 185 ++++ raddb/sites-available/proxy-inner-tunnel | 47 + raddb/sites-available/resource-check | 140 +++ raddb/sites-available/robust-proxy-accounting | 177 ++++ raddb/sites-available/soh | 34 + raddb/sites-available/status | 127 +++ raddb/sites-available/tls | 696 ++++++++++++++ raddb/sites-available/tls-cache | 144 +++ raddb/sites-available/totp | 85 ++ raddb/sites-available/virtual.example.com | 32 + raddb/sites-available/vmps | 98 ++ 31 files changed, 6579 insertions(+) create mode 100644 raddb/sites-available/README create mode 100644 raddb/sites-available/abfab-tls create mode 100644 raddb/sites-available/abfab-tr-idp create mode 100644 raddb/sites-available/aws-nlb create mode 100644 raddb/sites-available/buffered-sql create mode 100644 raddb/sites-available/challenge create mode 100644 raddb/sites-available/channel_bindings create mode 100644 raddb/sites-available/check-eap-tls create mode 100644 raddb/sites-available/coa create mode 100644 raddb/sites-available/coa-relay create mode 100644 raddb/sites-available/control-socket create mode 100644 raddb/sites-available/copy-acct-to-home-server create mode 100644 raddb/sites-available/decoupled-accounting create mode 100644 raddb/sites-available/default create mode 100644 raddb/sites-available/dhcp create mode 100644 raddb/sites-available/dhcp.relay create mode 100644 raddb/sites-available/dynamic-clients create mode 100644 raddb/sites-available/example create mode 100644 raddb/sites-available/google-ldap-auth create mode 100644 raddb/sites-available/inner-tunnel create mode 100644 raddb/sites-available/originate-coa create mode 100644 raddb/sites-available/proxy-inner-tunnel create mode 100644 raddb/sites-available/resource-check create mode 100644 raddb/sites-available/robust-proxy-accounting create mode 100644 raddb/sites-available/soh create mode 100644 raddb/sites-available/status create mode 100644 raddb/sites-available/tls create mode 100644 raddb/sites-available/tls-cache create mode 100644 raddb/sites-available/totp create mode 100644 raddb/sites-available/virtual.example.com create mode 100644 raddb/sites-available/vmps (limited to 'raddb/sites-available') diff --git a/raddb/sites-available/README b/raddb/sites-available/README new file mode 100644 index 0000000..0805a75 --- /dev/null +++ b/raddb/sites-available/README @@ -0,0 +1,333 @@ +1. Virtual Servers. + + FreeRADIUS supports virtual servers. The virtual servers do NOT have +to be set up with the "sites-available" and "sites-enabled" +directories. You can still have one "radiusd.conf" file, and put the +server configuration there: + + ... + server { + authorize { + ... + } + authenticate { + ... + } + ... + } + ... + + The power of virtual servers lies in their ability to separate +policies. A policy can be placed into a virtual server, where it is +guaranteed to affect only the requests that are passed through that +virtual server. In 1.x, the policies were global, and it sometimes +took much effort to write a policy so that it only applied in certain +limited situations. + + +2. What do we mean by "virtual server"? + + + A virtual server is a (nearly complete) RADIUS server, just like a +configuration for FreeRADIUS 1.x. However, FreeRADIUS can now run +multiple virtual servers at the same time. The virtual servers can +even proxy requests to each other! + + The simplest way to create a virtual server is to take the all of +the request processing sections from radius.conf, ("authorize" , +"authenticate", etc.) and wrap them in a "server {}" block, as above. + + You can create another virtual server by: + + 1) defining a new "server foo {...}" section in radiusd.conf + 2) Putting the normal "authorize", etc. sections inside of it + 3) Adding a "listen" section *inside* of the "server" section. + + e.g. + + ... + server foo { + listen { + ipaddr = 127.0.0.1 + port = 2000 + type = auth + } + + authorize { + update control { + Cleartext-Password := "bob" + } + pap + } + + authenticate { + pap + } + } + ... + + With that text added to "radiusd.conf", run the server in debugging +mode (radiusd -X), and in another terminal window, type: + +$ radtest bob bob localhost:2000 0 testing123 + + You should see the server return an Access-Accept. + + +3. Capabilities and limitations + + + The only sub-sections that can appear in a virtual server section +are: + + listen + client + authorize + authenticate + post-auth + pre-proxy + post-proxy + preacct + accounting + session + + All other configuration parameters (modules, etc.) are global. + + Inside of a virtual server, the authorize, etc. sections have their +normal meaning, and can contain anything that an authorize section +could contain in 1.x. + + When a "listen" section is inside of a virtual server definition, it +means that all requests sent to that IP/port will be processed through +the virtual server. There cannot be two "listen" sections with the +same IP address and port number. + + When a "client" section is inside of a virtual server definition, it +means that that client is known only to the "listen" sections that are +also inside of that virtual server. Not only is this client +definition available only to this virtual server, but the details of +the client configuration is also available only to this virtual +server. + + i.e. Two virtual servers can listen on different IP address and +ports, but both can have a client with IP address 127.0.0.1. The +shared secret for that client can be different for each virtual +server. + + +4. More complex "listen" capabilities + + The "listen" sections have a few additional configuration items that +were not in 1.x, and were not mentioned above. These configuration +items enable almost any mapping of IP / port to clients to virtual +servers. + + The configuration items are: + + virtual_server = + + If set, all requests sent to this IP / port are processed + through the named virtual server. + + This directive can be used only for "listen" sections + that are global. i.e. It CANNOT be used if the + "listen" section is inside of a virtual server. + + clients = + + If set, the "listen" section looks for a "clients" section: + + clients { + ... + } + + It looks inside of that named "clients" section for + "client" subsections, at least one of which must + exist. Each client in that section is added to the + list of known clients for this IP / port. No other + clients are known. + + If it is set, it over-rides the list of clients (if + any) in the same virtual server. Note that the + clients are NOT additive! + + If it is not set, then the clients from the current + virtual server (if any) are used. If there are no + clients in this virtual server, then the global + clients are used. + + i.e. The most specific directive is used: + * configuration in this "listen" section + * clients in the same virtual server + * global clients + + The directives are also *exclusive*, not *additive*. + If you have one client in a virtual server, and + another client referenced from a "listen" section, + then that "listen" section will ONLY use the second + client. It will NOT use both clients. + + +5. More complex "client" capabilities + + The "client" sections have a few additional configuration items that +were not in 1.x, and were not mentioned above. These configuration +items enable almost any mapping of IP / port to clients to virtual +servers. + + The configuration items are: + + virtual_server = + + If set, all requests from this client are processed + through the named virtual server. + + This directive can be used only for "client" sections + that are global. i.e. It CANNOT be used if the + "client" section is inside of a virtual server. + + If the "listen" section has a "server" entry, and a matching +client is found ALSO with a "server" entry, then the clients server is +used for that request. + + +6. Worked examples + + + Listening on one socket, and mapping requests from two clients to +two different servers. + + listen { + ... + } + client one { + ... + virtual_server = server_one + } + client two { + ... + virtual_server = server_two + } + server server_one { + authorize { + ... + } + ... + } + server server_two { + authorize { + ... + } + ... + } + + This could also be done as: + + + listen { + ... + virtual_server = server_one + } + client one { + ... + } + client two { + ... + virtual_server = server_two + } + server server_one { + authorize { + ... + } + ... + } + server server_two { + authorize { + ... + } + ... + } + + In this case, the default server for the socket is "server_one", so +there is no need to set that in the client "one" configuration. The +"server_two" configuration for client "two" over-rides the default +setting for the socket. + + Note that the following configuration will NOT work: + + listen { + ... + virtual_server = server_one + } + client one { + ... + } + server server_one { + authorize { + ... + } + ... + } + server server_two { + client two { + ... + } + authorize { + ... + } + ... + } + + In this example, client "two" is hidden inside of the virtual +server, where the "listen" section cannot find it. + + +7. Outlined examples + + This section outlines a number of examples, with alternatives. + + One server, multiple sockets + - multiple "listen" sections in a "server" section + + one server per client + - define multiple servers + - have a global "listen" section + - have multiple global "clients", each with "virtual_server = X" + + two servers, each with their own sockets + - define multiple servers + - put "client" sections into each "server" + - put a "listen" section into each "server" + + Each server can list the same client IP, and the secret + can be different + + two sockets, sharing a list of clients, but pointing to different servers + - define global "listen" sections + - in each, set "virtual_server = X" + - in each, set "clients = Y" + - define "clients Y" section, containing multiple clients. + + This also means that you can have a third socket, which + doesn't share any of these clients. + + +8. How to decide what to do + + + If you want *completely* separate policies for a socket or a client, +then create a separate virtual server. Then, map the request to that +server by setting configuration entries in a "listen" section or in a +"client" section. + + Start off with the common cases first. If most of the clients +and/or sockets get a particular policy, make that policy the default. +Configure it without paying attention to the sockets or clients you +want to add later, and without adding a second virtual server. Once +it works, then add the second virtual server. + + If you want to re-use the previously defined sockets with the second +virtual server, then you will need one or more global "client" +sections. Those clients will contain a "virtual_server = ..." entry +that will direct requests from those clients to the appropriate +virtual server. diff --git a/raddb/sites-available/abfab-tls b/raddb/sites-available/abfab-tls new file mode 100644 index 0000000..b8d0626 --- /dev/null +++ b/raddb/sites-available/abfab-tls @@ -0,0 +1,118 @@ +# +# Example configuration for ABFAB listening on TLS. +# +# $Id$ +# +listen { + ipaddr = * + port = 2083 + type = auth + proto = tcp + + tls { + tls_min_version = "1.2" + private_key_password = whatever + + # Moonshot tends to distribute certs separate from keys + private_key_file = ${certdir}/server.key + certificate_file = ${certdir}/server.pem + ca_file = ${cadir}/ca.pem + dh_file = ${certdir}/dh + fragment_size = 8192 + ca_path = ${cadir} + cipher_list = "DEFAULT" + cache { + enable = no + lifetime = 24 # hours + name = "abfab-tls" + # persist_dir = ${logdir}/abfab-tls + } + require_client_cert = yes + verify { + } + + psk_query = "%{psksql:select hex(key) from psk_keys where keyid = '%{TLS-PSK-Identity}'}" + } + + virtual_server = abfab-idp + clients = radsec-abfab +} + +# There needs to be a separated "listen" section for IPv6. +# Typically it will be identical to the IPv4 one above, but there might be +# some differences (e.g. if a different certificate or port is desired) +listen { + ipaddr = :: + port = 2083 + type = auth + proto = tcp + + tls { + tls_min_version = "1.2" + private_key_password = whatever + + # Moonshot tends to distribute certs separate from keys + private_key_file = ${certdir}/server.key + certificate_file = ${certdir}/server.pem + ca_file = ${cadir}/ca.pem + dh_file = ${certdir}/dh + fragment_size = 8192 + ca_path = ${cadir} + cipher_list = "DEFAULT" + cache { + enable = no + lifetime = 24 # hours + name = "abfab-tls" + # persist_dir = ${logdir}/abfab-tls + } + require_client_cert = yes + verify { + } + + psk_query = "%{psksql:select hex(key) from psk_keys where keyid = '%{TLS-PSK-Identity}'}" + } + + virtual_server = abfab-idp + clients = radsec-abfab +} + +clients radsec-abfab { + # + # Allow all clients, but require TLS. + # This client stanza will match other RP proxies from other + # realms established via the trustrouter. In general + # additional client stanzas are also required for local services. + # + client default { + ipaddr = 0.0.0.0/0 + proto = tls + } + + client default_ip6 { + ipaddr = ::/0 + proto = tls + } + + # An example local service + # client service_1 { + # ipaddr = 192.0.2.20 + # # You should either set gss_acceptor_host_name below + # # or set up policy to confirm that a client claims + # # the right acceptor hostname when using ABFAB. If + # # set, the RADIUS server will confirm that all + # # requests have this value for the acceptor host name + # gss_acceptor_host_name = "server.example.com" + # # If set, this acceptor realm name will be included. + # # Foreign realms will typically reject a request if this is not + # # properly set. + # gss_acceptor_realm_name = "example.com" + # # Additionally, trust_router_coi can be set; if set + # # it will override the default_community in the realm + # # module + # trust_router_coi = "community1.example.net" + # # In production depployments it is important to set + # # up certificate verification so that even if + # # clients spoof IP addresses, one client cannot + # # impersonate another. + # } +} diff --git a/raddb/sites-available/abfab-tr-idp b/raddb/sites-available/abfab-tr-idp new file mode 100644 index 0000000..be98568 --- /dev/null +++ b/raddb/sites-available/abfab-tr-idp @@ -0,0 +1,198 @@ +# +# This file represents a server that is implementing an identity +# provider for GSS-EAP (RFC 7055) using the trust router +# protocol for dynamic realm discovery. Any ABFAB identity +# provider is also an ABFAB relying party proxy. +# +# This file does not include a TLS listener; see abfab-tls for a simple +# example of a RADSEC listener for ABFAB. +# +# $Id$ +# + +server abfab-idp { +authorize { + psk_authorize + abfab_client_check + filter_username + preprocess + + # If you intend to use CUI and you require that the Operator-Name + # be set for CUI generation and you want to generate CUI also + # for your local clients then uncomment the operator-name + # below and set the operator-name for your clients in clients.conf +# operator-name + + # + # If you want to generate CUI for some clients that do not + # send proper CUI requests, then uncomment the + # cui below and set "add_cui = yes" for these clients in clients.conf +# cui + + # + # Do RFC 7542 bang path routing. If you want to only do standard + # RADIUS NAI routing, comment out the below line. + rfc7542 + + # Standard RADIUS NAI routing + if (!updated) { + suffix { + updated = 1 + noop = reject + } + } + + eap { + ok = return + } + + expiration + logintime +} + +authenticate { + # + # Allow EAP authentication. + eap +} + +# Post-Authentication +# Once we KNOW that the user has been authenticated, there are +# additional steps we can take. +post-auth { + # + # For EAP-TTLS and PEAP, add the cached attributes to the reply. + # The "session-state" attributes are automatically cached when + # an Access-Challenge is sent, and automatically retrieved + # when an Access-Request is received. + # + # The session-state attributes are automatically deleted after + # an Access-Reject or Access-Accept is sent. + # + # If both session-state and reply contain a User-Name attribute, remove + # the one in the reply if it is just a copy of the one in the request, so + # we don't end up with two User-Name attributes. + + if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) { + update reply { + &User-Name !* ANY + } + } + update { + &reply: += &session-state: + } + + # Create the CUI value and add the attribute to Access-Accept. + # Uncomment the line below if *returning* the CUI. +# cui + + # + # If you want to have a log of authentication replies, + # un-comment the following line, and enable the + # 'detail reply_log' module. +# reply_log + + # + # After authenticating the user, do another SQL query. + # + # See "Authentication Logging Queries" in `mods-config/sql/main/$driver/queries.conf` + -sql + + # + # Un-comment the following if you want to modify the user's object + # in LDAP after a successful login. + # +# ldap + + # For Exec-Program and Exec-Program-Wait + exec + # Remove reply message if the response contains an EAP-Message + remove_reply_message_if_eap + # Access-Reject packets are sent through the REJECT sub-section of the + # post-auth section. + # + # Add the ldap module name (or instance) if you have set + # 'edir = yes' in the ldap module configuration + # + Post-Auth-Type REJECT { + # log failed authentications in SQL, too. + -sql + attr_filter.access_reject + + # Insert EAP-Failure message if the request was + # rejected by policy instead of because of an + # authentication failure And already has an EAP message + # For non-ABFAB, we insert the failure all the time, but for ABFAB + # It's more desirable to preserve reply-message when we can + if (&reply:Eap-Message) { + eap + } + + # Remove reply message if the response contains an EAP-Message + remove_reply_message_if_eap + } +} +# +# When the server decides to proxy a request to a home server, +# the proxied request is first passed through the pre-proxy +# stage. This stage can re-write the request, or decide to +# cancel the proxy. +# +# Only a few modules currently have this method. +# +pre-proxy { + # Before proxing the request add an Operator-Name attribute identifying + # if the operator-name is found for this client. + # No need to uncomment this if you have already enabled this in + # the authorize section. +# operator-name + + # The client requests the CUI by sending a CUI attribute + # containing one zero byte. + # Uncomment the line below if *requesting* the CUI. +# cui + + # Uncomment the following line if you want to change attributes + # as defined in the preproxy_users file. +# files + + # Uncomment the following line if you want to filter requests + # sent to remote servers based on the rules defined in the + # 'attrs.pre-proxy' file. +# attr_filter.pre-proxy + + # If you want to have a log of packets proxied to a home + # server, un-comment the following line, and the + # 'detail pre_proxy_log' section, above. +# pre_proxy_log +} +# +# When the server receives a reply to a request it proxied +# to a home server, the request may be massaged here, in the +# post-proxy stage. +# +post-proxy { + + # If you want to have a log of replies from a home server, + # un-comment the following line, and the 'detail post_proxy_log' + # section, above. +# post_proxy_log + + # Uncomment the following line if you want to filter replies from + # remote proxies based on the rules defined in the 'attrs' file. +# attr_filter.post-proxy + + # + # If you are proxying LEAP, you MUST configure the EAP + # module, and you MUST list it here, in the post-proxy + # stage. + # + # You MUST also use the 'nostrip' option in the 'realm' + # configuration. Otherwise, the User-Name attribute + # in the proxied request will not match the user name + # hidden inside of the EAP packet, and the end server will + # reject the EAP request. + # + eap +} +} diff --git a/raddb/sites-available/aws-nlb b/raddb/sites-available/aws-nlb new file mode 100644 index 0000000..acea81e --- /dev/null +++ b/raddb/sites-available/aws-nlb @@ -0,0 +1,46 @@ +# -*- text -*- +###################################################################### +# +# A sample virtual server which handles "health checks" from Amazon +# elastic load balancer. +# +# https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-healthchecks.html +# +# In the Amazon system, configure "proto" as "tcp", and "port" as the port +# given below in the "listen" section. +# +# $Id$ +# +server aws-nlb { + +# +# This should be the IP address of the Amazon load balancer. +# +# If TCP checks come from multiple IP addresses, just list each IP in a separate "client" section. +# +client aws-nlb { + ipaddr = 192.0.2.1 + proto = tcp + secret = "this-will-never-be-used" +} + +# +# Listen on a port. Don't use 80, as that requires root permissions, +# and you don't want to run radiusd as root. +# +listen { + type = status + proto = tcp + ipaddr = * + port = 8000 +} + +# +# This will never get used, but it's here just in case we actually +# get sent RADIUS packets. +# +authorize { + reject +} + +} diff --git a/raddb/sites-available/buffered-sql b/raddb/sites-available/buffered-sql new file mode 100644 index 0000000..74574ac --- /dev/null +++ b/raddb/sites-available/buffered-sql @@ -0,0 +1,161 @@ +# -*- text -*- +###################################################################### +# +# In 2.0.0, radrelay functionality is integrated into the +# server core. This virtual server gives an example of +# using radrelay functionality inside of the server. +# +# In this example, the detail file is read, and the data +# is put into SQL. This configuration is used when a RADIUS +# server on this machine is receiving accounting packets, +# and writing them to the detail file. +# +# The purpose of this virtual server is to de-couple the storage +# of long-term accounting data in SQL from "live" information +# needed by the RADIUS server as it is running. +# +# The benefit of this approach is that for a busy server, the +# overhead of performing SQL queries may be significant. Also, +# if the SQL databases are large (as is typical for ones storing +# months of data), the INSERTs and UPDATEs may take a relatively +# long time. Rather than slowing down the RADIUS server by +# having it interact with a database, you can just log the +# packets to a detail file, and then read that file later at a +# time when the RADIUS server is typically lightly loaded. +# +# If you use on virtual server to log to the detail file, +# and another virtual server (i.e. this one) to read from +# the detail file, then this process will happen automatically. +# A sudden spike of RADIUS traffic means that the detail file +# will grow in size, and the server will be able to handle +# large volumes of traffic quickly. When the traffic dies down, +# the server will have time to read the detail file, and insert +# the data into a long-term SQL database. +# +# $Id$ +# +###################################################################### + +server buffered-sql { + listen { + type = detail + + # The location where the detail file is located. + # This should be on local disk, and NOT on an NFS + # mounted location! + # + # On most systems, this should support file globbing + # e.g. "${radacctdir}/detail-*:*" + # This lets you write many smaller detail files as in + # the example in radiusd.conf: ".../detail-%Y%m%d:%H" + # Writing many small files is often better than writing + # one large file. File globbing also means that with + # a common naming scheme for detail files, then you can + # have many detail file writers, and only one reader. + # + filename = "${radacctdir}/detail-*" + + # + # The server can read accounting packets from the + # detail file much more quickly than those packets + # can be written to a database. If the database is + # overloaded, then bad things can happen. + # + # The server will keep track of how long it takes to + # process an entry from the detail file. It will + # then pause between handling entries. This pause + # allows databases to "catch up", and gives the + # server time to notice that other packets may have + # arrived. + # + # The pause is calculated dynamically, to ensure that + # the load due to reading the detail files is limited + # to a small percentage of CPU time. The + # "load_factor" configuration item is a number + # between 1 and 100. The server will try to keep the + # percentage of time taken by "detail" file entries + # to "load_factor" percentage of the CPU time. + # + # If the "load_factor" is set to 100, then the server + # will read packets as fast as it can, usually + # causing databases to go into overload. + # + load_factor = 10 + + # + # Set the interval for polling the detail file. + # If the detail file doesn't exist, the server will + # wake up, and poll for it every N seconds. + # + # Useful range of values: 1 to 60 + # + poll_interval = 1 + + # + # Set the retry interval for when the home server + # does not respond. The current packet will be + # sent repeatedly, at this interval, until the + # home server responds. + # + # Useful range of values: 5 to 30 + # + retry_interval = 30 + + # + # Track progress through the detail file. When the detail + # file is large, and the server is re-started, it will + # read from the START of the file. + # + # Setting "track = yes" means it will skip packets which + # have already been processed. The default is "no". + # + # track = yes + + # + # In some circumstances it may be desirable for the + # server to start up, process a detail file, and + # immediately quit. To do this enable the "one_shot" + # option below. + # + # Do not enable this for normal server operation. The + # default is "no". + # + # one_shot = no + } + + # + # Pre-accounting. Decide which accounting type to use. + # + preacct { + preprocess + + # + # Ensure that we have a semi-unique identifier for every + # request, and many NAS boxes are broken. + acct_unique + + # + # Read the 'acct_users' file. This isn't always + # necessary, and can be deleted if you do not use it. + files + } + + # + # Accounting. Log the accounting data. + # + accounting { + # + # Log traffic to an SQL database. + # + # See "Accounting queries" in mods-config/sql/main/$driver/queries.conf + # sql + + + # Cisco VoIP specific bulk accounting + # pgsql-voip + + } + + # The requests are not being proxied, so no pre/post-proxy + # sections are necessary. +} diff --git a/raddb/sites-available/challenge b/raddb/sites-available/challenge new file mode 100644 index 0000000..c3aeb08 --- /dev/null +++ b/raddb/sites-available/challenge @@ -0,0 +1,123 @@ +# +# This file gives an example of using Challenge-Response +# +# In this example, the user logs in with a password, which has +# to be "hello". The server will send them a challenge +# consisting of a random number 0..9. The user has to respond +# with that number. +# +# +# $Id$ +# +listen { + type = auth + ipaddr = * + port = 2000 + virtual_server = challenge +} + +server challenge { +authorize { + # + # OTP requires a password. + # + if (!User-Password) { + reject + } + + # + # If there's no State attribute, then this is the first + # request from the user. + # + if (!State) { + # + # Set the authentication to use step 1. + update control { + Auth-Type := Step1 + + # + # For testing we will just set the password to "hello". + # + # Normally the password comes from "ldap" or "sql". + # + Cleartext-Password := "hello" + +# ldap +# sql +# ... + } + } + else { + # + # Check that the password looks like an OTP + # + if (User-Password !~ /[0-9]{6}/) { + reject + } + + # + # Set the authentication to use step 2. + # Set the "known good" password to the number + # saved in the session-state list. + # + update control { + Auth-Type := Step2 + + # + # For testing, ensure that the user enters the same password. + # + # Normally this section should look up a TOTP-Secret, and + # + Cleartext-Password := &session-state:Tmp-Integer-0 + + # + # Normally this section should also set &control:TOTP-Secret, too. + # + TOTP-Password := &User-Password + } + } +} + +authenticate { + Auth-Type Step1 { + # If the password doesn't match, the user is rejected + # immediately. + pap + + # + # For testing, just use a 6 digit random OTP. + # + update session-state { + Tmp-Integer-0 := "%{randstr:nnnnnn}" + } + + # + # For testing, tell the user what OTP to enter. + # + # Don't do this in production... + # + update reply { + Reply-Message := "Please enter OTP %{session-state:Tmp-Integer-0}" + } + + # + # Send an Access-Challenge. + # See raddb/policy.d/control for the definition + # of "challenge" + # + challenge + } + + Auth-Type Step2 { + # + # For testing, do PAP authentication with the password. + # + pap + + # + # Normally you'd do TOTP checks via the TOTP module. + # +# totp + } +} +} diff --git a/raddb/sites-available/channel_bindings b/raddb/sites-available/channel_bindings new file mode 100644 index 0000000..b9f0ac7 --- /dev/null +++ b/raddb/sites-available/channel_bindings @@ -0,0 +1,17 @@ +# +# A virtual server which is used to validate channel-bindings. +# +# $Id$ +# +server channel_bindings { + # + # Only the "authorize" section is needed. + # + authorize { + # In general this section should include a policy for each type + # of channel binding that may be in use. For example each lower + # layer such as GSS-EAP (RFC 7055) or IEEE 802.11I is likely to + # need a separate channel binding policy. + abfab_channel_bindings + } +} diff --git a/raddb/sites-available/check-eap-tls b/raddb/sites-available/check-eap-tls new file mode 100644 index 0000000..d367463 --- /dev/null +++ b/raddb/sites-available/check-eap-tls @@ -0,0 +1,135 @@ +# This virtual server allows EAP-TLS to reject access requests +# based on some attributes of the certificates involved. +# +# To use this virtual server, you must enable it in the tls +# section of mods-enabled/eap as well as adding a link to this +# file in sites-enabled/. +# +# +# Value-pairs that are available for checking include: +# +# TLS-Client-Cert-Subject +# TLS-Client-Cert-Issuer +# TLS-Client-Cert-Common-Name +# TLS-Client-Cert-Subject-Alt-Name-Email +# +# To see a full list of attributes, run the server in debug mode +# with this virtual server configured, and look at the attributes +# passed in to this virtual server. +# +# +# This virtual server is also useful when using EAP-TLS as it is +# only called once, just before the final Accept is about to be +# returned from eap, whereas the outer authorize section is called +# multiple times for each challenge / response. For this reason, +# here may be a good location to put authentication logging, and +# modules that check for further authorization, especially if they +# hit external services such as sql or ldap. + + +server check-eap-tls { + + +# Authorize - this is the only section required. +# +# To accept the access request, set Auth-Type = Accept, otherwise +# set it to Reject. + +authorize { + + # + # By default, we just accept the request: + # + update config { + &Auth-Type := Accept + } + + + # + # Check the client certificate matches a string, and reject otherwise + # + +# if ("%{TLS-Client-Cert-Common-Name}" == 'client.example.com') { +# update config { +# &Auth-Type := Accept +# } +# } +# else { +# update config { +# &Auth-Type := Reject +# } +# update reply { +# &outer.Reply-Message := "Your certificate is not valid." +# } +# } + + + # + # Check the client certificate common name against the supplied User-Name + # +# if (&User-Name == "host/%{TLS-Client-Cert-Common-Name}") { +# update config { +# &Auth-Type := Accept +# } +# } +# else { +# update config { +# &Auth-Type := Reject +# } +# } + + + # + # This is a convenient place to call LDAP, for example, when using + # EAP-TLS, as it will only be called once, after all certificates as + # part of the EAP-TLS challenge process have been verified. + # + # An example could be to use LDAP to check that the connecting host, as + # well as presenting a valid certificate, is also in a group based on + # the User-Name (assuming this contains the service principal name). + # Settings such as the following could be used in the ldap module + # configuration: + # + # basedn = "dc=example, dc=com" + # filter = "(servicePrincipalName=%{User-Name})" + # base_filter = "(objectClass=computer)" + # groupname_attribute = cn + # groupmembership_filter = "(&(objectClass=group)(member=%{control:Ldap-UserDn}))" + +# ldap + + # Now let's test membership of an LDAP group (the ldap bind user will + # need permission to read this group membership): + +# if (!(Ldap-Group == "Permitted-Laptops")) { +# update config { +# &Auth-Type := Reject +# } +# } + + # or, to be more specific, you could use the group's full DN: + # if (!(Ldap-Group == "CN=Permitted-Laptops,OU=Groups,DC=example,DC=org")) { + + + # + # This may be a better place to call the files modules when using + # EAP-TLS, as it will only be called once, after the challenge-response + # iteration has completed. + # + +# files + + + # + # Log all request attributes, plus TLS certificate details, to the + # auth_log file. Again, this is just once per connection request, so + # may be preferable than in the outer authorize section. It is + # suggested that 'auth_log' also be in the outer post-auth and + # Post-Auth REJECT sections to log reply packet details, too. + # + + auth_log + +} +} + diff --git a/raddb/sites-available/coa b/raddb/sites-available/coa new file mode 100644 index 0000000..c10f88e --- /dev/null +++ b/raddb/sites-available/coa @@ -0,0 +1,49 @@ +# -*- text -*- +###################################################################### +# +# Sample virtual server for receiving a CoA or Disconnect-Request packet. +# + +# Listen on the CoA port. +# +# This uses the normal set of clients, with the same secret as for +# authentication and accounting. +# +listen { + type = coa + ipaddr = * + port = 3799 + virtual_server = coa +} + +server coa { + # When a packet is received, it is processed through the + # recv-coa section. This applies to *both* CoA-Request and + # Disconnect-Request packets. + recv-coa { + # CoA && Disconnect packets can be proxied in the same + # way as authentication or accounting packets. + # Just set Proxy-To-Realm, or Home-Server-Pool, and the + # packets will be proxied. + + # Do proxying based on realms here. You don't need + # "IPASS" or "ntdomain", as the proxying is based on + # the Operator-Name attribute. It contains the realm, + # and ONLY the realm (prefixed by a '1') + suffix + + # Insert your own policies here. + ok + } + + # When a packet is sent, it is processed through the + # send-coa section. This applies to *both* CoA-Request and + # Disconnect-Request packets. + send-coa { + # Sample module. + ok + } + + # You can use pre-proxy and post-proxy sections here, too. + # They will be processed for sending && receiving proxy packets. +} diff --git a/raddb/sites-available/coa-relay b/raddb/sites-available/coa-relay new file mode 100644 index 0000000..7dac7b1 --- /dev/null +++ b/raddb/sites-available/coa-relay @@ -0,0 +1,366 @@ +# -*- text -*- +###################################################################### +# +# This virtual server simplifies the process of sending CoA-Request or +# Disconnect-Request packets to a NAS. +# +# This virtual server will receive CoA-Request or Disconnect-Request +# packets that contain *minimal* identifying information. e.g. Just +# a User-Name, or maybe just an Acct-Session-Id attribute. It will +# look up that information in a database in order to find the rest of +# the session data. e.g. NAS-IP-Address, NAS-Identifier, NAS-Port, +# etc. That information will be added to the packet, which will then +# be sent to the NAS. +# +# This process is useful because NASes require the CoA packets to +# contain "session identification" attributes in order to to do CoA +# or Disconnect. If the attributes aren't in the packet, then the +# NAS will NAK the request. This NAK happens even if you ask to +# disconnect "User-Name = bob", and there is only one session with a +# "bob" active. +# +# Using this virtual server makes the CoA or Disconnect process +# easier. Just tell FreeRADIUS to disconnect "User-Name = bob", and +# FreeRADIUS will take care of adding the "session identification" +# attributes. +# +# The process is as follows: +# +# - A CoA/Disconnect-Request is received by FreeRADIUS. +# - The radacct table is searched for active sessions that match each of +# the provided identifier attributes: User-Name, Acct-Session-Id. The +# search returns the owning NAS and Acct-Unique-Id for the matching +# session/s. +# - The original CoA/Disconnect-Request content is written to a detail file +# with custom attributes representing the NAS and Acct-Session-Id. +# - A detail reader follows the file and originates CoA/Disconenct-Requests +# containing the original content, relayed to the corresponding NAS for +# each session using the custom attributes. +# +# This simplifies scripting directly against a set of NAS devices since a +# script need only send a single CoA/Disconnect to FreeRADIUS which will +# then: +# +# - Lookup all active sessions belonging to a user, in the case that only a +# User-Name attribute is provided in the request +# - Handle routing of the request to the correct NAS, in the case of a +# multi-NAS setup +# +# For example, to disconnect a specific session: +# +# $ echo 'Acct-Session-Id = "769df3 312343"' | \ +# radclient 127.0.0.1 disconnect testing123 +# +# To perform a CoA update of all active sessions belonging to a user: +# +# $ cat <