From 465934bd497c79e6c10ef08326cc96642f00ac25 Mon Sep 17 00:00:00 2001 From: Antonio Torres Date: Tue, 2 Apr 2024 12:06:03 +0200 Subject: [PATCH] Remove Antora docs from package These files are not needed since they are meant for upstream web documentation. Resolves: RHEL-31184 Signed-off-by: Antonio Torres --- freeradius-no-antora-docs.patch | 7732 +++++++++++++++++++++++++++++++ freeradius.spec | 8 +- 2 files changed, 7739 insertions(+), 1 deletion(-) create mode 100644 freeradius-no-antora-docs.patch diff --git a/freeradius-no-antora-docs.patch b/freeradius-no-antora-docs.patch new file mode 100644 index 0000000..a7f08f9 --- /dev/null +++ b/freeradius-no-antora-docs.patch @@ -0,0 +1,7732 @@ +From: Antonio Torres +Date: Tue, 2 Apr 2024 +Subject: Remove Antora docs from sources + +These files are meant to be used for upstream web documentation, so we don't need them for +distribution in RHEL. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2238511 +Signed-off-by: Antonio Torres +--- + doc/antora/antora.yml | 18 - + doc/antora/modules/ROOT/assets/images/favicon.svg | 104 --- + doc/antora/modules/ROOT/nav.adoc | 1 - + doc/antora/modules/ROOT/pages/directories.adoc | 69 -- + doc/antora/modules/ROOT/pages/index.adoc | 137 ---- + doc/antora/modules/howto/nav.adoc | 19 - + doc/antora/modules/howto/pages/index.adoc | 17 - + .../modules/howto/pages/protocols/dhcp/enable.adoc | 213 ----- + .../modules/howto/pages/protocols/dhcp/index.adoc | 35 - + .../modules/howto/pages/protocols/dhcp/policy.adoc | 14 - + .../protocols/dhcp/policy_common_options.adoc | 80 -- + .../protocols/dhcp/policy_device_options.adoc | 310 ------- + .../pages/protocols/dhcp/policy_ippool_access.adoc | 54 -- + .../protocols/dhcp/policy_ippool_creation.adoc | 112 --- + .../protocols/dhcp/policy_network_options.adoc | 237 ------ + .../protocols/dhcp/policy_subnet_options.adoc | 184 ----- + .../howto/pages/protocols/dhcp/prepare.adoc | 59 -- + .../modules/howto/pages/protocols/dhcp/test.adoc | 143 ---- + .../protocols/proxy/enable_proxy_protocol.adoc | 114 --- + .../howto/pages/protocols/proxy/enable_radsec.adoc | 188 ----- + .../modules/howto/pages/protocols/proxy/index.adoc | 126 --- + .../howto/pages/protocols/proxy/radsec_client.adoc | 181 ----- + .../pages/protocols/proxy/radsec_with_haproxy.adoc | 134 ---- + .../pages/protocols/proxy/radsec_with_traefik.adoc | 128 --- + doc/antora/modules/installation/nav.adoc | 5 - + .../modules/installation/pages/dependencies.adoc | 58 -- + doc/antora/modules/installation/pages/index.adoc | 15 - + .../modules/installation/pages/packages.adoc | 22 - + doc/antora/modules/installation/pages/source.adoc | 199 ----- + doc/antora/modules/installation/pages/upgrade.adoc | 737 ----------------- + doc/antora/modules/unlang/.gitignore | 1 - + doc/antora/modules/unlang/nav.adoc | 51 -- + doc/antora/modules/unlang/pages/attr.adoc | 77 -- + doc/antora/modules/unlang/pages/break.adoc | 28 - + doc/antora/modules/unlang/pages/case.adoc | 44 - + doc/antora/modules/unlang/pages/condition/and.adoc | 21 - + doc/antora/modules/unlang/pages/condition/cmp.adoc | 104 --- + doc/antora/modules/unlang/pages/condition/eq.adoc | 30 - + .../modules/unlang/pages/condition/index.adoc | 85 -- + doc/antora/modules/unlang/pages/condition/not.adoc | 19 - + .../modules/unlang/pages/condition/operands.adoc | 37 - + doc/antora/modules/unlang/pages/condition/or.adoc | 21 - + .../modules/unlang/pages/condition/para.adoc | 19 - + .../modules/unlang/pages/condition/regex.adoc | 180 ----- + .../unlang/pages/condition/return_codes.adoc | 35 - + doc/antora/modules/unlang/pages/default.adoc | 47 -- + doc/antora/modules/unlang/pages/else.adoc | 30 - + doc/antora/modules/unlang/pages/elsif.adoc | 43 - + doc/antora/modules/unlang/pages/foreach.adoc | 40 - + doc/antora/modules/unlang/pages/group.adoc | 39 - + doc/antora/modules/unlang/pages/if.adoc | 29 - + doc/antora/modules/unlang/pages/index.adoc | 162 ---- + doc/antora/modules/unlang/pages/keywords.adoc | 78 -- + doc/antora/modules/unlang/pages/list.adoc | 72 -- + doc/antora/modules/unlang/pages/load-balance.adoc | 32 - + doc/antora/modules/unlang/pages/module.adoc | 86 -- + .../modules/unlang/pages/module_builtin.adoc | 42 - + doc/antora/modules/unlang/pages/module_method.adoc | 27 - + .../unlang/pages/redundant-load-balance.adoc | 39 - + doc/antora/modules/unlang/pages/redundant.adoc | 42 - + doc/antora/modules/unlang/pages/return.adoc | 36 - + doc/antora/modules/unlang/pages/return_codes.adoc | 17 - + doc/antora/modules/unlang/pages/switch.adoc | 83 -- + .../modules/unlang/pages/type/all_types.adoc | 80 -- + doc/antora/modules/unlang/pages/type/double.adoc | 39 - + doc/antora/modules/unlang/pages/type/index.adoc | 117 --- + doc/antora/modules/unlang/pages/type/ip.adoc | 15 - + doc/antora/modules/unlang/pages/type/numb.adoc | 11 - + .../unlang/pages/type/string/backticks.adoc | 38 - + .../modules/unlang/pages/type/string/double.adoc | 68 -- + .../modules/unlang/pages/type/string/escaping.adoc | 14 - + .../modules/unlang/pages/type/string/single.adoc | 19 - + .../modules/unlang/pages/type/string/unquoted.adoc | 21 - + doc/antora/modules/unlang/pages/update.adoc | 160 ---- + .../modules/unlang/pages/xlat/alternation.adoc | 24 - + .../modules/unlang/pages/xlat/attribute.adoc | 54 -- + doc/antora/modules/unlang/pages/xlat/builtin.adoc | 891 --------------------- + .../modules/unlang/pages/xlat/character.adoc | 80 -- + doc/antora/modules/unlang/pages/xlat/index.adoc | 56 -- + doc/antora/modules/unlang/pages/xlat/module.adoc | 18 - + .../modules/unlang/partials/rcode_table.adoc | 39 - + 81 files changed, 7153 deletions(-) + +diff --git a/doc/antora/antora.yml b/doc/antora/antora.yml +deleted file mode 100644 +index e345e9c4cc..0000000000 +--- a/doc/antora/antora.yml ++++ /dev/null +@@ -1,18 +0,0 @@ +-# +-# Metadata for the freeradius-server component +-# Examples of other components are the PAM module, +-# apache module, and the client library. +-# +-name: freeradius-server +-title: The FreeRADIUS Server +-version: '3.2.3' +-start_page: ROOT:index.adoc +-nav: +-- modules/ROOT/nav.adoc +-- modules/installation/nav.adoc +-- modules/concepts/nav.adoc +-- modules/howto/nav.adoc +-- modules/tutorials/nav.adoc +-- modules/unlang/nav.adoc +-- modules/developers/nav.adoc +-- modules/raddb/nav.adoc +diff --git a/doc/antora/modules/ROOT/assets/images/favicon.svg b/doc/antora/modules/ROOT/assets/images/favicon.svg +deleted file mode 100644 +index 7476355932..0000000000 +--- a/doc/antora/modules/ROOT/assets/images/favicon.svg ++++ /dev/null +@@ -1,104 +0,0 @@ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/doc/antora/modules/ROOT/nav.adoc b/doc/antora/modules/ROOT/nav.adoc +deleted file mode 100644 +index 3d924122c1..0000000000 +--- a/doc/antora/modules/ROOT/nav.adoc ++++ /dev/null +@@ -1 +0,0 @@ +-* xref:index.adoc[Introduction] +diff --git a/doc/antora/modules/ROOT/pages/directories.adoc b/doc/antora/modules/ROOT/pages/directories.adoc +deleted file mode 100644 +index 9b16249044..0000000000 +--- a/doc/antora/modules/ROOT/pages/directories.adoc ++++ /dev/null +@@ -1,69 +0,0 @@ +-= Directories +- +-The directories in the server source are laid out ad follows: +- +-== Documentation +- +-[width="100%",cols="50%,50%",options="header",] +-|=== +-| Directory | Description +-| `doc/` | Various snippets of documentation. +-| `doc/introduction/` | Concepts and introduction to FreeRADIUS. +-| `doc/raddb/` | HTML versions of the configuration files. +-| `doc/developers/` | Developer documentation for internal APIs +-| `doc/unlang/` | The unlang processing language. +-| `doc/upgrade/` | How to upgrade from version 3 to version 4. +-| `doc/rfc/` | Copies of the RFC’s. If you have Perl, do a `make` in +- that directory, and look at the HTML output. +-| `doc/antora/` | Metadata and documentation source files to build +- an Antora based documentation site. +-| `doc/doxygen/` | Files to build a Doxygen site from the source code. +-| `man/` | Unix Manual pages for the server, configuration files, +- and associated utilities. +-|=== +- +-== Utility +- +-[cols=",",options="header",] +-|=== +-|Directory | Description +-| `mibs/` | SNMP Mibs for the server. +-| `scripts/` | Sample scripts for startup and maintenance. +-|=== +- +-== Configuration +- +-[width="100%",cols="50%,50%",options="header",] +-|=== +-| Directory | Description +-| `raddb/` | Sample configuration files for the server. +-| `raddb/mods-available` | Module configuration files. +-| `raddb/mods-enabled` | Directory containing symlinks to `raddb/mods-available`. +- Controls which modules are enabled. +-| `raddb/sites-available` | Virtual servers. +-| `raddb/sites-enabled` | Directory containing symlinks to `raddb/sites-available`. +- Control which virtual servers are enabled. +-|=== +- +-== Packaging +- +-[cols=",",options="header",] +-|=== +-|Directory | Description +-| `debian/` | Files to build a `freeradius` Debian Linux package. +-| `redhat/` | Additional files for a RedHat Linux system. +-| `suse/` | Additional files for a SuSE (UnitedLinux) system. +-|=== +- +-== Source +- +-[cols=",",options="header",] +-|=== +-|Directory | Description +-| `src/` | Source code. +-| `src/bin/` | Source code for the daemon and associated utilities. +-| `src/lib/` | Source code for various utility libraries. +-| `src/include/` | Header files. +-| `src/protocols/` | Dynamic frontend plug-in modules. +-| `src/modules/` | Dynamic backend plug-in modules. +-|=== +diff --git a/doc/antora/modules/ROOT/pages/index.adoc b/doc/antora/modules/ROOT/pages/index.adoc +deleted file mode 100644 +index e9bc7a0954..0000000000 +--- a/doc/antora/modules/ROOT/pages/index.adoc ++++ /dev/null +@@ -1,137 +0,0 @@ +-= Introduction +- +-This is the documentation for FreeRADIUS, version 3. The documentation +-is available under the Creative Commons Non-Commercial license, as given +-in the `LICENSE` file in this directory. +- +-FreeRADIUS is a complex piece of software with many configuration +-options. However, we have taken great care to make the default +-configuration work in most circumstances. The result is that for most +-simple systems, it is trivial to install and configure the server. For +-those situations, this documentation will serve to answer basic +-questions about functionality, configuration, etc. +- +-For more complex requirements, FreeRADIUS can be difficult to +-configure. The reason for this difficulty is that the server can do +-almost anything, which means that there are a near-infinite number of +-ways to configure it. The question for an administrator, then, is what +-piece of the configuration to change, and how to change it. +- +-This documentation will answer those questions. The FreeRADIUS team has +-put substantial effort into writing the documentation for this release. +-Everything in the server is fully documented, and there are many +-`how-to` guides available. +- +-The documentation is split into sections by subject area, oganized by +-desired outcome. At a high level, the subject areas describe: +- +-* xref:concepts:index.adoc[Concepts] and introduction for newcomers. +-* xref:installation:index.adoc[Installing] and xref:installation:upgrade.adoc[upgrading] FreeRADIUS. +-* The syntax of the xref:unlang:index.adoc[unlang] processing language. +-* The xref:raddb:index.adoc[configuration files] located in `/etc/raddb/`, or `/etc/freeradius/` +-* Various xref:howto:index.adoc[how-to] guides. +-* xref:developers:index.adoc[Developer documentation]. +- +-This organization means that for example, the `ldap` module will have +-documention located in multiple places. We feel that organizing the +-documentation by desired _goal_ is better than the alternatives. +- +-Within each section, the documentation is split into small pages, which +-are generally no more than a few screens worth of information. We feel +-that having multiple small pages with cross-links is more helpful than +-having a smaller number of enormous pages. This division ensures that +-(for example) the `how-to` guides are split into a series of small +-steps, each of which can be performed quickly. +- +-We hope that this extended documentation will address any lingering +-concerns about the quality of the FreeRADIUS documentation. +- +-== Changes From Earlier Versions +- +-Administrators who have version 2 and wish to upgrade to version 3 +-should read the xref:installation:upgrade.adoc[upgrading] documentation. +-That documentation explains the differences between the two versions, and +-how an existing configuration can be reproduced in the latest +-release. We do _not_ recommend using version 2 configuration files +-with version 3. The configuration files are _not_ compatible across a +-major version upgrade. +- +-== Getting Started with FreeRADIUS +- +-FreeRADIUS can be installed using the pre-built packages available +-from http://packages.networkradius.com[Network RADIUS, +-window="_blank"]. That page contains packages for all common OS +-distributions. New packages are available as soon as a new version +-has been released. Packages for older releases are also available for +-historical purposes. +- +-FreeRADIUS can also be installed from the source code. Please see the +-xref:installation:index.adoc[installation guide] for instructions. +- +-WARNING: Many Operating System distributions ship versions of FreeRADIUS +-which are years out of date. Those versions may contain bugs which have +-been fixed in newer releases. We recommend using the +-http://packages.networkradius.com[Network RADIUS, window="_blank"] packages where +-possible. +- +-Administrators who are new to FreeRADIUS should read the +-xref:concepts:index.adoc[concepts section] as it describes the concepts behind +-FreeRADIUS. It is vital for newcomers to understand these concepts, as the rest +-of the documentation assumes familiarity with them. +- +-A detailed xref:unlang:index.adoc[unlang] reference guide is also available. +-This section describes the syntax and functionality of the keywords, +-data types, etc. used in the `unlang` processing language. +- +-All of the xref:raddb:index.adoc[configuration files] are available in +-hypertext format. In can often be easier to read the configuration files +-in a nicely formatted version, instead of as a fixed-width font in a +-text editor. +- +-For specific problem solving, we recommend the xref:howto:index.adoc[how-to] +-guides. These guides give instructions for reaching high-level goals, or +-for configuring and testing individual xref:howto:modules/index.adoc[modules]. +- +-There is also xref:developers:index.adoc[developer documentation]. This section +-documents the APIs for developers. Most people can ignore it. +- +-== Debugging +- +-If you have ANY problems, concerns, or surprises when running the +-server, the the server should be run in debugging mode as root, from the +-command line: +- +-``` +-# radiusd -X +-``` +- +-It will produce a large number of messages. The answers to many +-questions, and the solution to many problems, can usually be found in +-these messages. When run in a terminal window, error messages will be +-shown in red text, and warning messages will be shown in yellow text. +- +-For other use-cases, please look for `ERROR` or `WARNING` in the +-debug output. In many cases, those messages describe exactly what is +-going wrong, and how to fix it. +- +-For further details, about the debug output see the +-http://wiki.freeradius.org/radiusd-X[radiusd-X, window="_blank"] page on the +-http://wiki.freeradius.org[wiki, window="_blank"]. +- +-== Getting Help +- +-We also recommend joining the +-http://lists.freeradius.org/mailman/listinfo/freeradius-users[mailing +-list] in order to ask questions and receive answers. The developers are +-not on Stack Overflow, IRC, or other web sites. While the FreeRADIUS +-source is available on +-https://github.com/FreeRADIUS/freeradius-server/[GitHub, window="_blank"], questions +-posted there will not be answered. +- +-Before posting to the list, please read the +-http://wiki.freeradius.org/list-help[list help, window="_blank"] page. That page explains +-how to run the server in debugging mode; how to understand the debug +-output; and what information to post to the list. +- +-Commercial support for FreeRADIUS is available from +-https://networkradius.com/freeradius-support/[Network RADIUS, window="_blank"]. +diff --git a/doc/antora/modules/howto/nav.adoc b/doc/antora/modules/howto/nav.adoc +deleted file mode 100644 +index 351200b292..0000000000 +--- a/doc/antora/modules/howto/nav.adoc ++++ /dev/null +@@ -1,19 +0,0 @@ +-* xref:index.adoc[Howto Guides] +-** Protocols +-**** xref:protocols/dhcp/index.adoc[DHCP] +-***** xref:protocols/dhcp/prepare.adoc[Preparation] +-***** xref:protocols/dhcp/enable.adoc[Enabling the DHCP service] +-***** xref:protocols/dhcp/test.adoc[Testing the DHCP service] +-***** xref:protocols/dhcp/policy.adoc[Defining the DHCP policy] +-****** xref:protocols/dhcp/policy_ippool_creation.adoc[IP pool creation] +-****** xref:protocols/dhcp/policy_common_options.adoc[Common options] +-****** xref:protocols/dhcp/policy_network_options.adoc[Network options and IP pool selection] +-****** xref:protocols/dhcp/policy_subnet_options.adoc[Subnet options] +-****** xref:protocols/dhcp/policy_device_options.adoc[Device, class and group options] +-****** xref:protocols/dhcp/policy_ippool_access.adoc[IP pool access restriction] +-**** xref:protocols/proxy/index.adoc[PROXY Protocol] +-***** xref:protocols/proxy/enable_radsec.adoc[Enabling RadSec] +-***** xref:protocols/proxy/radsec_client.adoc[Configuring a test RadSec client] +-***** xref:protocols/proxy/radsec_with_haproxy.adoc[Proxying RadSec with HAproxy] +-***** xref:protocols/proxy/radsec_with_traefik.adoc[Proxying RadSec with Traefik] +-***** xref:protocols/proxy/enable_proxy_protocol.adoc[Enabling PROXY Protocol for RadSec] +diff --git a/doc/antora/modules/howto/pages/index.adoc b/doc/antora/modules/howto/pages/index.adoc +deleted file mode 100644 +index 47a51460c1..0000000000 +--- a/doc/antora/modules/howto/pages/index.adoc ++++ /dev/null +@@ -1,17 +0,0 @@ +-= Howto Guides +- +-The documents in this section describe how to perform various common tasks with +-FreeRADIUS. They also provide worked examples on using the various modules in +-common deployment scenarions. +- +-If you have a topic you'd like to see included in the list of howtos, contact +-the developers on the +-link:http://lists.freeradius.org/mailman/listinfo/freeradius-users[User's +-mailing list]. +- +-Some of the documents here started life as pages on +-link:http://wiki.freeradius.org[wiki.freeradius.org]. If you've just been +-through a particularly arduous service configuration and deployment, and would +-like to help your fellow users, then please create a new how to on the wiki. +-If it's popular enough, we'll include it in the official documentation for the +-next release. +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/enable.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/enable.adoc +deleted file mode 100644 +index 2824bd0f48..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/enable.adoc ++++ /dev/null +@@ -1,213 +0,0 @@ +-== Enabling the DHCP service +- +-A major difference between configuring FreeRADIUS as a DHCP server versus most +-other DHCP software such as ISC DHCP is that other software typically uses a +-single monolithic configuration file whereas FreeRADIUS has a collection of +-configuration files. This reflects the modularity of FreeRADIUS; attempting to +-put the entire configuration in a single file would result in a very difficult +-to read configuration. +- +-The root of the FreeRADIUS configuration may be in a different location on the +-filesystem depending on how FreeRADIUS has been installed. This directory will +-be referred to as `` below. The sample configuration files are well +-commented describing what each configuration option does. +- +-FreeRADIUS compiled from source will default to `/usr/local/etc/raddb`. +-Pre-built packages will default to either `/etc/raddb` or +-`/etc/freeradius`. +- +- +-=== Enable the DHCP virtual server +- +-The FreeRADIUS configuration separates each network service that it provides +-into "virtual servers". A number of sample virtual server definitions are +-provided in `/sites-available`, one of which is the sample +-configuration for a DHCP service. +- +-Sites may be added to the working configuration by either creating a symlink to +-them or copying them to `/sites-enabled` depending on how you wish to +-manage future upgrades. +- +-[TIP] +-==== +-As with other package-managed configuration files, package upgrades will not +-automatically replace files that you have edited but you will need to resolve +-any local differences. Creating copies avoids the need to resolve conflicts +-during a package upgrade. +-==== +- +-Add the DHCP virtual server to the active configuration: +- +-[source,shell] +----- +-cd /sites-enabled +-ln -s ../sites-available/dhcp . +----- +- +-or: +- +-[source,shell] +----- +-cd /sites-enabled +-cp ../sites-available/dhcp . +----- +- +-The sample configuration has been set up in such a way that it is initially +-safe. It will not actually take over live DHCP serving on the network when it +-is simply enabled until it is configured to do so. Rather is set up for testing +-prior to going live. +- +-The virtual server begins with a `listen` section. In this section your need to +-modify the following configuration items: +- +-`ipaddr`:: The IP address to listen on. +-`src_ipaddr`:: The source IP for unicast packets. +-`port`:: The port to listen on. Setting this to `67` will make the DHCP service live on the network. +-`interface`:: The network interface to listen on. +-`broadcast`:: Allow broadcast packets. For most live systems this will need to be set to `yes`. +- +-Below the `listen` section, there are sections that define how to respond to +-each of the DHCP packet types. Most installations will require that you review +-the settings for `DHCP-Discover` and `DHCP-Request`. +- +-Their contents contain directives in the FreeRADIUS policy language, "unlang". +-Many examples are provided which have been carefully described. +- +- +-=== Enable SQL and IP pool modules +- +-FreeRADIUS has many modules to support different aspects of the functionality +-required for the network protocols it can process. The two of most significance +-for DHCP are `dhcp_sql` and `dhcp_sqlippool`. As with virtual servers, a +-number of example module configurations are available in +-`/mods-available`. +-These should be symlinked or copied into `/mods-enabled` in order to +-enable them. +- +- +-==== Configure the `dhcp_sql` module +- +-Add the `dhcp_sql` module to the active configuration: +- +-[source,shell] +----- +-cd /mods-enabled +-ln -s ../mods-available/dhcp_sql . +----- +- +-or: +- +-[source,shell] +----- +-cd /mods-enabled +-cp ../mods-available/dhcp_sql . +----- +- +-The `dhcp_sql` module should be configured with the connection parameters for +-whichever database is to be used. The key configuration items are: +- +-`dialect`:: Which SQL dialect is in use. +-`driver`:: Which driver to use to access the database. For most databases this +- is `rlm_sql_`, however Microsoft SQL Server has a choice of +- drivers. +- +-Then, there are configuration options that are unique to each database, +-including connection details. For most databases these are: +- +-`server`:: The host name or IP address of the database server. +-`port`:: The port to connect to the database server on. +-`login`:: The user name used to connect to the database. +-`password`:: The password for authenticating to the database. +-`radius_db`:: The name of the database. +- +-[NOTE] +-==== +-SQLite does not use these connection options, rather the `filename` +-option within the `sqlite` section is used to determine where the database +-will be stored. +-==== +- +- +-==== Configure the `dhcp_sqlippool` module +- +-Add the `dhcp_sqlippool` module to the active configuration: +- +-[source,shell] +----- +-cd /mods-enabled +-ln -s ../mods-available/dhcp_sqlippool . +----- +- +-or +- +-[source,shell] +----- +-cd /mods-enabled +-cp ../mods-available/dhcp_sqlippool . +----- +- +-The `dhcp_sqlippool` module must be configured. The key configuration +-items are: +- +-`dialect`:: Set this to the same SQL dialect as in the `sql` module. +-`offer_duration`:: How long an IP is offered to the client in a DHCP OFFER. +-`lease_duration`:: How long an IP is leased to the client in a DHCP ACK. +- +- +-=== Provision the database +- +-You should provision your database by creating a user for FreeRADIUS (matching +-the configuration that you have previously provided) and then loading the +-schema. The procedure for doing this will vary according to the database +-server. +- +-The schema, stored procedure definition and any additional setup scripts for +-your database are in `/mods-config/sql/ippool-dhcp/{dialect}/`. +- +-=== Test FreeRADIUS startup +- +-Once you have provisioned your schema, created a user account and granted +-access to the user, you should be able to start FreeRADIUS. +- +-If FreeRADIUS has been configured correctly then the output of `ss` will +-contain a line showing that FreeRADIUS is listening for DHCP packets on the +-designated interface on port 67: +- +-.Example of FreeRADIUS listening on `` for DHCP packets +-================================================================== +- # ss -lunp +- Netid Recv-Q Send-Q Local Address:Port ... +- udp 0 0 0.0.0.0%:67 ... users:(("radiusd",...)) +-================================================================== +- +-Note that if the database is inaccessible then FreeRADIUS will normally refuse +-to start. +- +-The FreeRADIUS wiki contains extensive information about debugging FreeRADIUS +-startup issues that we do not repeat in any detail here. +- +-Essentially, stop your init system from repeatedly trying to launch FreeRADIUS: +- +-[source,shell] +----- +-service radiusd stop +----- +- +-Then start FreeRADIUS manually in debug mode: +- +-[source,shell] +----- +-radiusd -X +----- +- +-Carefully read the output since this will tell you why FreeRADIUS was unable to +-start. +- +-Once you have fixed the issue start FreeRADIUS as normal: +- +-[source,shell] +----- +-service radiusd start +----- +- +-Now xref:protocols/dhcp/test.adoc[test the DHCP service] to ensure that it is responding to requests. +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/index.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/index.adoc +deleted file mode 100644 +index fde22024f0..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/index.adoc ++++ /dev/null +@@ -1,35 +0,0 @@ +-= FreeRADIUS DHCP server +- +-This guide describes how FreeRADIUS can be used in place of ISC DHCP or ISC Kea +-to provide a significantly more performant and, above all, more flexible DHCP +-server. +- +-This guide provides a suggested configuration that should be somewhat familiar +-to anyone who has previously implemented DHCP using the most frequently used +-features of other DHCP server software. +- +-The modular design of FreeRADIUS means that there is no one "right" way to +-implement the DHCP service. FreeRADIUS allows you to put together a "mix and +-match" approach. +- +-For example you can manage the leases in an SQL database. You might then hard +-code certain DHCP reply parameters within configuration and then look up +-additional parameters using a datastore such as: +- +- * a local file such as a structured text file or an SQLite database +- * an organisational LDAP directory +- * an SQL or "no SQL" database +- * a remote endpoint such as a RESTful HTTP API +- +-The policy language and modular configuration of FreeRADIUS is sufficiently +-powerful and that almost any aspect of the server's behaviour can be customised +-to implement even the most sophisticated DHCP configurations. +- +-== Sections in this guide +- +-This guide is organised into four parts that should be read in order: +- +-1. xref:protocols/dhcp/prepare.adoc[Preparation] +-2. xref:protocols/dhcp/enable.adoc[Enabling the DHCP service] +-3. xref:protocols/dhcp/test.adoc[Testing the DHCP service] +-4. xref:protocols/dhcp/policy.adoc[Defining the DHCP policy] +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy.adoc +deleted file mode 100644 +index d8f1bcb79a..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/policy.adoc ++++ /dev/null +@@ -1,14 +0,0 @@ +-== Defining the DHCP policy +- +-Now that FreeRADIUS is successfully running as a DHCP server it is necessary to +-configure a DHCP policy so that it returns correctly formed responses to the DHCP +-requests that it receives. +- +-This involves a number of steps: +- +- * xref:protocols/dhcp/policy_ippool_creation.adoc[Defining the IP address pools.] +- * xref:protocols/dhcp/policy_common_options.adoc[Defining the options that are common to all replies.] +- * xref:protocols/dhcp/policy_network_options.adoc[Defining the options for the network from which the request originates and ensuring that IP addresses are allocated from the correct pool.] +- * xref:protocols/dhcp/policy_subnet_options.adoc[Defining the options for the subnet to which this issued IP address belongs.] +- * xref:protocols/dhcp/policy_device_options.adoc[Defining the device, class and group based options specific to the device.] +- * xref:protocols/dhcp/policy_ippool_access.adoc[Using device properties to restrict access to certain pools.] +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy_common_options.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy_common_options.adoc +deleted file mode 100644 +index 949868d26a..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/policy_common_options.adoc ++++ /dev/null +@@ -1,80 +0,0 @@ +-== Configure common reply options +- +-FreeRADIUS includes a powerful xref:unlang/index.adoc[policy language] called +-"unlang". +- +-Statements in unlang may be used to call further policies, update attribute +-lists and invoke modules. There are also control flow statements (if, +-switch, etc.) typical of most imperative languages. +- +-FreeRADIUS has a number attribute lists that it maintains as it processes +-packets within the virtual server sections. Most relevant to DHCP are +-`request`, `control` and `reply`. +- +-The DHCP options from the current request packet are provided in the +-`request` list. This includes fixed DHCP parameters such as +-`DHCP-Client-Hardware-Address`, optional parameters such as +-`DHCP-Requested-IP-Address`, and parameters synthesised by FreeRADIUS such as +-`DHCP-Message-Type` and `DHCP-Network-Subnet`. +- +-DHCP options can be set by updating their value in the `reply` list. This +-forms the basis of the packet returned to the client. +- +-In the default DHCP server configuration, a "policy" (akin to a subroutine) is +-used to set common options for reply packets. The policy is found in +-`/policy.d/dhcp`. +- +-Look at the contents of the `dhcp_common` section and set any global options +-applicable to all clients in this policy. +- +-[source,unlang] +----- +-dhcp_common { +- update reply { +- &DHCP-Domain-Name-Server := 8.8.8.8 +- &DHCP-Domain-Name-Server += 8.8.4.4 +- &DHCP-Subnet-Mask := 255.255.255.0 +- &DHCP-Router-Address := 192.0.2.1 +- ... +- } +-} +----- +- +-Note, FreeRADIUS has four main operators for assigning values to attributes: +- +-`=`:: Add the attribute to the list, if and only if an attribute of the same +- name is not already present in that list. +-`:=`:: Add the attribute to the list. If any attribute of the same name is +- already present in that list it is replaced with the new one. +-`+=`:: Add the attribute to the tail of the list, even if attributes of the +- same name are already present in the list. +-`^=`:: Add the attribute to the head of the list, even if attributes of the +- same name are already present in the list. +- +-These operators allow for attributes to be set to default values and then +-overwritten, e.g. setting a default lease time, but then overwriting it for +-a particular group of clients. +- +-Attributes in the `control` list are not returned in the DHCP reply packets +-but instead govern aspects of server's behaviour. +- +-To use an SQL backend for either static or dynamic IP allocation, un-comment +-the block: +- +-[source,unlang] +----- +-update control { +- &Pool-Name := "local" +-} +-dhcp_sqlippool +----- +- +-The `Pool-Name` control attribute is used in looking up addresses in the +-database. The line containing `dhcp_sqlippool` is a call to invoke an +-instance of a module with that name. This module is responsible for assigning a +-free IP address into the `DHCP-Your-IP-Address` reply attribute from the pool +-identified by `Pool-Name`. +- +-Here `Pool-Name` is being set to a constant value (`local`) indicating +-that a single pool is to be used. If you have multiple pools, then replace this +-`update` block with logic to map clients to the correct pool, as described below. +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc +deleted file mode 100644 +index 05845ea893..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc ++++ /dev/null +@@ -1,310 +0,0 @@ +-== Configure "device", "class" and "group" options +- +-Beyond the global, network and subnet options already described, most sites +-will have a number of group or class based options, and have a requirement for +-setting reply parameters against individual devices. +- +-In general, FreeRADIUS does not differentiate between "classes" (memberships +-defined by some attribute of the DHCP request) and "groups" (memberships +-defined by some manually aggregation related devices, typically based on lists +-of MAC address). +- +-The sample DHCP configuration provided with FreeRADIUS makes use of an internal +-attribute `DHCP-Group-Name` to support the setting of different options for +-different groups of devices. +- +-In general the groups to which a device belongs is determined during the +-processing of a request and these are added as instances of the +-`DHCP-Group-Name` attribute. This may be by performing a test on one or more +-request parameters (akin to a "class"), hash-based lookup of up all of part of +-an attribute in a local list (akin to a "subclass"), or doing the same using a +-remote datastore (SQL, LDAP, REST API, etc). +- +-FreeRADIUS can then iterate over `DHCP-Group-Name` to set group-specific +-options. +- +-We describe some of these options in more detail. +- +-=== Directly in Policy +- +-Simple class options can be written directly into policy. This is most +-suited to those options that rarely change and are based on attributes in the +-request such as the `User-Class`. +- +-Consider the ISC DHCP configuration snippet: +- +-[source,iscdhcp] +----- +-filename "undionly.kpxe"; +-class "pxeclient" { +- match option substring(user-class,0,4); +-} +-subclass "pxeclient" "iPXE" { +- filename "http://my.web.server/boot_script.php"; +-} +----- +- +-Or the equivalent Kea configuration: +- +-[source,isckea] +----- +-"Dhcp4": { +- "option-data": [ +- { "name": "boot-file-name", "data": "undionly.kpxe" } +- ], +- "client-classes": [ +- { +- "name": "pxeclient", +- "test": "substring(option[77],0,4) == 'iPXE'", +- "option-data": [ +- { +- "name": "boot-file-name", +- "data": "http://my.web.server/boot_script.php" +- } +- ] +- } +- ] +- ... +-} +----- +- +-These define the "filename" DHCP option differently based on whether or not the +-supplied "user-class" option begins with "iPXE". +- +-FreeRADIUS provides multiple ways for this to be configured. +- +-For example, the following "unlang" policy implements the class options defined +-above: +- +-[source,unlang] +----- +-if (&DHCP-User-Class && "%{substring:&DHCP-User-Class 0 4}" == "iPXE") { +- update reply { +- &DHCP-Boot-Filename := "http://my.web.server/boot_script.php" +- } +-} else { +- update reply { +- &DHCP-Boot-Filename := "undionly.kpxe" +- } +-} +----- +- +-Policy-based configuration of DHCP options is also useful for complex matching. +-For example, the following Unlang sets the DHCP-Boot-Filename parameter based +-on the request's DHCP-Client-Identifier using regular expression captures, +-provided that it matches the given format: +- +-[source,unlang] +----- +-if (&DHCP-Client-Identifier && \ +- "%{string:DHCP-Client-Identifier}" =~ /^RAS([0-9])-site([A-Z])$/) { +- update reply { +- &DHCP-Boot-Filename := "rasboot-%{1}-%{2}.kpxe" +- } +-} +----- +- +-=== In Text Files +- +-The `files` module that has already been described for global, network and +-subnet options can also be used to apply options to groups of clients. +- +-Firstly we must defined a mapping from a set of clients clients to their +-respective groups. One option for this is to use the `passwd` module, for +-which a sample configuration is included. +- +-Firstly symlink or copy the module configuration +-`/mods-available/dhcp_passwd` into `/mods-enabled/`. The +-suggested configuration expects the group membership file to be in +-`/mods-config/files/dhcp_groups` and take the form of: +- +-[source,config] +----- +-|,, +-|, +----- +- +-i.e. one line for each group starting with the group name followed by a pipe +-character and then a comma-separated list of hardware addresses. +- +-The `allow_multiple_keys` option allows for a host to be a member of +-more than one group. +- +-Sample configuration for looking up group options is contained in +-`/policy.d/dhcp` in the `dhcp_group_options` policy and in +-`/mods-available/dhcp_files` as the `dhcp_set_group_options` instance. +- +-The same data file `/mods-config/files/dhcp` is used to lookup +-group options as was used for global and network options. In this instance, +-add entries with the group name as the key such as: +- +-[source,config] +----- +-group1 +- DHCP-Log-Server := 10.10.0.100, +- DHCP-LPR-Server := 10.10.0.200 +- +-group2 +- DHCP-LPR-Server := 192.168.20.200 +----- +- +-=== In the SQL Database +- +-Policy and files are both read during startup and editing them while +-FreeRADIUS is running will not result in any changes in behaviour. If +-you require regular changes to DHCP options, then storing them in +-an SQL database provides greater flexibility since the queries will be run in +-response to each DHCP packet rather than requiring the server to be restarted. +- +-DHCP reply options for devices (including network-specific options) can be +-fetched from SQL using an arbitrary lookup key. This can be performed multiple +-times as necessary using different contexts, for example to first set +-subnet-specific options and then to set group-specific options. +- +-The default schema contains three tables to support this: +- +-"dhcpreply" contains reply options for a given identifier (e.g. MAC Address): +- +-.dhcpreply table +-|=== +-|Identifier |Attribute |Op |Value |Context +- +-|`02:01:aa:bb:cc:dd` |`DHCP-Log-Server` |`:=` |`192.0.2.10` |`by-mac` +-|`02:01:aa:bb:cc:dd` |`DHCP-LPR-Server` |`:=` |`192.0.2.11` |`by-mac` +-|`02:01:aa:bb:cc:dd` |`Fall-Through` |`:=` |`Yes` |`by-mac` +-|=== +- +-"dhcpgroup" maps identifiers to a group of options that can be shared: +- +-.dhcpgroup table +-|=== +-|Identifier |GroupName |Priority |Context +- +-|`02:01:aa:bb:cc:dd` |`salesdept` |`10` |`by-mac` +-|=== +- +-"dhcpgroupreply" contains reply options for each group: +- +-.dhcpgroupreply table +-|=== +-|GroupName |Attribute |Op |Value |Context +- +-|`salesdept` |`DHCP-NTP-Servers` |`:=` |`192.0.2.20` |`by-mac` +-|`salesdept` |`DHCP-Log-Server` |`+=` |`192.0.2.21` |`by-mac` +-|`salesdept` |`DHCP-LPR-Server` |`^=` |`192.0.2.22` |`by-mac` +-|=== +- +-Within the context of assigning options directly to devices, as well as to +-manually-curated groups of devices keyed by their MAC address: +- +- - Place device-specific options in the "dhcpreply" table. +- - Add `Fall-Through := Yes` to the options in the "dhcpreply" table in order +- to trigger group lookups, which are disabled by default. +- - Place entries in the "dhcpgroup" `identifier = , groupname = , priority = +- ` in the "dhcpgroup" table to map a device to its groups by +- priority. +- - Place the grouped options in the "dhcpgroupreply" table. +- - For each of the above, set `Context` to something by which the option +- lookup is referred to in the policy, for example `Context = 'by-mac'`. +- +-For the above example you would add the following to the DHCP virtual server to +-perform reply option lookup using the device's MAC address against the `by-mac` +-context: +- +-[source,unlang] +----- +-update control { +- &DHCP-SQL-Option-Context := "by-mac" +- &DHCP-SQL-Option-Identifier := &request:DHCP-Client-Hardware-Address +-} +-dhcp_sql.authorize +----- +- +-In the above, the DHCP reply options would be assigned to a device with MAC +-address 02:01:aa:bb:cc:dd as follows: +- +- - Firstly, the `DHCP-Log-Server` option would be set to `192.0.2.10` and the +- `DHCP-LPR-Server` option set to `192.0.2.11`. +- - `Fall-Through` is set, so the group mapping is then queried which +- determines that the device belongs to a single `salesdept` group. +- - Finally, the options for the `salesdept` group are now merged, setting a +- `DHCP-NTP-Servers` option to `192.0.2.20`, appending an additional +- `DHCP-Log-Server` option set to `192.0.2.21`, and prepending an additional +- `DHCP-LPR-Server` option set to `192.0.2.22`. +- +-If instead you wanted to perform a "subclass" lookup based on the first three +-octets of the device's MAC address then with tables containing the following +-sample data you could invoke an SQL lookup as shown: +- +-."dhcpreply" table: +-|=== +-|Identifier |Attribute |Op |Value |Context +- +-|`000393` |`Fall-Through` |`:=` |`Yes` |`class-vendor` +-|`000a27` |`Fall-Through` |`:=` |`Yes` |`class-vendor` +-|`f40304` |`Fall-Through` |`:=` |`Yes` |`class-vendor` +-|=== +- +-."dhcpgroup" table: +-|=== +-|Identifier |GroupName |Priority |Context +- +-|`000393` |`apple` |`10` |`class-vendor` +-|`000a27` |`apple` |`10` |`class-vendor` +-|`f40304` |`google` |`10` |`class-vendor` +-|=== +- +-."dhcpgroupreply" table: +-|=== +-|GroupName |Attribute |Op |Value |Context +- +-|`apple` |`DHCP-Boot-Filename` |`:=` |`apple.efi` |`class-vendor` +-|`google` |`DHCP-Boot-Filename` |`:=` |`google.efi` |`class-vendor` +-|=== +- +- +-[source,unlang] +----- +-update control { +- &DHCP-SQL-Option-Context := "class-vendor" +- &DHCP-SQL-Option-Identifier := \ +- "%{substring:%{hex:&DHCP-Client-Hardware-Address} 0 6}" +-} +-dhcp_sql.authorize +----- +- +-The file `policy.d/dhcp` contains a policy named `dhcp_policy_sql` which +-provides further worked examples for different types of option lookups. +- +-=== Testing "device", "class" and "group" options +- +-You should now test that any device-related options that you have configured +-using the various methods available are applied successfully by generating +-packets containing those parameters based upon which the reply options are set. +- +-For example, to test the iPXE user class example above you might want to +-generate a request as follows: +- +-[source,shell] +----- +-cat < dhcp-packet-ipxe-boot.txt +-DHCP-Message-Type := DHCP-Discover +-DHCP-Client-Hardware-Address := 02:01:aa:bb:cc:dd +-DHCP-User-Class := "iPXE-class-abc" +-EOF +----- +- +-To which you would expect to see a response such as: +- +-.Example output from dhcpclient +-=============================== +- dhcpclient: ... +- ---------------------------------------------------------------------- +- Waiting for DHCP replies for: 5.000000 +- ---------------------------------------------------------------------- +- ... +- DHCP-Message-Type = DHCP-Offer +- DHCP-Your-IP-Address = 1.2.3.4 +- DHCP-Boot-Filename := "http://my.web.server/boot_script.php" +- ... +-=============================== +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_access.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_access.adoc +deleted file mode 100644 +index 40b8e3094a..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_access.adoc ++++ /dev/null +@@ -1,54 +0,0 @@ +-== Configure access restrictions for pools +- +-We can combine what we have learned in the preceeding sections to provide pools +-whose access is restricted in some way, for example to a particular class. +- +-Consider the ISC DHCP configuration snippet: +- +-[source,iscdhcp] +----- +-subnet 10.99.99.0 netmask 255.255.255.0 { +- pool { +- range 10.99.99.200 10.99.99.250; +- allow members of "printers"; +- } +- option routers 10.99.99.1; +-} +----- +- +-Or the equivalent Kea configuration: +- +-[source,isckea] +----- +-"Dhcp4": { +- "subnet4": [{ +- "subnet": "10.99.99.0/24", +- "pools": [ +- { +- "pool": "10.99.99.200 - 10.99.99.250", +- "client-class": "printers" +- } +- ], +- "option-data": [ +- { "name": "routers", "data": "10.10.0.1" } +- ] +- }], +- ... +-} +----- +- +-These define a subnet containing a single pool that is restricted to members of +-the "printers" class. (The definition for this class is omitted.) +- +-In FreeRADIUS, to filter access to this pool entries such as the following +-should included in the `/mods-config/files/dhcp` configuration file: +- +-[source,config] +----- +-network DHCP-Network-Subnet < 10.99.99.0/24, \ +- DHCP-Group-Name == "printers", Pool-Name := "printers-pool" +- DHCP-Router-Address := 10.99.99.1 +----- +- +-Note that any number of additional filters can be added to the initial "check" +-line to restrict matches to the network block. +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_creation.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_creation.adoc +deleted file mode 100644 +index e976873c12..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_creation.adoc ++++ /dev/null +@@ -1,112 +0,0 @@ +-=== Determine the IP pool plan +- +-Except for cases where all IP allocation is performed using a mapping from the +-device MAC address to a fixed IP address, the DHCP configuration will involve +-the use of one or more IP address pools. +- +-FreeRADIUS stores all the IP addresses in its pools in whichever database has +-been chosen. An instance of the `sqlippools` module is used to manage all pools +-within a single table (normally `dhcpippool`). Each row of this table +-corresponds to an IP address that is a member of some pool. The pools are +-distinguished by name, so the table has a column (`pool_name`) that denotes +-this. +- +-Each pool in this table should be composed of a set of equally valid IP +-addresses for the devices that are designated to be members of the pool. +- +-Firstly, consider the network locations to which distinct ranges of IP +-addresses must be allocated and provisionally assign a pool to each. +- +-Next, consider that many networks support multiple co-existing subnets without +-VLAN separation. We will call this a "shared-network" to use the original ISC +-DHCP parlance. In Microsoft DHCP contexts this is often referred to as a +-"multinet". +- +-Often in a shared-network the policy has no regard for which of the network's +-devices is allocated to which subnet. In this case we must create a single, +-combined pool containing all of the IP addresses from each subnet in that +-network. Since all addresses in a pool are treated equally this will mean that +-any IP address may be allocated to a device that is making a DHCP request from +-that network. The appropriate DHCP parameters for the subnet to which the IP +-address belongs is determined after allocation. +- +-There are sometimes shared-networks (or even single subnets) for which IP +-addresses belonging to any subnet may be technically suitable for any device, +-however some local policy wants to assigning them to a particular subnet, for +-example to provide loose segregation between classes of device. In this case we +-define multiple pools, one for each range of IP addresses whose devices needs to +-be differentiated. +- +-The choice of pool is ordinarily determined based on the network from which the +-request originates using a mapping from Layer 2 networks to the pool name +-provided by the user. The indicator for the originating network can be +-overridden when this alone is insufficient to implement the required pool +-selection policy such as when you need to differentiate the pool's users with +-more granularity that their Layer 2 network, such as by considering device +-attributes ("class" membership in ISC parlance) or Option 82 circuit data. +- +- +-=== Populate the IP Pools +- +-By this stage you should have derived a list of pools, the IP address ranges +-contained therein, and the means of selecting the pool to use based on the +-originating network and/or some additional criteria from the request. +- +-A helper Perl script is provided with FreeRADIUS that can be used to populate +-the pools provide that you are using the default schema. +- +-[source,shell] +----- +-rlm_sqlippool_tool -p -s -e \ +- -t (-d | -f [ -i ]) \ +- [ -c ] [ -x ] +----- +- +-If, for example, you had a range configured in ISC DHCP as: +- +-[source,iscdhcp] +----- +-range 10.0.0.5 10.0.0.199 +----- +- +-and you are using PostgreSQL as your database, and you wish to refer to this pool +-using the name `local`, this could be prepared with: +- +-[source,shell] +----- +-rlm_sqlippool_tool -p local -s 10.0.0.5 -e 10.0.0.199 -t dhcpippool -d postgresql +----- +- +-If the SQL module of FreeRADIUS is already configured then this can +-be referenced so that the tool is able to use the configured connection +-parameters to connect to the database and populate the pool: +- +-[source,shell] +----- +-rlm_sqlippool_tool -p local -s 10.0.0.5 -e 10.0.0.199 -t dhcpippool -f /etc/raddb +----- +- +-For installations that require multiple pools, `rlm_sqlippool_tool` can +-be called referencing a YAML file defining the pools. Comments at the +-head of `rlm_sqlippool_tool` explain the options in more detail. +- +-If static leases are required then these should be set up in the database +-such that the MAC address of the client should be set as the `pool_key` +-against the corresponding address and the `status` column of the row +-representing the address set to `static`. A helper perl script, +-`rlm_iscfixed2ippool` can be used to read an ISC DHCP config file and produce +-SQL to perform these changes or directly update the database: +- +-[source,shell] +----- +-rlm_iscfixed2ippool -c -t -k \ +- (-d | -f [-i ]) +----- +- +-For example, to read /etc/dhcp/dhcpd.conf and populate the configured +-FreeRADIUS database, using the mac as the identifier: +- +-[source,shell] +----- +-rlm_iscfixed2ippool -c /etc/dhcp/dhcpd.conf -t dhcpippool -k mac -f /usr/local/etc/raddb +----- +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy_network_options.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy_network_options.adoc +deleted file mode 100644 +index e2657a8cfe..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/policy_network_options.adoc ++++ /dev/null +@@ -1,237 +0,0 @@ +-== Configure network-specific options and IP pool selection +- +-In an environment where multiple networks (often VLANs) are in use, it is +-necessary to identify which network a client belongs to in order to assign an +-address from the correct pool. +- +-Consider the ISC DHCP configuration snippet: +- +-[source,iscdhcp] +----- +-option domain-name "example.org"; +- +-subnet 10.10.0.0 netmask 255.255.0.0 { +- range 10.10.1.10 10.10.10.254; +- range 10.10.100.10 10.10.110.254; +- option routers 10.10.0.1; +- option domain-name-servers 10.10.0.2, 10.10.0.3; +- default-lease-time 7200; +-} +----- +- +-Or the equivalent Kea configuration: +- +-[source,isckea] +----- +-"Dhcp4": { +- "option-data": [ +- { "name": "domain-name", "data": "example.org" } +- ], +- "subnet4": [{ +- "subnet": "10.10.0.0/16", +- "pools": [ { "pool": "10.10.1.10 - 10.10.10.254" }, +- { "pool": "10.10.100.10 - 10.10.110.254" } +- ], +- "option-data": [ +- { "name": "routers", "data": "10.10.0.1" }, +- { "name": "domain-name-servers", "data": "10.10.0.2, 10.10.0.3" } +- ], +- "valid-lifetime": 7200 +- }], +- ... +-} +----- +- +-These define a network consisting of a single subnet 10.10.0.0/16 containing two +-IP address pools 10.10.1.10 - 10.10.10.254 and 10.10.100.10 - 10.10.110.254. +-Requests that are determined to have originated from this network (e.g. because +-their `giaddr` belongs within the subnet) will be assigned the specified DHCP +-parameters and allocated an address from one of its ranges. +- +-To provide equivalent functionality, FreeRADIUS must identify the correct DHCP +-reply parameters as well as the name of the pool to be used for IP address +-assignment, based on the originating network of the request. +- +-The definition for this pool (the addresses contained within it, corresponding +-to the `range` statement in ISC DHCP and Kea) is specified entirely in the +-database: It is precisely the rows in the `dhcpippool` table with a particular +-`pool_name`. +- +-[TIP] +-==== +-As described previously, in FreeRADIUS a pool is a set of IP addresses that are +-equally valid with respect to the network policy; therefore, unlike ISC DHCP +-and ISC Kea, FreeRADIUS does not differentiate between the two `range`s. +-Instead we should have previously populated a single pool containing all of the +-IP addresses from both ranges. +-==== +- +-FreeRADIUS derives a request attribute called `DHCP-Network-Subnet` which +-honours the standard DHCP process for designating the choice of network, in +-order of preference: +- +- 1. Link Selection Suboption of Option 82 +- 2. IPv4 Subnet Selection Option +- 3. Gateway IP Address ("giaddr") +- 4. Client IP Address ("ciaddr", only set for unicast packets) +- +-If `DHCP-Network-Subnet` contains an IP address then this should be used as +-the basis of choosing a network. When there is no address in this attribute it +-can be assumed that the packet has been received from a client on the local +-LAN. +- +-The `files` module in FreeRADIUS provides a simple method to map +-`DHCP-Network-Subnet` to the corresponding pool based on its network +-membership, setting the appropriate options to return to clients. It can also +-set the global options. +- +-[TIP] +-==== +-In the case where an instance of the `files` module is used to get global +-default parameters, the `dhcp_common` policy becomes redundant so the +-statement calling the policy (by name) can be commented out in +-`/sites-enabled/dhcp`. +-==== +- +-To use the provided example `files` module instance for DHCP, symlink or copy +-`/mods-available/dhcp_files` into `/mods-enabled/` and then +-uncomment the calls to `dhcp_network` in `/sites-enabled/dhcp`. +- +-A template configuration file `/mods-config/files/dhcp` is also +-provided which should be adapted to suit your network topology. +- +-For the configuration above you may deduce the following configuration, which +-has been extended to include an initial default section for requests originating +-from directly-connected clients on the local LAN (192.168.20/24): +- +-[source,config] +----- +-network Pool-Name := "local" +- DHCP-Domain-Name := "example.org", +- DHCP-Subnet-Mask := 255.255.255.0, +- DHCP-Router-Address := 192.168.20.1, +- DHCP-Domain-Name-Server := 192.168.20.2, +- Fall-Through := yes +- +-network DHCP-Network-Subnet < 10.10.0.0/16, Pool-Name := "remote" +- DHCP-Subnet-Mask := 255.0.0.0, +- DHCP-Router-Address := 10.10.0.1, +- DHCP-Domain-Name-Server := 10.10.0.2, +- DHCP-Domain-Name-Server += 10.10.0.3, +- DHCP-IP-Address-Lease-Time := 7200 +----- +- +-Each block in the file starts with a line beginning with the key to be matched. +-In this case the keyword of `network` (defined earlier in `dhcp_networks` +-configuration) is used for each block, so each of the above blocks is a +-candidate during the search. +- +-There may be further filtering of the candidates in the form of ` +- `. In the case of the second block we match the +-`DHCP-Network-Subnet` to an enclosing subnet with +-`DHCP-Network-Subnet < `. Additional filters could be added as +-required, comma separated. +- +-Following the filters on the first line, attributes in the `control` list can +-be set using the syntax of ` := `. In this example this is +-used to specify the `Pool-Name` for choosing the appropriate IP pool to +-allocate an address from. +- +-Subsequent indented lines are attribute assignments for values in the `reply` +-list. Note that, apart from the last line, they are all terminated with a +-comma. +- +-The special option `Fall-Through` determines whether, following a match, +-other records are checked for a match. All lookups will match the entry +-with a key of `network` and no further filtering, so `Fall-Through` +-is set on that record in order that the other records will be tested +-to find subnet matches. +- +-=== Example packet processing +- +-For our example, we consider a request arriving from a DHCP relay within +-10.10.0.0/16. In the absence of any specific DHCP subnet selection options in +-the request, the `DHCP-Network-Subnet` attribute is calculated to be the +-relay's IP address, say 10.10.0.1. +- +-The request is matched against the first block, setting an initial pool name to +-"local", domain name to "example.org" and setting some additional global +-default parameters. By virtue of `Fall-Through` being set, the next block is +-considered. +- +-Since the network identifier is within the specified subnet (i.e. `10.10.0.1 < +-10.10.0.0/16`) this second block is matched. This block overrides the pool name +-setting it to "remote", overrides some other global defaults and sets the lease +-time to 7200 seconds. `Fall-Through` is not set, so we are now done with +-deriving the pool name and network options. +- +-When the `dhcp_sqlippool` module is called during DHCP DISCOVER processing (in +-`/sites-enabled/dhcp`) the `remote` pool will be used for IP address +-allocation. +- +-The assigned IP address and network parameters will subsequently be returned in +-the DHCP reply. +- +-=== Testing the pool operation and network-specific options +- +-Before proceeding further, you should test the operation of the IP pools and +-ensure that any network-specific reply attributes that you have configured are +-correctly set in replies. +- +-For example, if you have a single, flat pool you should test using sample +-packets for devices with different MAC addresses and/or Client Identifiers. +- +-[source,shell] +----- +-cat < dhcp-packet-1.txt +-DHCP-Message-Type := DHCP-Discover +-DHCP-Client-Hardware-Address := 02:01:11:11:11:11 +-DHCP-Client-Identifier := device1 +-EOF +----- +- +-[source,shell] +----- +-cat < dhcp-packet-2.txt +-DHCP-Message-Type := DHCP-Discover +-DHCP-Client-Hardware-Address := 02:01:22:22:22:22 +-DHCP-Client-Identifier := device2 +-EOF +----- +- +-Generate these packets as show previously using the dhcpclient tool and look +-for `DHCP-Your-IP-Address` in the DHCP responses to determine the IP address +-that has been offered. +- +-Ensure that the DHCP Offer responses contain unique IP addresses. Ensure that +-when these requests are resent within the lifetime of the initial offer that +-the reponses to the subsequent replies contain the original IP address that was +-in the initial offer to the device. +- +-Additionally, ensure that the DHCP Offers contain any network-specific +-parameters that you have specified. +- +-In the case that the policy contains multiple IP pools and network definitions +-for clients belonging to different Layer 2 networks (or indeed belonging to the +-same network but segregated according to some local policy) you should ensure +-that the devices are being mapped to the correct definition. +- +-For a typical policy that selects the IP pool and network options based on the +-originating network for the DHCP packet, explicitly specifying a network by +-including a `DHCP-Subnet-Selection-Option` parameter may avoid the need to test +-from a host within each individual network: +- +-[source,shell] +----- +-cat < dhcp-packet-network-10.10.10.0.txt +-DHCP-Message-Type := DHCP-Discover +-DHCP-Client-Hardware-Address := 02:01:aa:bb:cc:dd +-DHCP-Client-Identifier := abc123 +-DHCP-Subnet-Selection-Option := 10.10.10.0 +-EOF +----- +- +-For policies where the IP pool and network option selection is based on some +-custom criteria it is necessary to include different variations for the +-parameters on which the policy makes the decision. The testing example for the +-class-specific options later in this document provides such an example. +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy_subnet_options.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy_subnet_options.adoc +deleted file mode 100644 +index 1980e89cd0..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/policy_subnet_options.adoc ++++ /dev/null +@@ -1,184 +0,0 @@ +-== Configure subnet-specific options for shared networks +- +-In the case that shared-networks are in use, with the pool containing +-equally-valid IP addresses from multiple subnets, it is necessary to set the +-subnet-specific parameters such as `DHCP-Router-Address`, `DHCP-Subnet-Mask` +-and `DHCP-Broadcast-Address` based on the IP address that has been allocated. +- +-Consider the ISC DHCP configuration snippet: +- +-[source,iscdhcp] +----- +-option domain-name "example.org"; +- +-shared-network bigdept { +- +- option domain-name-servers 10.10.0.2, 10.10.0.3; +- default-lease-time 7200; +- +- subnet 10.30.10.0 netmask 255.255.255.0 { +- option routers 10.30.10.1; +- } +- subnet 10.30.20.0 netmask 255.255.255.0 { +- option routers 10.30.20.1; +- } +- range 10.30.10.10 10.30.10.254; +- range 10.30.20.10 10.30.20.254; +- +-} +----- +- +-Or the equivalent Kea configuration: +- +-[source,kea] +----- +-"Dhcp4": { +- "option-data": [ +- { "name": "domain-name", "data": "example.org" } +- ], +- "shared-networks": [{ +- "name": "bigdept", +- "option-data": [ +- { "name": "domain-name-servers", "data": "10.10.0.2, 10.10.0.3" } +- ], +- "valid-lifetime": 7200, +- "subnet4": [{ +- "subnet": "10.30.10.0/24", +- "pools": [ { "pool": "10.30.10.10 - 10.30.10.254" } ], +- "option-data": [ +- { "name": "routers", "data": "10.30.10.1" } +- ] +- }], +- "subnet4": [{ +- "subnet": "10.30.20.0/24", +- "pools": [ { "pool": "10.30.20.10 - 10.30.20.254" } ], +- "option-data": [ +- { "name": "routers", "data": "10.30.20.1" } +- ] +- }] +- }], +- ... +-} +----- +- +-As with the network to pool lookup, an instance of the `files` modules can be +-employed (this time after the allocation of an IP address) to set the correct +-reply parameters based on the subnet membership of the assigned address. +- +-To do this, we can use this section of `/mods-available/dhcp_files`: +- +-[source,config] +----- +-files dhcp_subnets { +- filename = ${modconfdir}/files/dhcp +- key = "subnet" +-} +----- +- +-Additionally, uncomment the `dhcp_subnets` policy in `/policy.d/dhcp`. +-This policy wraps the call to the `dhcp_subnets` files module with code that +-"tightens" the `DHCP-Network-Subnet` attribute by setting it to the +-just-allocated IP address. +- +-The relevant entries in the `/mods-config/files/dhcp` configuration +-file might then look something like this: +- +-[source,config] +----- +-network +- DHCP-Domain-Name := "example.org", +- Fall-Through := yes +- +-network DHCP-Network-Subnet < 10.30.0.0/16, Pool-Name := "bigdept" +- DHCP-Domain-Name-Server := 10.10.0.2, +- DHCP-Domain-Name-Server += 10.10.0.3, +- DHCP-IP-Address-Lease-Time := 7200 +- +-subnet DHCP-Network-Subnet < 10.30.10.0/24 +- DHCP-Router-Address := 10.30.10.1 +- +-subnet DHCP-Network-Subnet < 10.30.20.0/24 +- DHCP-Router-Address := 10.30.20.1 +----- +- +-=== Example packet processing +- +-For our example, we consider a request arriving from a DHCP relay within +-10.30.10.0/24. In the absence of any specific DHCP subnet selection options in +-the request, the `DHCP-Network-Subnet` attribute is calculated to be the +-relay's IP address, say 10.30.10.1. +- +-The request is matched against the first "network" block, setting the domain +-name to "example.org". By virtue of `Fall-Through` being set, the next "network" +-block is considered. +- +-Since the network identifier is within the specified subnet (i.e. `10.30.10.1 < +-10.30.0.0/16`) this second "network" block is matched. This block sets the pool +-name to "bigdept", sets some network-specific DNS resolvers and sets the lease +-time to 7200 seconds. `Fall-Through` is not set, so we are now done with +-deriving the pool name and network options. +- +-When the `dhcp_sqlippool` module is called during DHCP DISCOVER processing (in +-`/sites-enabled/dhcp`) the `bigdept` pool will be used for IP address +-allocation. +- +-After IP allocation the `dhcp_subnet` policy and files instance are called. +-Before the subnet options are looked up the `DHCP-Network-Subnet` +-attribute is tightened to match the assigned IP address, say 10.30.20.123. +- +-The request does not match the first subnet block since 10.30.20.123 is not +-within 10.30.10.0/24. However, the request does match the second subnet block +-since `10.30.20.123 < 10.30.20.0/24`. This block sets the default gateway +-reply parameter. `Fall-Through` is not set, so we are now done with deriving +-the pool name and network options. +- +-The assigned IP address, network and subnet parameters will subsequently be +-returned in the DHCP reply. +- +-=== Testing the subnet-specific options +- +-If you have set any subnet-specific reply parameters then you should test these +-before proceeding further. +- +-For example, in the case that you have a single, large pool spanning two IP +-subnets you might want to test by repeatedly allocating addresses using sample +-packets with different MAC addresses, each time checking to ensure that the +-DHCP parameters correspond to the IP address that has been offered. +- +-.Example output from dhcpclient showing a response +-================================================== +- dhcpclient: ... +- ... +- ---------------------------------------------------------------------- +- Waiting for DHCP replies for: 5.000000 +- ---------------------------------------------------------------------- +- ... +- DHCP-Your-IP-Address = 10.0.10.50 +- DHCP-Router-Address = 10.0.10.1 +- DHCP-Broadcast-Address = 10.0.10.255 +- DHCP-Subnet-Mask = 255.255.255.255 +-================================================== +- +- +-.Example output from dhcpclient showing a response +-================================================== +- dhcpclient: ... +- ... +- ---------------------------------------------------------------------- +- Waiting for DHCP replies for: 5.000000 +- ---------------------------------------------------------------------- +- ... +- DHCP-Your-IP-Address = 10.99.99.50 +- DHCP-Router-Address = 10.99.99.1 +- DHCP-Broadcast-Address = 10.99.99.255 +- DHCP-Subnet-Mask = 255.255.255.255 +-================================================== +- +- +-[TIP] +-==== +-If the subnets are large then you might want to temporarily reduce their +-size by setting the `status` field of the majority of the rows for each subnet +-to "`disabled`" to cause offers to be made more readily with IP addresses in +-different subnets. +-==== +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/prepare.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/prepare.adoc +deleted file mode 100644 +index aa43530a66..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/prepare.adoc ++++ /dev/null +@@ -1,59 +0,0 @@ +-== Preparation +- +-It is necessary to consider the requirements for the installation in order to +-devise an efficient and manageable set up. +- +-=== Understand the network topology +- +-When multiple networks (VLANs) are in use consideration must be given to how +-the correct "pool" (IP address ranges) from which to allocate addresses is +-identified. +- +-The policy for setting specific DHCP options (e.g. lease time, default gateway, +-time server and vendor-specific parameters) for different groups of hosts, +-based on their network or some device attributes either supplied in the DHCP +-requests or determined by dynamic lookup, should be well defined and +-understood. +- +-Other DHCP servers may implement implicit assumptions about the requirement of +-your network topology and silently define particular behaviours, such as the +-selection of IP address pool for a request based on a relay address. Some of +-these behaviours must be specifed explicitly when using FreeRADIUS. +- +-=== Choose a database backend +- +-FreeRADIUS stores its leases in an SQL database, so one of the key decisions to +-make is which database to use. +- +-FreeRADIUS supports: +- +- * SQLite +- * PostgreSQL +- * MySQL / MariaDB +- * Microsoft SQL Server +- * Oracle +- +-In most configurations the SQL database is likely to be the limiting component +-that restricts the IP allocation throughput of the overall system. Each +-database server has its own performance characteristics and unique approach to +-features such as high-availability. +- +-The choice of database should be made carefully based on the performance and +-high-availability requirements of the system, as well as any prior experience. +- +-[TIP] +-==== +-SQLite is an in-process database that uses the local file system, is simple to +-configure and is suitable for smaller installations. However, users with larger +-address pools or high availability requirements should choose one of the other +-standalone databases based on criteria such as performance, features, +-familiarity and your need for commercial support. +-==== +- +-FreeRADIUS ships with a default database schema and set of queries for each +-supported database. These are sufficient for most DHCP deployments but can be +-reviewed and modified as required to suit a particular situation, for example +-to customise the IP allocation policy such as by disabling address +-"stickiness". +- +-Now xref:protocols/dhcp/enable.adoc[enable the DHCP service]. +diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/test.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/test.adoc +deleted file mode 100644 +index 322de08fa9..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/dhcp/test.adoc ++++ /dev/null +@@ -1,143 +0,0 @@ +-== Testing the DHCP service +- +-We can verify that FreeRADIUS is providing a DHCP service using the +-`dhcpclient` tool that is included with the FreeRADIUS distribution. +- +-Temporarily configure FreeRADIUS to issue a single static IP address to all +-clients by updating the `dhcp DHCP-Discover` section in the `dhcp` virtual +-server to include the following: +- +-[source,unlang] +----- +-update reply { +- &DHCP-Your-IP-Address := 1.2.3.4 +-} +----- +- +-Define a sample DHCP packet as follows: +- +-[source,shell] +----- +-cat < dhcp-packet.txt +-DHCP-Message-Type := DHCP-Discover +-DHCP-Client-Hardware-Address := 02:01:aa:bb:cc:dd +-DHCP-Client-Identifier := abc123 +-EOF +----- +- +-We can now generate this packet by invoking one of the following commands based +-on the current circumstances... +- +-From the host that is running the FreeRADIUS DHCP server: +- +-[source,shell] +----- +-dhcpclient -i lo 255.255.255.255 -f dhcp-packet.txt -x auto +----- +- +-From a different host with an interface (eth0) in the same broadcast domain +-as the FreeRADIUS DHCP server: +- +-[source,shell] +----- +-dhcpclient -i eth0 255.255.255.255 -f dhcp-packet.txt -x auto +----- +- +-If all of the DHCP broadcast traffic in other Layer 2 networks is converted to +-unicast by DHCP relay agents then it is not necessary for FreeRADIUS to listen +-on a broadcast address. In this case you can test DHCP using a unicast request: +- +-[source,shell] +----- +-dhcpclient 192.0.2.10 -f dhcp-packet.txt -x auto +----- +- +-[NOTE] +-==== +-In order for the returned, unicast DHCP OFFER to be received it is necessary to +-ensure that the `DHCP-Your-IP-Address` parameter set by FreeRADIUS matches an +-address on the interface used by the dhcpclient tool to send the Discover +-packet. +-==== +- +-When one of the above commands is run, the tool with generate output such as +-the following which shows that the packet was sent and that it is now waiting +-for replies: +- +-.Example output from dhcpclient showing the request +-=================================================== +- dhcpclient: ... +- ---------------------------------------------------------------------- +- DHCP-Opcode = 0x01 +- DHCP-Hardware-Type = 0x01 +- DHCP-Hardware-Address-Length = 0x06 +- DHCP-Hop-Count = 0x00 +- DHCP-Transaction-Id = 0x5e0bbfab +- DHCP-Number-of-Seconds = 0x0000 +- DHCP-Flags = 0x0000 +- DHCP-Client-IP-Address = 0x00000000 +- DHCP-Your-IP-Address = 0x00000000 +- DHCP-Server-IP-Address = 0x00000000 +- DHCP-Gateway-IP-Address = 0x00000000 +- ... +- ---------------------------------------------------------------------- +- Waiting for DHCP replies for: 5.000000 +- ---------------------------------------------------------------------- +-=================================================== +- +- +-Each received DHCP response will generate output such as the following: +- +-.Example output from dhcpclient showing a response +-================================================== +- ... +- ---------------------------------------------------------------------- +- DHCP-Opcode = Server-Message +- DHCP-Hardware-Type = Ethernet +- DHCP-Hardware-Address-Length = 6 +- DHCP-Hop-Count = 0 +- DHCP-Transaction-Id = 1577828267 +- DHCP-Number-of-Seconds = 0 +- DHCP-Flags = 0 +- DHCP-Client-IP-Address = 0.0.0.0 +- DHCP-Your-IP-Address = 1.2.3.4 +- DHCP-Server-IP-Address = 192.0.2.10 +- DHCP-Gateway-IP-Address = 0.0.0.0 +- DHCP-Client-Hardware-Address = 02:42:0a:00:00:0b +- DHCP-Message-Type = DHCP-Offer +- DHCP-Client-Identifier = 0x616263313233 +- Waiting for additional DHCP replies for: 4.999429 +- ... +-================================================== +- +-Examine the DHCP response to ensure that it has the correct message type +-(`DHCP-Offer`, in this case), contains the temporary IP address that you +-configured earlier, i.e. `DHCP-Your-IP-Address = 1.2.3.4`, and any other +-expected reply parameters (which we configure later). You should also carefully +-examine the output of a FreeRADIUS debug session (`radius -X`) to ensure that +-the policy is being executed in the way that you expect and that no warnings +-are being generated. +- +-You can now change the content of the sample DHCP request by editing the +-`dhcp-packet.txt` file and re-run the above command to see the server's reply. +-You should examine the DHCP dictionary distrubuted with FreeRADIUS (usually +-`/usr/share/freeradius/dictionary.dhcp`) which provides the list of all of the +-DHCP parameters ("attributes") understood by FreeRADIUS. +- +-[WARNING] +-==== +-When you are done **remember** to remove the temporary edit that was made to +-the `dhcp` virtual server that provides the static IP assignment. +-==== +- +-=== Testing the DHCP policy +- +-The remainder of this guide describes how to configure the IP address plan, +-setup the IP pools and define a DHCP policy. You should develop your policy by +-making small, incremental changes to the provided configuration and then test +-those changes with the approach described above, using `dhcpclient` and `radius -X`, +-modifying the sample DHCP packet as required. If you break the policy then +-revert the last change, attempt to understand what went wrong, and try +-something else. +- +-Now xref:protocols/dhcp/policy.adoc[define the DHCP policy]. +diff --git a/doc/antora/modules/howto/pages/protocols/proxy/enable_proxy_protocol.adoc b/doc/antora/modules/howto/pages/protocols/proxy/enable_proxy_protocol.adoc +deleted file mode 100644 +index b6898247d5..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/proxy/enable_proxy_protocol.adoc ++++ /dev/null +@@ -1,114 +0,0 @@ +-== Enabling PROXY Protocol +- +-Now that we have a working configuration which used RadSec and HAproxy +-or Traefik, we are finally ready to enable PROXY Protocol. +- +-Configure FreeRADIUS on the `radsecsvr` host to expect the PROXY +-Protocol for RadSec connections. This is done by editing the `listen +-{}` section of the `tls` virtual server to include a reference to the +-proxy protocol: +- +-.Enabling PROXY Protocol in a FreeRADIUS virtual server +-======================================================= +- +- listen { +- ... +- proxy_protocol = true +- ... +- } +- +-======================================================= +- +-Now restart the debugging session: +-[source,shell] +----- +-radiusd -fxxl /dev/stdout +----- +- +- +-For HAproxy, you should enable the PROXY Protocol on connections to +-the RadSec backend, by editing the `backend` definition to add a +-`send-proxy` argument: +- +-.Example HAproxy backend configuration with PROXY Protocol +-========================================================== +- +- backend radsec_be +- mode tcp +- balance roundrobin +- server radsecsvr 172.23.0.3:2083 send-proxy +- +-========================================================== +- +-Note the `send-proxy` argument in the `server` definition. +- +-Now reload the HAproxy service: +- +-[source,shell] +----- +-service haproxy reload +---- +- +- +-For Traefik, enable the PROXY Protocol on connections to the RadSec +-backend by editing the `radsec-service` definition to add a reference +-to the proxy protocol" +- +-.Example Traefik service configuration with PROXY Protocol +-========================================================== +- +- radsec-service: +- loadBalancer: +- servers: +- - address: "172.23.0.3:2083" +- proxyProtocol: +- version: 1 +- +-========================================================== +- +-Note the `proxyProtocol` and `version: 1` directives. +- +-Traefik should automatically detect the updates and reconfigure the +-service. +- +- +-=== Testing RadSec connectivity via a proxy using PROXY Protocol +- +-Finally, with your test client configured to use the proxy, perform a +-test authentication: +- +-[source,shell] +----- +- echo "User-Name = bob" | radclient 127.0.0.1 auth testing123 +----- +- +-You should expect to see the familiar output: +- +-.Example output from radclient +-============================== +- +- Sent Access-Request Id 252 from 0.0.0.0:50118 to 127.0.0.1:1812 length 27 +- Received Access-Accept Id 252 from 127.0.0.1:1812 to 127.0.0.1:50118 length 39 +- +-============================== +- +-Now examine the FreeRADIUS debug output on the RadSec server: +- +-.Expected output from `radiusd -X` with PROXY Protocol +-====================================================== +- +- ... +- (0) (TLS) Received PROXY protocol connection from client \ +- 172.23.0.2:55343 -> 172.23.0.4:2083, via proxy 172.23.0.4:40268 -> 0.0.0.0:2083 +- ... +- (0) Received Access-Request Id 227 from 172.23.0.2:55343 to 172.23.0.4:2083 length 49 +- (0) Sent Access-Accept Id 227 from 172.23.0.4:2083 to 172.23.0.2:55343 length 0 +- ... +- +-====================================================== +- +-The output indicates that FreeRADIUS is receiving the originating +-connection information from the PROXY Protocol. FreeRADIUS then +-handles the RadSec requests as though they have been received directly +-from the originating client. +- +diff --git a/doc/antora/modules/howto/pages/protocols/proxy/enable_radsec.adoc b/doc/antora/modules/howto/pages/protocols/proxy/enable_radsec.adoc +deleted file mode 100644 +index f5e7603c10..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/proxy/enable_radsec.adoc ++++ /dev/null +@@ -1,188 +0,0 @@ +-== Enabling RadSec with FreeRADIUS +- +-Our first task is to set up a RadSec server by configuring an instance of +-FreeRADIUS to accept RADIUS over TLS requests. +- +-The following steps should be performed on the host which will be the +-RadSec server, we will call it `radsecsvr`. +- +-You can install FreeRADIUS using the NetworkRADIUS packages by +-following the instructions provided here: +- +- +- +-Before making any configuration changes, you should stop the radiusd +-service: +- +-[source,shell] +----- +- service radiusd stop +----- +- +-Then, enable the `tls` virtual server: +- +-[source,shell] +----- +-cd /etc/raddb/sites-enabled +-ln -s ../sites-available/tls +----- +- +-The FreeRADIUS distribution contains an example Certificate Authority +-that will have generated the necessary CA, server and client +-certificates and keys during package installation. You can use this +-CA, or you can use your own CA and certificates. +- +-[TIP] +-==== +-If the example certificates are not present (for example if FreeRADIUS was +-installed from source) then FreeRADIUS will fail to start. The files can be +-regenerated by running `make` in the `/etc/raddb/certs` directory. +-==== +- +-Edit the `tls` virtual server configuration, in order to add +-definitions for the clients by extending the `clients radsec {}` section: +- +-.Example radsec client definitions in `/etc/raddb/sites-available/tls` +-==== +- +- clients radsec { +- ... +- # Direct connections from the test client +- client radseccli { +- ipaddr = 172.23.0.2 +- proto = tls +- virtual_server = default +- } +- # Connections via HAproxy +- client haproxy { +- ipaddr = 172.23.0.4 +- proto = tls +- virtual_server = default +- } +- # Connections via Traefik +- client traefik { +- ipaddr = 172.23.0.5 +- proto = tls +- virtual_server = default +- } +- } +- +-==== +- +-The client `ipaddr` configuration item is used to match the source IP +-address of incoming connections. You must add client definitions for +-each of the clients which will connect. +- +-For RadSec, you can just list the IP address of the RadSec client. +-This client definition is used for processing RADIUS packets from the +-RadSec client. +- +-[NOTE] +-==== +-A `secret` does not have to be specified for RadSec clients, as the +-default is `radsec`. If you specify a secret, then that will be used +-instead of `radsec`. +-==== +- +-When the PROXY protocol is used, you must _also_ define a client which +-matches the IP address of the proxy (haproxy, etc). This client is +-only used to check that the source IP is permitted to connect to the +-server. Fields other than `ipaddr` can be specified (and in some +-cases may be required). However, all other fields will be ignored. +- +-For testing purposes, we want to amend the `default` virtual server so +-that it accepts all authentication reqeusts and immediately responds +-to accounting requests. +- +-Edit the `/etc/raddb/sites-enabled/default` file so that the beginning of +-the `authorize` and `preacct` sections looks as follows: +- +-.Example default virtual server modification to unconditionally accept Access-Requests +-==== +- +- authorize { +- accept +- ... +- } +- ... +- preacct { +- handled +- ... +- } +- +-==== +- +-This change makes the `authorize` section always "accept" the user, +-and makes the `preacct` section always say "we handled the accounting +-request". These changes are only for testing, and should never be +-used in production. +- +-Start the FreeRADIUS service in the foreground with debugging enabled: +- +-[source,shell] +----- +-radiusd -fxxl /dev/stdout +----- +- +-Examine the output from FreeRADIUS to ensure that it is now listening for +-RadSec connection on TCP/2083: +- +-.Example output from running `radiusd -fxxl /dev/stdout` +-==== +- +- FreeRADIUS Version 3.0.24 +- Copyright (C) 1999-2021 The FreeRADIUS server project and contributors +- ... +- ... : Debug: Listening on auth+acct proto tcp address * port 2083 (TLS) bound to server default +- ... : Debug: Listening on auth address * port 1812 bound to server default +- ... : Debug: Listening on acct address * port 1813 bound to server default +- ... : Debug: Listening on auth address :: port 1812 bound to server default +- ... : Debug: Listening on acct address :: port 1813 bound to server default +- ... +- ... : Info: Ready to process requests +- +-==== +- +-FreeRADIUS is now ready to process RadSec traffic. +- +-For testing, we first test normal RADIUS over UDP functionality, then +-the RadSec connection using a test client, then introduce a proxy +-server, and finally we enable PROXY Protocol. Doing the tests in this +-way ensures that we know that all previous steps work before trying +-the next step. This process allows us to quickly narrow down +-problems, and gets us to the final goal _faster_ than just "doing +-everything all at once". +- +-=== Testing the RADIUS policy +- +-Before moving on, verify that the FreeRADIUS policy is able to +-authenticate a local test RADIUS Access-Request over UDP: +- +-[source,shell] +----- +-echo "User-Name = terry" | radclient 127.0.0.1 auth testing123 +----- +- +-Due to the `accept` we added in the `authorize` section, the expected +-output should be an Access-Accept: +- +-.Expected output from radclient +-=============================== +- +- Sent Access-Request Id 157 from 0.0.0.0:36850 to 127.0.0.1:1812 length 27 +- Received Access-Accept Id 157 from 127.0.0.1:1812 to 127.0.0.1:36850 length 20 +- +-=============================== +- +-Any other output indicates that there is a problem with the FreeRADIUS +-configuration which *must* be solved before testing RadSec. Carefully verify that +-you have carried out each of the above steps correctly and examine the debug +-output from FreeRADIUS, which will usually tell you what is wrong. +- +-See [how to read the debug +-output](http://wiki.freeradius.org/radiusd-X) for instructions on +-reading amd understanding the debug output. +- +-The next step is to xref:protocols/proxy/radsec_client.adoc[configure +-FreeRADIUS as a RadSec test client] so that we can verify that our +-RadSec server is working. +diff --git a/doc/antora/modules/howto/pages/protocols/proxy/index.adoc b/doc/antora/modules/howto/pages/protocols/proxy/index.adoc +deleted file mode 100644 +index 5100635921..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/proxy/index.adoc ++++ /dev/null +@@ -1,126 +0,0 @@ +-= Proxying RadSec and enabling PROXY Protocol +- +-This guide shows how to set up FreeRADIUS to serve RadSec connections, fronted +-by either HAproxy or Traefik as Layer 4 proxies that pass on the original +-client connection information using PROXY Protocol. +- +-It is not a comprehensive guide to using RadSec with FreeRADIUS. It presents a +-basic configuration that uses an example CA and does not validate certificate +-attributes or perform revokation status. +- +- +-== Introduction +- +-FreeRADIUS supports receiving RADIUS requests over TLS-enabled TCP connections +-and supports proxying of requests over TCP connections to another TLS-enabled +-homeserver. The protocol for RADIUS over TLS is called "RadSec" and is defined +-in RFC 6614. +- +-FreeRADIUS is a capable and performant application-aware ("Layer 7") proxy / +-load-balancer for RadSec and other forms of RADIUS traffic. +- +- +-=== Layer 4 proxying +- +-Rather than use an application-aware proxy it is sometimes better to reduce the +-performance impact incurred by re-encoding an application protocol by using a +-"Layer 4" proxy that operates at the level of individual connections without +-regard for the application protocol. Such a proxy is more of a "bump in the +-wire" than a request buffer and minimises the latency incurred due to proxying. +- +-It is common to see software such as HAproxy and Traefik used in Layer 4 mode +-in place of FreeRADIUS for purposes such as connection load balancing. In +-addition to improved performance, these tools have the benefit that they +-typically support dynamic service discovery and "hitless" reloads to +-automatically adapt their connection routing based on changes to backend +-services such as the introduction of new nodes with even a momentary loss of +-service. +- +- +-=== Loss of connection information +- +-When TCP connections are relayed through Layer 4 proxies the information +-about the originating source of the connection is no longer known to the +-backend service, unless it is otherwise made available. Identifying the +-originator of connections is often necessary for security purposes and for +-request processing. +- +-Whilst many application protcols support headers that allow proxies to preserve +-connection information these are not helpful in the context of Layer 4 +-proxying: The process of populating headers requires knowledge of the +-application protocol to re-encode requests as they are transmitted between the +-frontend and backend connections. +- +- +-=== PROXY Protocol +- +-PROXY Protocol overcomes this limitation by allowing the original connection +-information to be provided to the backend at the start of the TCP connection. +-After this initial data is encoded the remainder of the conversation then +-proceeds as normal. However now that the connection information is known to the +-backend server it is able to process requests made on the connection as though +-the connection were being made directly by the client and not via the proxy. +- +-PROXY Protocol is specified in this document: +-http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt +- +- +-== Requirements +- +-PROXY Protocol Version 1 is supported by FreeRADIUS v3.0.24 and later versions. +- +-You will require the following set of VMs or containers, each with their own +-IP address: +- +-[cols="1,1,1"] +-|=== +-|Hostname|IP address|Purpose +- +-|radseccli +-|172.23.0.2 +-|FreeRADIUS configured to provide a RadSec test client +- +-|radsecsvr +-|172.23.0.3 +-|FreeRADIUS configured as a RadSec server +- +-|haproxy +-|172.23.0.4 +-|HAproxy in Layer 4 mode to the FreeRADIUS RadSec backend +-|=== +- +-Optionally you may want to configure a host to run Traefik within a Docker +-container using host mode networking, perhaps configured by Docker Compose, +-however the installation is beyond the scope of this guide: +- +-[cols="1,1,1"] +-|=== +-|traefik +-|172.23.0.5 +-|Traefik configured as a TCP router with TLS passthrough to the FreeRADIUS RadSec backend +-|=== +- +-The hostnames and IP addresses provided above are for examples purposes and are +-used throughout the remainder of this guide. This guide provides commands and +-output for CentOS. Other distributions will have minor differences, including +-the location of the FreeRADIUS configuration (the "raddb"). +- +-[NOTE] +-==== +-You can choose to use your own hostname, IP addresses and OS distribution. You +-could also use official Docker images provided by the respecitive projects, +-however these prescribe methods for configuring and managing the services +-that are not typical for a normal package installation which would provide a +-distraction if used for by guide. +-==== +- +- +-== Sections in this guide +- +-This guide is organised into four parts that should be read in order: +- +-1. xref:protocols/proxy/enable_radsec.adoc[Enabling RadSec] +-2. xref:protocols/proxy/radsec_client.adoc[Configuring a test RadSec client] +-3. xref:protocols/proxy/radsec_with_haproxy.adoc[Proxying RadSec with HAproxy] +-4. xref:protocols/proxy/radsec_with_traefik.adoc[Proxying RadSec with Traefik] +-5. xref:protocols/proxy/enable_proxy_protocol.adoc[Enabling PROXY Protocol for RadSec] +diff --git a/doc/antora/modules/howto/pages/protocols/proxy/radsec_client.adoc b/doc/antora/modules/howto/pages/protocols/proxy/radsec_client.adoc +deleted file mode 100644 +index d92345e9e8..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/proxy/radsec_client.adoc ++++ /dev/null +@@ -1,181 +0,0 @@ +-== Configuring FreeRADIUS as a RadSec test client +- +-Unfortunately, the `radclient` program does not support RadSec. We +-must therefore configure an instance of FreeRADIUS as a "transport +-converter" which proxies UDP-based RADIUS requests to a RadSec +-destination of our choice. +- +-The following steps should be performed on a client system, which we +-will call `radseccli`. This system should be a new system, with a +-different IP address. That is, you shoudl not edit the configuration +-on the `radsecsvr` host. Doing so will break the RadSec configuration. +- +-Install FreeRADIUS using the NetworkRADIUS packages by following the +-instructions provided here: +- +- +- +-Before making any configuration changes, you should stop the radiusd +-service: +- +-[source,shell] +----- +- service radiusd stop +----- +- +-Add a new `tls` home server definition, which will point to the RadSec +-server. We do this by creating a file +-`/etc/raddb/sites-enabled/radsec-homeserver` with the following +-contents: +- +-.Example homeserver, pool and realm definitions for the RadSec service +-==== +- +- home_server tls { +- ipaddr = 172.23.0.3 # IP address of our RadSec server +- port = 2083 +- type = auth+acct +- proto = tcp +- tls { +- private_key_password = whatever +- private_key_file = ${certdir}/client.pem +- certificate_file = ${certdir}/client.pem +- ca_file = ${cadir}/ca.pem +- } +- } +- home_server_pool tls { +- type = fail-over +- home_server = tls +- } +- realm tls { +- auth_pool = tls +- acct_pool = tls +- } +- +-==== +- +-[TIP] +-==== +-Complete descriptions of each of the above configuration items can be found in the +-`[raddb]/sites-available/tls` example configuration file. For simple tests, however, +-we can omit all of the comments from the file. +-==== +- +-To use this `tls` home server, we change the `default` virtual server to proxy +-all authentication and accounting requests to it. +- +-Edit the `/etc/raddb/sites-enabled/default` file so that the beginning of +-the `authorize` and `preacct` sections looks as follows: +- +-.Example default virtual server modification to proxy requests to a RadSec proxy server +-==== +- +- authorize { +- update control { +- &Proxy-To-Realm := tls +- } +- handled +- ... +- } +- ... +- preacct { +- update control { +- &Proxy-To-Realm := tls +- } +- handled +- ... +- } +- +-==== +- +-These changes make the `tls` virtual server always proxy packets. +-These changes are only for testing, and should never be used in +-production. +- +-We must now copy the example CA certificate as well as the client +-certificate and key files which are on the `radsecsrv` host to this +-test client. +- +-Replace the following files on `radseccli` with the equivalent files from +-`radsecsrv`: +- +-[cols="1,1,1"] +-|=== +-|File|Corresponding configuration item|Purpose +- +-|/etc/raddb/certs/ca.pem +-|`ca_file` +-|CA certificate which is used to authenticate the server certificate presented by the RadSec server to the client. +- +-|/etc/raddb/certs/client.pem +-|`certificate_file` +-|Client certificate (signed by the CA certificate) that is presented by the test client to the RadSec server. +- +-|/etc/raddb/certs/client.pem +-|`private_key_file` and `private_key_password` +-|Private key corresponding to the client certificate +-|=== +- +-Note that the client certificate and key are typically bundled into a single file. +- +-[CAUTION] +-==== +-If you do not correctly replace the CA, client certificate, and key +-material on the test client then the RadSec client and RadSec server +-will fail to mutually authenticate each other as they do not share a +-trusted CA. If you see messages like `unknown CA`, then you know that +-the certificates have not been set up correctly. +-==== +- +-Start the FreeRADIUS service in debug mode: +- +-[source,shell] +----- +-radiusd -X +----- +- +- +-=== Testing RadSec connectivity +- +-At this stage you should be able to cause the test client to send RadSec +-requests directly to the RadSec server. +- +-Run the following to send a RADUS (UDP) Access-Request to the local FreeRADIUS +-instance. It should then proxy the request over RadSec connection to +-the remote RadSec server: +- +-[source,shell] +----- +- echo "User-Name = bob" | radclient 127.0.0.1 auth testing123 +----- +- +-If the test client is able to successfully establish the RadSec +-connection, and the RadSec server replies with an Access-Accept +-response, then the output will be as follows: +- +-.Expected output from radclient +-=============================== +- +- Sent Access-Request Id 252 from 0.0.0.0:50118 to 127.0.0.1:1812 length 27 +- Received Access-Accept Id 252 from 127.0.0.1:1812 to 127.0.0.1:50118 length 39 +- +-=============================== +- +-Lack of response or an Access-Reject response indicates that the RadSec +-connection is not being established successfully. +- +-There may be serveral reasons for broken connectivity including: +- +- * The client not accepting the certificate presented by the server. +- * The server not accepting the certificate presented by the client. +- +-Look at the debug output generated by both the test client and the RadSec +-server. In many cases it will tell you exactly what the problem is. +- +-Do not proceed with any further steps until direct connections between the +-RadSec client and Radsec Server are working properly. +- +-Once things are working we are ready to +-xref:protocols/proxy/radsec_with_haproxy.adoc[configure HAproxy to proxy RadSec +-connections] or to xref:protocols/proxy/radsec_with_traefik.adoc[configure +-Traefik to proxy RadSec connections]. +diff --git a/doc/antora/modules/howto/pages/protocols/proxy/radsec_with_haproxy.adoc b/doc/antora/modules/howto/pages/protocols/proxy/radsec_with_haproxy.adoc +deleted file mode 100644 +index e58abfe53b..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/proxy/radsec_with_haproxy.adoc ++++ /dev/null +@@ -1,134 +0,0 @@ +-== Proxying RadSec with HAproxy +- +-This section shows how to configure HAproxy to proxy RadSec connections. +- +-The following steps should be performed on the `haproxy` host, unless otherwise +-stated. +- +-Install the HAproxy package supplied with the OS distribution: +- +-[source,shell] +----- +- yum install haproxy +----- +- +-Stop the haproxy service: +- +-[source,shell] +----- +- service haproxy stop +----- +- +-Modify the haproxy configuration (typically `/etc/haproxy/haproxy.conf`) so +-that it includes new frontend and backend configuration for the radsec service: +- +-.Example minimal HAproxy configuration +-====================================== +- +- global +- maxconn 100 +- defaults +- mode tcp +- timeout connect 10s +- timeout client 30s +- timeout server 30s +- frontend radsec_fe +- bind *:2083 +- default_backend radsec_be +- backend radsec_be +- balance roundrobin +- server radsecsvr 172.23.0.3:2083 +- +-====================================== +- +-Note the `mode tcp` directive which tells HAproxy to act as a Layer 4 +-proxy, so that it doesn't attempt to perform SSL termination or +-decode the RADIUS protocol. +- +-[NOTE] +-==== +-The above example is a minimal configuration. In practise you will want to +-retain many of the HAproxy configuration items already present in the +-configuration (e.g. `log`, `chroot`, `user`, `group`), but these vary across +-distributions. Other HTTP-related options that may already exist in the +-configuration will conflict with `mode tcp` (Layer 4 proxying) and should be +-removed if HAproxy complains about them. +- +-However, you should first get things working with the minimal +-configuration which is known to work, and then make customisations. +-If you start off with a complex configuration, then there may be a +-large number of things which are broken, and debugging them all will +-be difficult. Start simple, and then add complexity! +-==== +- +-Restart the haproxy service in foreground mode for debugging purposes: +- +-[source,shell] +----- +-haproxy -f /etc/haproxy/haproxy.cfg -db +----- +- +- +-=== Testing RadSec connectivity via HAproxy +- +-Now edit the test RadSec client, so that instead of making connections directly +-to the RadSec server it makes connections to the HAproxy server. +- +-On `radseccli` edit the `/etc/raddb/sites-enabled/tls` file, and set +-the IP address to the address of the `haproxy` host. +- +-.Example updated test client homeserver configuration +-===================================================== +- +- home_server tls { +- ipaddr = 172.23.0.4 # Updated from radsecsvr to haproxy +- ... +- } +- +-===================================================== +- +-Restart the debug mode session: +- +-[source,shell] +----- +-radiusd -X +----- +- +-Perform a test authentication: +- +-[source,shell] +----- +- echo "User-Name = bob" | radclient 127.0.0.1 auth testing123 +----- +- +-If the test client is able to successfully establish the RadSec +-connection via HAproxy, and the RadSec server replies with an +-Access-Accept response, then the output will be as follows: +- +-.Expected output from radclient +-=============================== +- +- Sent Access-Request Id 252 from 0.0.0.0:50118 to 127.0.0.1:1812 length 27 +- Received Access-Accept Id 252 from 127.0.0.1:1812 to 127.0.0.1:50118 length 39 +- +-=============================== +- +-HAproxy should also log a message that indicates that the connection was +-proxied, such as the following: +- +-.Expected output from HAproxy +-============================= +- +- <150>...: Connect from 172.23.0.2:50087 to 172.23.0.4:2083 (radius_fr/TCP) +- +-============================= +- +-Any other output from radclient or HAproxy indicates that there is a +-problem with the HAproxy configuration, or that FreeRADIUS is not +-accepting connection from the `haproxy` host, which must be solved +-before continuing. +- +-Once proxied connections are working we are ready to +-xref:protocols/proxy/enable_proxy_protocol.adoc[enable the PROXY +-Protocol] on both HAproxy and the RadSec server. +- +diff --git a/doc/antora/modules/howto/pages/protocols/proxy/radsec_with_traefik.adoc b/doc/antora/modules/howto/pages/protocols/proxy/radsec_with_traefik.adoc +deleted file mode 100644 +index 11030e92fd..0000000000 +--- a/doc/antora/modules/howto/pages/protocols/proxy/radsec_with_traefik.adoc ++++ /dev/null +@@ -1,128 +0,0 @@ +-== Proxying RadSec with Traefik +- +-This section shows how to configure Traefik to proxy RadSec connections. You +-should skip this section if you are not using Traefik as your proxy. +- +-Installing Traefik is beyond the scope of this guide. It is typically installed +-as a service mesh router within a Docker or Kubernetes environment using +-offical Docker images. +- +-Traefik configuration has two components of interest: +- +- * Static configuration: Defines "entrypoints" on which Traefik listens for connections. +- * Dynamic configuration: Defines backend service components and the routing policy. +- +-Traefik supports a number of providers of dynamic configuration data for the +-router and service definitions. For demonstration purposes the files provider +-is used here, however you can switch to another provide once you have things +-working using this method. +- +-The static configuration can be provided by starting Traefik with the following +-arguments: +- +-.Example Traefik static configuration +-===================================== +- +- traefik \ +- --log.level=DEBUG \ +- --providers.file.filename=/etc/traefik/dynamic_config.yml +- --providers.file.watch=true +- --entryPoints.radsec.address=:2083 +- +-===================================== +- +-Note that a `radsec` entrypoint is defined to listen on port 2083 and that a +-static `file` provider is used to defined the dynamic services. +- +-The backend for RadSec should be defined in this file as follows: +- +-.Example Traefik dynamic configuration +-====================================== +- +- tcp: +- routers: +- radsec-router: +- entryPoints: +- - radsec +- rule: "HostSNI(`*`)" +- service: "radsec-service" +- tls: +- passthrough: true +- services: +- radsec-service: +- loadBalancer: +- servers: +- - address: "172.23.0.3:2083" +- +-====================================== +- +-Note the `passthrough: true` directive under `tls:` which tells Treafik not to +-attempt TLS termination which it would otherwise perform for all incoming TLS +-connections. We require that the connection is passed through from the RadSec +-client to the RadSec server without being reterminated since the end client's +-certificate is authenticated by the RadSec server and many be used for +-policy decisions. +- +- +-=== Testing RadSec connectivity via Traefik +- +-Now amend the test RadSec client so that instead of making connections directly +-to the RadSec server it makes them via Traefik. +- +-On `radseccli` amend `/etc/raddb/sites-enabled/tls` and set the IP address to +-that of the `traefik` host. +- +-.Example updated test client homeserver configuration +-===================================================== +- +- home_server tls { +- ipaddr = 172.23.0.5 # Updated from radsecsvr to traefik +- ... +- } +- +-===================================================== +- +-Restart the debug mode session: +- +-[source,shell] +----- +-radiusd -X +----- +- +-Perform a test authentication: +- +-[source,shell] +----- +- echo "User-Name = bob" | radclient 127.0.0.1 auth testing123 +----- +- +-If the test client is able to successfully establish the RadSec connection via +-Traefik and the RadSec server replies with an Access-Accept response then the +-output will be as follows: +- +-.Example output from radclient +-============================== +- +- Sent Access-Request Id 252 from 0.0.0.0:50118 to 127.0.0.1:1812 length 27 +- Received Access-Accept Id 252 from 127.0.0.1:1812 to 127.0.0.1:50118 length 39 +- +-============================== +- +-Traefik should also log a message that indicates that the connection was +-proxied, such as the following: +- +-.Example output from Traefik +-============================ +- +- time="..." level=debug msg="Handling connection from 172.23.0.2:57367" +- +-============================ +- +-Any other output from radclient or Traefik indicates that there is a problem +-with the Traefik configuration or that FreeRADIUS is not accepting connection +-from the `traefik` host, which must be solved before continuing. +- +-Once proxied connections are working we are ready to +-xref:protocols/proxy/enable_proxy_protocol.adoc[enable the PROXY Protocol] on +-both Traefik and the RadSec server. +- +diff --git a/doc/antora/modules/installation/nav.adoc b/doc/antora/modules/installation/nav.adoc +deleted file mode 100644 +index 26ce32e54e..0000000000 +--- a/doc/antora/modules/installation/nav.adoc ++++ /dev/null +@@ -1,5 +0,0 @@ +-* xref:index.adoc[Installing and upgrading] +-** xref:packages.adoc[Install from packages] +-** xref:dependencies.adoc[Dependencies] +-** xref:source.adoc[Build from source] +-** xref:upgrade.adoc[Upgrading to v3] +diff --git a/doc/antora/modules/installation/pages/dependencies.adoc b/doc/antora/modules/installation/pages/dependencies.adoc +deleted file mode 100644 +index e910e76561..0000000000 +--- a/doc/antora/modules/installation/pages/dependencies.adoc ++++ /dev/null +@@ -1,58 +0,0 @@ +-= FreeRADIUS Dependencies +- +-Some external dependencies must be installed before building or +-running FreeRADIUS. The core depends on two mandatory libraries: +-`libtalloc` for memory management and `libkqueue` for event +-handling. +- +-Many of the modules also have optional dependencies. For example, +-the LDAP module requires LDAP client libraries to be installed +-and database modules need their respective database client +-libraries. +- +-If building from source code, the configure stage will check for +-the optional dependencies. Any missing libraries will cause that +-particular module to be skipped. +- +-== Libraries +- +-=== libtalloc +- +-Talloc is a memory allocation library available at +-https://talloc.samba.org/talloc/doc/html/index.html +- +-*OSX* +- +-`# brew install talloc` +- +-*Debian, Ubuntu and `dpkg`-based systems* +- +-`# apt-get install libtalloc-dev` +- +-*RedHat or CentOS* +- +-``` +-# subscription-manager repos --enable rhel-7-server-optional-rpms +-# yum install libtalloc-dev +-``` +- +-=== kqueue +- +-Kqueue is an event / timer API originally written for BSD systems. +-It is _much_ simpler to use than third-party event libraries. A +-library, `libkqueue`, is available for Linux systems. +- +-*OSX* +- +-_kqueue is already available, there is nothing to install._ +- +-*Debian, Ubuntu and `dpkg`-based systems* +- +-`# apt-get install libkqueue-dev` +- +-*RedHat or CentOS* +- +-``` +-# subscription-manager repos --enable rhel-7-server-optional-rpms +-# yum install libkqueue-dev +-``` +diff --git a/doc/antora/modules/installation/pages/index.adoc b/doc/antora/modules/installation/pages/index.adoc +deleted file mode 100644 +index b810078083..0000000000 +--- a/doc/antora/modules/installation/pages/index.adoc ++++ /dev/null +@@ -1,15 +0,0 @@ +-== Installation +- +-FreeRADIUS is available from multiple sources: +- +-* Official xref:packages.adoc[Network RADIUS packages] +-* xref:source.adoc[Source code] +-* Many Operating System distributions +- +-We highly recommend using the official packages from Network +-RADIUS, where available. +- +-The documents in this section cover details of the above +-installation methods, as well as instructions on building +-packages locally. +- +diff --git a/doc/antora/modules/installation/pages/packages.adoc b/doc/antora/modules/installation/pages/packages.adoc +deleted file mode 100644 +index ffc52cd8f3..0000000000 +--- a/doc/antora/modules/installation/pages/packages.adoc ++++ /dev/null +@@ -1,22 +0,0 @@ +-== Install from packages +- +-Network RADIUS provide pre-built binary packages of FreeRADIUS for +-common Linux distributions. This is the recommended installation +-method when packages are available for your system. +- +-The official http://packages.networkradius.com[Network RADIUS +-packages] page contains recent FreeRADIUS packages and +-installation instructions. +- +-=== Distribution-supplied packages +- +-While many Operating System distributions ship FreeRADIUS +-packages, the versions they include are often years out of date. +-As well as missing out on the latest bug fixes and features, this +-also means that it is very hard to know if an issue encountered is +-still a problem or if it is fixed in the latest release. +- +-Therefore, whilst the distribution-supplied packages can often be +-the most convenient to install, we do not usually recommend using +-them. +- +diff --git a/doc/antora/modules/installation/pages/source.adoc b/doc/antora/modules/installation/pages/source.adoc +deleted file mode 100644 +index cf40a792f4..0000000000 +--- a/doc/antora/modules/installation/pages/source.adoc ++++ /dev/null +@@ -1,199 +0,0 @@ +-== Building from Source +- +-We recommend xref:packages.adoc[installing from packages] if +-possible. Full instructions on building and installing from source +-code follow. +- +-The mandatory xref:installation:dependencies.adoc[dependencies] +-must be installed before FreeRADIUS can be built. These dependencies +-are `libtalloc` and `libkqueue`, which FreeRADIUS uses for memory +-management, and platform-independent event handling. +- +-Per-module dependencies that enable support for external services +-such as LDAP, SQL, etc, are optional. They must be installed for +-any modules that are to be used. The FreeRADIUS `./configure` step +-will automatically detect if each module has its dependencies met +-and automatically enable support for them. If the features you +-require are not enabled you should inspect the configure script +-output to figure out which additional development libraries need +-to be installed. +- +-The FreeRADIUS source may be obtained from a number of locations: +- +-* Download the latest version of the FreeRADIUS source from +- https://www.freeradius.org/releases/[the FreeRADIUS web site]; or +-* download directly from the +- ftp://ftp.freeradius.org/pub/freeradius/[FreeRADIUS FTP site]; or +-* download from +- https://github.com/FreeRADIUS/freeradius-server/[GitHub]. +- +-The file wil be name something like: `freeradius-server-3.0.22.tar.gz`. +-Later versions will be `3.0.23`, or `4.0.0`, etc. PGP signatures are +-also provided for official releases from the FTP site; these are +-named e.g. `freeradius-server-3.0.22.tar.gz.sig`. +- +-Un-tar the file, and change to the FreeRADIUS directory (where +-`VERSION` below is the version of the server that you have +-downloaded). +- +-[source,shell] +----- +-tar -zxf freeradius-server-VERSION.tar.gz +-cd freeradius-server-VERSION +----- +- +-Take the following steps to build and install the server from source: +- +-[source,shell] +----- +-./configure +-make +-sudo make install +----- +- +-=== Custom build +- +-FreeRADIUS has GNU autoconf support. This means you have to run +-`./configure`, and then run `make`. To see which configuration +-options are supported, run `./configure --help`, and read its output. +- +-The `make install` stage will install the binaries, the "man" pages, +-and _may_ install the configuration files. If you have not installed a +-RADIUS server before, then the configuration files for FreeRADIUS will +-be installed. +- +-If you already have a RADIUS server installed, then *FreeRADIUS +-WILL NOT over-write your current configuration.* +- +-The `make install` process will warn you about the files it could not +-install. +- +-If you see a warning message about files that could not be +-installed, then you *must* ensure that the new server is using the +-new configuration files and not the old configuration files, as +-this may cause undesired behavior and failure to operate correctly. +- +-The initial output from running in debugging mode (`radiusd -X`) +-will tell you which configuration files are being used. See +-xref:installation:upgrade.adoc[Upgrading] for information about +-upgrading from older versions. There _may_ be changes in the +-dictionary files which are required for a new version of the +-software. These files will not be installed over your current +-configuration, so you *must* verify and install any problem files by +-hand, for example using `diff(1)` to check for changes. +- +-When installing from source, it is _extremely_ helpful to read the +-output of `./configure`, `make`, and `make install`. If a +-particular module you expected to be installed was not installed, +-then the output will tell you why that module was not installed. +-The most likely reason is that required libraries (including their +-development header files) are not available. +- +-Please do _not_ post questions to the FreeRADIUS users list +-without first carefully reading the output of this process as it +-often contains the information needed to resolve a problem. +- +-== Upgrading To A New Minor Release +- +-The installation process will not over-write your existing configuration +-files. It will, however, warn you about the files it did not install. +-These will require manual integration with the existing files. +- +-It is not possible to re-use configurations between different major +-versions of the server. +- +-For details on what has changed between the version, see the +-xref:installation:upgrade.adoc[upgrade] guide. +- +-We _strongly_ recommend that new major versions be installed in a +-different location than any existing installations. Any local policies +-can then be migrated gradually to the configuration format of the new +-major version. The number of differences in the new configuration mean +-that is is both simpler and safer to migrate your configurations rather +-than to try and just get the old configuration to work. +- +-== Running the server +- +-If the server builds and installs, but doesn’t run correctly, then +-you should first use debugging mode (`radiusd -X`) to figure out +-the problem. +- +-This is your best hope for understanding the problem. Read _all_ +-of the messages which are printed to the screen, the answer to +-your problem will often be in a warning or error message. +- +-We really cannot emphasize that last sentence enough. Configuring +-a RADIUS server for complex local authentication isn’t a trivial +-task. Your _best_ and _only_ method for debugging it is to read +-the debug messages, where the server will tell you exactly what +-it’s doing, and why. You should then compare its behaviour to what +-you intended, and edit the configuration files as appropriate. +- +-If you don’t use debugging mode, and ask questions on the mailing +-list, then the responses will all tell you to use debugging mode. +-The server prints out a lot of information in this mode, including +-suggestions for fixes to common problems. Look especially for +-`WARNING` and `ERROR` messages in the output, and read the related +-messages. +- +-Since the main developers of FreeRADIUS use debugging mode to +-track down their configuration problems with the server, it’s a +-good idea for you to use it, too. If you don’t, there is little +-hope for you to solve any configuration problem related to the +-server. +- +-To start the server in debugging mode, do: +- +-[source,shell] +----- +-radiusd -X +----- +- +-You should see a lot of text printed on the screen as it starts up. If +-you don’t, or if you see error messages, please read the FAQ: +- +-https://wiki.freeradius.org/guide/FAQ +- +-If the server says `Ready to process requests.`, then it is running +-properly. From another shell (or another window), type +- +-[source,shell] +----- +-radtest test test localhost 0 testing123 +----- +- +-You should see the server print out more messages as it receives the +-request, and responds to it. The `radtest` program should receive the +-response within a few seconds. It doesn’t matter if the authentication +-request is accepted or rejected, what matters is that the server +-received the request, and responded to it. +- +-You can now edit the configuration files for your local system. You will +-usually want to start with `sites-enabled/default` for main +-configurations. To set which NASes (clients) can communicate with this +-server, edit `raddb/clients.conf`. Please read the configuration files +-carefully, as many configuration options are only documented in comments +-in the file. +- +-Note that is is _highly_ recommended that you use some sort of version +-control system to manage your configuration, such as git or Subversion. +-You should then make small changes to the configuration, checking in and +-testing as you go. When a config change causes the server to stop +-working, you will be able to easily step back and find out what update +-broke the configuration. +- +-It is also considered a best practice to maintain a staging or +-development environment. This allows you to test and integrate your +-changes without impacting your active production environment. You should +-make the appropirate investment in order to properly support a critical +-resource such as your authentication servers. +- +-Configuring and running the server MAY be complicated. Many modules have +-`man` pages. See `man rlm_pap`, or `man rlm_*` for information. +-Please read the documentation in the doc/ directory. The comments in the +-configuration files also contain a lot of documentation. +- +-If you have any additional issues, the FAQ is also a good place to +-start. +- +-https://wiki.freeradius.org/guide/FAQ +diff --git a/doc/antora/modules/installation/pages/upgrade.adoc b/doc/antora/modules/installation/pages/upgrade.adoc +deleted file mode 100644 +index 67874c859a..0000000000 +--- a/doc/antora/modules/installation/pages/upgrade.adoc ++++ /dev/null +@@ -1,737 +0,0 @@ +-= Upgrading from v2 to v3 +- +-The configuration for 3.0 is *largely* compatible with the 2.x.x +-configuration. However, it is NOT possible to simply use the 2.x.x +-configuration as-is. Instead, you should re-create it. +- +-== Security +- +-A number of configuration items have moved into the "security" subsection of +-radiusd.conf. If you use these, you should move them. Otherwise, they can +-be ignored. +- +-The list of moved options is: +- +-* chroot +-* user +-* group +-* allow_core_dumps +-* reject_delay +-* status_server +- +-These entries should be moved from "radiusd.conf" to the "security" +-subsection of that file. +- +-== Naming +- +-Many names used by configuration items were inconsistent in earlier +-versions of the server. These names have been unified in version 3.0. +- +-If a file is being referenced or created the config item `filename` +-is used. +- +-If a file is being created, the initial permissions are set by the +-`permissions` config item. +- +-If a directory hierarchy needs to be created, the permissions are set +-by `dir_permissions`. +- +-If an external host is referenced in the context of a module the +-`server` config item is used. +- +-Unless the config item is a well recognised portmanteau +-(as `filename` is for example), it must be written as multiple +-distinct words separated by underscores `_`. +- +-The configuration items `file`, `script_file`, `module`, +-`detail`, `detailfile`, `attrsfile`, `perm`, `dirperm`, +-`detailperm`, and `hostname` are deprecated. As well as any false +-portmanteaus, and configuration items that used hyphens as word +-delimiters. e.g. `foo-bar` has been changed to `foo_bar`. Please +-update your module configuration to use the new syntax. +- +-In most cases the server will tell you the replacement config item to +-use. As always, run the server in debugging mode to see these +-messages. +- +-== Modules Directory +- +-As of version 3.0, the `modules/` directory no longer exists. +- +-Instead, all "example" modules have been put into the +-`mods-available/` directory. Modules which can be loaded by the +-server are placed in the `mods-enabled/` directory. All of the +-modules in that directory will be loaded. This means that the +-`instantiate` section of radiusd.conf is less important. The only +-reason to list a module in the `instantiate` section is to force +-ordering when the modules are loaded. +- +-Modules can be enabled by creating a soft link. For module `foo`, do: +- +-[source,shell] +----- +-cd raddb/mods-enabled +-ln -s ../mods-available/foo +----- +- +-To create "local" versions of the modules, we suggest copying the file +-instead. This leaves the original file (with documentation) in the +-`mods-available/` directory. Local changes should go into the +-`mods-enabled/` directory. +- +-Module-specific configuration files are now in the `mods-config/` +-directory. This change allows for better organization, and means that +-there are fewer files in the main `raddb` directory. See +-`mods-config/README.rst` for more details. +- +-== Changed Modules +- +-The following modules have been changed in this version. +- +-=== rlm_sql +- +-The SQL configuration has been moved from `sql.conf` to +-`mods-available/sql`. The `sqlippool.conf` file has also been +-moved to `mods-available/sqlippool`. +- +-The SQL module configuration has been changed. The old connection +-pool options are no longer accepted: +- +----- +-num_sql_socks +-connect_failure_retry_delay +-lifetime +-max_queries +----- +- +-Instead, a connection pool configuration is used. This configuration +-contains all of the functionality of the previous configuration, but +-in a more generic form. It also is used in multiple modules, meaning +-that there are fewer different configuration items. The mapping +-between the configuration items is: +- +----- +-num_sql_socks -> pool { max } +-connect_failure_retry_delay -> pool { retry_delay } +-lifetime -> pool { lifetime } +-max_queries -> pool { uses } +----- +- +-The pool configuration adds a number of new configuration options, +-which allow the administrator to better control how FreeRADIUS uses +-SQL connection pools. +- +-The following parameters have been changed: +- +----- +-trace -> removed +-tracefile -> logfile +----- +- +-The logfile is intended to log SQL queries performed. If you need to +-debug the server, use debugging mode. If `logfile` is set, then +-*all* SQL queries will go to `logfile`. +- +-You can now use a NULL SQL database: +- +-.Example +----- +-driver = rlm_sql_null +----- +- +-This is an empty driver which will always return "success". It is +-intended to be used to replace the `sql_log` module, and to work in +-conjunction with the `radsqlrelay` program. Simply take your normal +-configuration for raddb/mods-enabled/sql, and set: +- +-.Example +----- +-driver = rlm_sql_null +-... +-logfile = ${radacctdir}/sql.log +----- +- +-All of the SQL queries will be logged to that file. The connection +-pool does not need to be configured for the `null` SQL driver. It +-can be left as-is, or deleted from the SQL configuration file. +- +- +-=== rlm_sql_sybase +- +-The `rlm_sql_sybase` module has been renamed to `rlm_sql_freetds` +-and the old `rlm_sql_freetds` module has been removed. +- +-`rlm_sql_sybase` used the newer ct-lib API, and `rlm_sql_freetds` +-used an older API and was incomplete. +- +-The new `rlm_sql_freetds` module now also supports database +-selection on connection startup so `use` statements no longer +-have to be included in queries. +- +- +-=== sql/dialup.conf +- +-Queries for post-auth and accounting calls have been re-arranged. The +-SQL module will now expand the 'reference' configuration item in the +-appropriate sub-section, and resolve this to a configuration +-item. This behaviour is similar to rlm_linelog. This dynamic +-expansion allows for a dynamic mapping between accounting types and +-SQL queries. Previously, the mapping was fixed. Any "new" accounting +-type was ignored by the module. Now, support for any accounting type +-can be added by just adding a new target, as below. +- +-Queries from v2.x.x may be manually copied to the new v3.0 +-`dialup.conf` file (`raddb/sql/main//queries.conf`). +-When doing this you may also need to update references to the +-accounting tables, as their definitions will now be outside of +-the subsection containing the query. +- +-The mapping from old "fixed" query to new "dynamic" query is as follows: +- +----- +-accounting_onoff_query -> accounting.type.accounting-on.query +-accounting_update_query -> accounting.type.interim-update.query +-accounting_update_query_alt +> accounting.type.interim-update.query +-accounting_start_query -> accounting.type.start.query +-accounting_start_query_alt +> accounting.type.start.query +-accounting_stop_query -> accounting.type.stop.query +-accounting_stop_query_alt +> accounting.type.stop.query +-postauth_query -> post-auth.query +----- +- +-Alternatively a 2.x.x config may be patched to work with the +-3.0 module by adding the following: +- +-.Example +-[source,unlang] +----- +- accounting { +- reference = "%{tolower:type.%{Acct-Status-Type}.query}" +- type { +- accounting-on { +- query = "${....accounting_onoff_query}" +- } +- accounting-off { +- query = "${....accounting_onoff_query}" +- } +- start { +- query = "${....accounting_start_query}" +- query = "${....accounting_start_query_alt}" +- } +- interim-update { +- query = "${....accounting_update_query}" +- query = "${....accounting_update_query_alt}" +- } +- stop { +- query = "${....accounting_stop_query}" +- query = "${....accounting_stop_query_alt}" +- } +- } +- } +- post-auth { +- query = "${..postauth_query}" +- } +----- +- +-In general, it is safer to migrate the configuration rather than +-trying to "patch" it, to make it look like a v2 configuration. +- +-Note that the sub-sections holding the queries are labelled +-`accounting-on`, and not `accounting_on`. The reason is that the +-names of these sections are taken directly from the +-`Accounting-Request` packet, and the `Acct-Status-Type` field. +-The `sql` module looks at the value of that field, and then looks +-for a section of that name, in order to find the query to use. +- +-That process means that the server can be extended to support any new +-value of `Acct-Status-Type`, simply by adding a named sub-section, +-and a query. This behavior is preferable to that of v2, which had +-hard-coded queries for certain `Acct-Status-Type` values, and was +-ignored all other values. +- +-=== rlm_ldap +- +-The LDAP module configuration has been substantially changed. Please +-read `raddb/mods-available/ldap`. It now uses a connection pool, +-just like the SQL module. +- +-Many of the configuration items remain the same, but they have been +-moved into subsections. This change is largely cosmetic, but it makes +-the configuration clearer. Instead of having a large set of random +-configuration items, they are now organized into logical groups. +- +-You will need to read your old LDAP configuration, and migrate it +-manually to the new configuration. Simply copying the old +-configuration WILL NOT WORK. +- +-Users upgrading from 2.x.x who used to call the ldap module in +-`post-auth` should now set `edir_autz = yes`, and remove the `ldap` +-module from the `post-auth` section. +- +-=== rlm_ldap and LDAP-Group +- +-In 2.x.x the registration of the `LDAP-Group` pair comparison was done +-by the last instance of rlm_ldap to be instantiated. In 3.0 this has +-changed so that only the default `ldap {}` instance registers +-`LDAP-Group`. +- +-If `-LDAP-Group` is already used throughout your configuration +-no changes will be needed. +- +-=== rlm_ldap authentication +- +-In 2.x.x the LDAP module had a `set_auth_type` configuration item, +-which forced `Auth-Type := ldap`. This was removed in 3.x.x as it +-often did not work, and was not consistent with the rest of the +-server. We generally recommend that LDAP should be used as a +-database, and that FreeRADIUS should do authentication. +- +-The only reason to use `Auth-Type := ldap` is when the LDAP server +-will not supply the "known good" password to FreeRADIUS, *and* where +-the Access-Request contains User-Password. This situation happens +-only for Active Directory. If you think you need to force `Auth-Type +-:= ldap` in other situations, you are very likely to be wrong. +- +-The following is an example of what should be inserted into the +-`authorize {}` and `authenticate {}` sections of the relevant +-virtual-servers, to get functionality equivalent to v2.x: +- +-.Example +-[source,unlang] +----- +-authorize { +- ... +- ldap +- if ((ok || updated) && User-Password) { +- update control { +- Auth-Type := ldap +- } +-... +-} +-authenticate { +- ... +- Auth-Type ldap { +- ldap +- } +-... +-} +----- +- +-=== rlm_eap +- +-The EAP configuration has been moved from `eap.conf` to +-`mods-available/eap`. A new `pwd` subsection has been added for +-EAP-PWD. +- +- +-=== rlm_expiration & rlm_logintime +- +-The rlm_expiration and rlm_logintime modules no longer add a `Reply-Message`, +-the same behaviour can be achieved checking the return code of the module and +-adding the `Reply-Message` with unlang: +- +-.Example +-[source,unlang] +----- +-expiration +-if (userlock) { +- update reply { +- Reply-Message := "Your account has expired" +- } +-} +----- +- +- +-=== rlm_unix +- +-The `unix` module does not have an `authenticate` section. So you +-cannot set `Auth-Type := System`. The `unix` module has also been +-deleted from the examples in `sites-available/`. Listing it there +-has been deprecated for many years. +- +-The PAP module can do crypt authentication. It should be used instead +-of Unix authentication. +- +-The Unix module still can pull the passwords from `/etc/passwd`, or +-`/etc/shadow`. This is done by listing it in the `authorize` +-section, as is done in the examples in `sites-available/`. However, +-some systems using NIS or NSS will not supply passwords to the +-`unix` module. For those systems, we recommend putting users and +-passwords into a database, instead of relying on `/etc/passwd`. +- +- +-=== rlm_preprocess +- +-In 2.x.x `huntroups` and `users` files were loaded from default locations +-without being configured explicitly. Since 3.x.x you need to set +-`huntgroups` and `users` configuration item(s) in module section in order +-to get them being processed. +- +- +-== New Modules +- +-=== rlm_date +- +-Instances of rlm_date register an xlat method which can translate +-integer and date values to an arbitrarily formatted date time +-string, or an arbitrarily formated time string to an integer, +-depending on the attribute type passed. +- +- +-=== rlm_rest +- +-The `rest` module is used to translate RADIUS requests into +-RESTfull HTTP requests. Currently supported body types are JSON +-and POST. +- +- +-=== rlm_unpack +- +-The `unpack` module is used to turn data buried inside of binary +-attributes. e.g. if we have `Class = 0x00000001020304` then: +- +-.Example +-[source,unlang] +----- +-Tmp-Integer-0 := "%{unpack:&Class 4 short}" +----- +- +-will unpack octets 4 and 5 as a "short", which has value 0x0304. +-All integers are assumed to be in network byte order. +- +- +-=== rlm_yubikey +- +-The `yubikey` module can be used to forward yubikey OTP token +-values to a Yubico validation server, or decrypt the token +-using a PSK. +- +- +-== Deleted Modules +- +-The following modules have been deleted, and are no longer supported +-in Version 3. If you are using one of these modules, your +-configuration can probably be changed to not need it. Otherwise email +-the freeradius-devel list, and ask about the module. +- +- +-=== rlm_acct_unique +- +-This module has been replaced by the "acct_unique" policy. See +-raddb/policy.d/accounting. +- +-The method for calculating the value of acct_unique has changed. +-However, as this method was configurable, this change should not +-matter. The only issue is in having a v2 and v3 server writing to the +-same database at the same time. They will calculate different values +-for Acct-Unique-Id. +- +- +-=== rlm_acctlog +- +-You should use rlm_linelog instead. That module has a superset of the +-acctlog functionality. +- +- +-=== rlm_attr_rewrite +- +-The attr_rewrite module looked for an attribute, and then re-wrote it, +-or created a new attribute. All of that can be done in "unlang". +- +-A sample configuration in "unlang" is: +- +-.Example +-[source,unlang] +----- +-if (request:Calling-Station-Id) { +- update request { +- Calling-Station-Id := "...." +- } +-} +----- +- +-We suggest updating all uses of attr_rewrite to use unlang instead. +- +- +-=== rlm_checkval +- +-The checkval module compared two attributes. All of that can be done in "unlang": +- +-.Example +-[source,unlang] +----- +-if (&request:Calling-Station-Id == &control:Calling-Station-Id) { +- ok +-} +----- +- +-We suggest updating all uses of checkval to use unlang instead. +- +- +-=== rlm_dbm +- +-No one seems to use it. There is no sample configuration for it. +-There is no speed advantage to using it over the "files" module. +-Modern systems are fast enough that 10K entries can be read from the +-"users" file in about 10ms. If you need more users than that, use a +-real database such as SQL. +- +- +-=== rlm_fastusers +- +-No one seems to use it. It has been deprecated since Version 2.0.0. +-The "files" module was rewritten so that the "fastusers" module was no +-longer necessary. +- +- +-=== rlm_policy +- +-No one seems to use it. Almost all of its functionality is available +-via `unlang`. +- +- +-=== rlm_sim_files +- +-The rlm_sim_files module has been deleted. It was never marked "stable", +-and was never used in a production environment. There are better ways +-to test EAP. +- +-If you want similar functionality, see rlm_passwd. It can read CSV +-files, and create attributes from them. +- +- +-=== rlm_sql_log +- +-This has been replaced with the "null" sql driver. See +-`raddb/mods-available/sql` for an example configuration. +- +-The main SQL module has more functionality than rlm_sql_log, and +-results in less code in the server. +- +-== Other Functionality +- +-The following is a list of new / changed functionality. +- +-=== RadSec +- +-RadSec (or RADIUS over TLS) is now supported. RADIUS over bare TCP +-is also supported, but is recommended only for secure networks. +- +-See `sites-available/tls` for complete details on using TLS. The server +-can both receive incoming TLS connections, and also originate outgoing +-TLS connections. +- +-The TLS configuration is taken from the old EAP-TLS configuration. It +-is largely identical to the old EAP-TLS configuration, so it should be +-simple to use and configure. It re-uses much of the EAP-TLS code, +-so it is well-tested and reliable. +- +-Once RadSec is enabled, normal debugging mode will not work. This is +-because the TLS code requires threading to work properly. Instead of doing: +- +-.Example +-[source,shell] +----- +-radiusd -X +----- +- +-you will need to do: +- +-.Example +-[source,shell] +----- +-radiusd -fxx -l stdout +----- +- +-That's the price to pay for using RadSec. This limitation may be +-lifted in a future version of the server. +- +- +-=== PAP and User-Password +- +-From version 3.0 onwards the server no longer supports authenticating +-against a cleartext password in the 'User-Password' attribute. Any +-occurences of this (for instance, in the users file) should now be changed +-to 'Cleartext-Password' instead. +- +-e.g. change entries like this: +- +----- +-bob User-Password == "hello" +----- +- +-to ones like this: +- +----- +-bob Cleartext-Password := "hello" +----- +- +-If this is not done, authentication will likely fail. The server will +-also print a helpful message in debugging mode. +- +-If it really is impossible to do this, the following unlang inserted above +-the call to the pap module may be used to copy User-Password to the correct +-attribute: +- +-.Example +-[source,unlang] +----- +-if (!control:Cleartext-Password && control:User-Password) { +- update control { +- Cleartext-Password := "%{control:User-Password}" +- } +-} +----- +- +-However, this should only be seen as a temporary, not permanent, fix. +-It is better to fix your databases to use the correct configuration. +- +- +-== Unlang +- +- +-The unlang policy language is compatible with v2, but has a number of +-new features. See `man unlang` for complete documentation. +- +- +-=== Errors +- +-Many more errors are caught when the server is starting up. Syntax +-errors in `unlang` are caught, and a helpful error message is +-printed. The error message points to the exact place where the error +-occurred: +- +----- +- ./raddb/sites-enabled/default[230]: Parse error in condition +- ERROR: if (User-Name ! "bob") { +- ERROR: ^ Invalid operator +----- +- +-`update` sections are more generic. Instead of doing `update +-reply`, you can do the following: +- +-.Example +-[source,unlang] +----- +-update { +- reply:Class := 0x0000 +- control:Cleartext-Password := "hello" +-} +----- +- +-This change means that you need fewer `update` sections. +- +- +-=== Comparisons +- +-Attribute comparisons can be done via the `&` operator. When you +-needed to compare two attributes, the old comparison style was: +- +-.Example +-[source,unlang] +----- +-if (User-Name == "%{control:Tmp-String-0}") { +----- +- +-This syntax is inefficient, as the `Tmp-String-0` attribute would be +-printed to an intermediate string, causing unnecessary work. You can +-now instead compare the two attributes directly: +- +-.Example +-[source,unlang] +----- +-if (&User-Name == &control:Tmp-String-0) { +----- +- +-See `man unlang` for more details. +- +-=== Casts +- +-Casts are now permitted. This allows you to force type-specific +-comparisons: +- +-.Example +-[source,unlang] +----- +-if ("%{sql: SELECT...}" == 127.0.0.1) { +----- +- +-This forces the string returned by the SELECT to be treated as an IP +-address, and compare to `127.0.0.1`. Previously, the comparison +-would have been done as a simple string comparison. +- +- +-=== Networks +- +-IP networks are now supported: +- +- if (127.0.0.1/32 == 127.0.0.1) { +- +-Will be `true`. The various comparison operators can be used to +-check IP network membership:: +- +-.Example +-[source,unlang] +----- +-if (127/8 > 127.0.0.1) { +----- +- +-Returns `true`, because `127.0.0.1` is within the `127/8` +-network. However, the following comparison will return `false`:: +- +-.Example +-[source,unlang] +----- +-if (127/8 > 192.168.0.1) { +----- +- +-because `192.168.0.1` is outside of the `127/8` network. +- +- +-=== Optimization +- +-As `unlang` is now pre-compiled, many compile-time optimizations are +-done. This means that the debug output may not be exactly the same as +-what is in the configuration files: +- +- if (0 && (User-Name == "bob')) { +- +-The result will always be `false`, as the `if 0` prevents the +-following `&& ...` from being evaluated. +- +-Not only that, but the entire contents of that section will be ignored +-entirely: +- +-.Example +-[source,unlang] +----- +-if (0) { +- this_module_does_not_exist +- and_this_one_does_not_exist_either +-} +----- +- +-In v2, that configuration would result in a parse error, as there is +-no module called `this_module_does_not_exist`. In v3, that text is +-ignored. This ability allows you to have dynamic configurations where +-certain parts are used (or not) depending on compile-time configuration. +- +-Similarly, conditions which always evaluate to `true` will be +-optimized away: +- +- +-.Example +-[source,unlang] +----- +-if (1) { +- files +-} +----- +- +-That configuration will never show the `if (1)` output in debugging mode. +- +-=== Dialup_admin +- +-The dialup_admin directory has been removed. No one stepped forward +-to maintain it, and the code had not been changed in many years. +- +diff --git a/doc/antora/modules/unlang/.gitignore b/doc/antora/modules/unlang/.gitignore +deleted file mode 100644 +index c5722d7c54..0000000000 +--- a/doc/antora/modules/unlang/.gitignore ++++ /dev/null +@@ -1 +0,0 @@ +-!*.adoc +diff --git a/doc/antora/modules/unlang/nav.adoc b/doc/antora/modules/unlang/nav.adoc +deleted file mode 100644 +index 77be32885e..0000000000 +--- a/doc/antora/modules/unlang/nav.adoc ++++ /dev/null +@@ -1,51 +0,0 @@ +-* xref:index.adoc[Unlang Policy Language] +- +-** xref:list.adoc[Attribute Lists] +-** xref:attr.adoc[Attribute References] +-** xref:return_codes.adoc[Return Codes] +- +-** xref:keywords.adoc[Keywords] +-*** xref:break.adoc[break] +-*** xref:case.adoc[case] +-*** xref:else.adoc[else] +-*** xref:elsif.adoc[elsif] +-*** xref:foreach.adoc[foreach] +-*** xref:group.adoc[group] +-*** xref:if.adoc[if] +-*** xref:load-balance.adoc[load-balance] +-*** xref:redundant-load-balance.adoc[redundant-load-balance] +-*** xref:redundant.adoc[redundant] +-*** xref:return.adoc[return] +-*** xref:switch.adoc[switch] +-*** xref:update.adoc[update] +- +-** xref:module.adoc[Modules] +-*** xref:module_method.adoc[Module Methods] +-*** xref:module_builtin.adoc[Built-in Modules] +- +-** xref:type/index.adoc[Data Types] +-*** xref:type/index.adoc[List of Data Types] +-*** xref:type/ip.adoc[IP Addresses] +-*** xref:type/numb.adoc[Numbers] +-*** xref:type/string/single.adoc[Single Quoted Strings] +-*** xref:type/string/double.adoc[Double Quoted Strings] +-*** xref:type/string/backticks.adoc[Backtick-quoted string] +-*** xref:type/string/unquoted.adoc[Unquoted Strings] +- +-** xref:condition/index.adoc[Conditional Expressions] +-*** xref:condition/cmp.adoc[Comparisons] +-*** xref:condition/operands.adoc[Operands] +-*** xref:condition/return_code.adoc[The Return Code Operator] +-*** xref:condition/eq.adoc[The '==' Operator] +-*** xref:condition/and.adoc[The '&&' Operator] +-*** xref:condition/or.adoc[The '||' Operator] +-*** xref:condition/not.adoc[The '!' Operator] +-*** xref:condition/para.adoc[The '( )' Operator] +-*** xref:condition/regex.adoc[Regular Expressions] +- +-** xref:xlat/index.adoc[String Expansion] +-*** xref:xlat/alternation.adoc[Alternation Syntax] +-*** xref:xlat/builtin.adoc[Built-in Expansions] +-*** xref:xlat/character.adoc[Single Letter Expansions] +-*** xref:xlat/attribute.adoc[Attribute References] +-*** xref:xlat/module.adoc[Module References] +diff --git a/doc/antora/modules/unlang/pages/attr.adoc b/doc/antora/modules/unlang/pages/attr.adoc +deleted file mode 100644 +index 70afce41af..0000000000 +--- a/doc/antora/modules/unlang/pages/attr.adoc ++++ /dev/null +@@ -1,77 +0,0 @@ +-= &Attribute References +- +-.Syntax +-[source,unlang] +----- +-[&]Attribute-Name +----- +- +-The `&Attribute-Name` operator returns a reference to the named +-attribute. +- +-When used as an existence check in a condition, the condition +-evaluates to `true` if the attribute exists. Otherwise, the condition +-evaluates to `false`. +- +-When used elsewhere, such as in xref:switch.adoc[switch], it returns +-the value of the named attribute. +- +-.Examples +-[source,unlang] +----- +-&User-Name +-&NAS-IP-Address +----- +- +-== Lists +- +-The attribute reference can also be qualified with a +-xref:list.adoc[list] reference. When no list is given, the server +-looks in the input packet list for the named attribute. +- +-.Examples +- +-[source,unlang] +----- +-&request:User-Name +-&reply:NAS-IP-Address +----- +- +-== Array References +- +-.Syntax +-[source,unlang] +----- +-&Attribute-Name[] +----- +- +-When an attribute appears multiple times in a list, this syntax allows +-you to address the attributes as if they were array entries. The +-`` value defines which attribute to address. The `[0]` value +-refers to the first attributes, `[1]` refers to the second attribute, +-etc. +- +-.Examples +-[source,unlang] +----- +-&EAP-Message[1] +-&reply:NAS-IP-Address[2] +----- +- +-== Removing ambuguity from the configuration files +- +-The server does not use the `&` character to distinguish attribute names +-from other strings. +- +-Without the `&`, it is more difficult to parse the configuration file +-clearly. You could interpret a string as `hello-there` +-either as a literal string "hello-there", or as a reference to an +-attribute named `hello-there`. +- +-Adding the leading `&` character means that attribute references are +-now easily distinguishable from literal strings. The use of the leading +-`&` character is highly recommended. +- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/break.adoc b/doc/antora/modules/unlang/pages/break.adoc +deleted file mode 100644 +index 01783ea8f2..0000000000 +--- a/doc/antora/modules/unlang/pages/break.adoc ++++ /dev/null +@@ -1,28 +0,0 @@ +-= The break statement +- +-.Syntax +-[source,unlang] +----- +-break +----- +- +-The `break` statement is used to exit an enclosing +-xref:foreach.adoc[foreach] loop. The `break` statement only be used +-inside of a xref:foreach.adoc[foreach] loop. +- +-.Example +-[source,unlang] +----- +-foreach &Class { +- if (&Foreach-Variable-0 == 0xabcdef) { +- break +- } +- +- update reply { +- Reply-Message += "Contains %{Foreach-Variable-0}" +- } +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/case.adoc b/doc/antora/modules/unlang/pages/case.adoc +deleted file mode 100644 +index ba2b5fe274..0000000000 +--- a/doc/antora/modules/unlang/pages/case.adoc ++++ /dev/null +@@ -1,44 +0,0 @@ +-= The case Statement +- +-.Syntax +-[source,unlang] +----- +-case [ ] { +- [ statements ] +-} +----- +- +-The `case` statement is used to match data inside of a +-xref:switch.adoc[switch] statement. The `case` statement cannot be used +-outside of a xref:switch.adoc[switch] statement. +- +- +-The `` text can be an attribute reference such as `&User-Name`, +-or it can be a xref:type/string/index.adoc[string]. If the match +-text is a dynamically expanded string, then the match is performed on +-the output of the string expansion. +- +-If no `` text is given, it means that the `case` statement is +-the "default" and will match all which is not matched by another +-`case` statement inside of the same xref:switch.adoc[switch]. +- +-.Example +-[source,unlang] +----- +-switch &User-Name { +- case "bob" { +- reject +- } +- +- case &Filter-Id { +- reject +- } +- +- case { +- ok +- } +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/and.adoc b/doc/antora/modules/unlang/pages/condition/and.adoc +deleted file mode 100644 +index 50b3deb2e0..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/and.adoc ++++ /dev/null +@@ -1,21 +0,0 @@ +-= The && Operator +- +-.Syntax +-[source,unlang] +----- +-(condition-1 && condition-2) +----- +- +-The `&&` operator performs a short-circuit "and" evaluation of the +-two conditions. This operator evaluates _condition-1_ and returns +-`false` if _condition-1_ returns `false`. Only if _condition-1_ +-returns `true` is _condition-2_ evaluated and its result returned. +- +-.Examples +-[source,unlang] +----- +-if (&User-Name && &EAP-Message) { ... +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/cmp.adoc b/doc/antora/modules/unlang/pages/condition/cmp.adoc +deleted file mode 100644 +index 4138b869ae..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/cmp.adoc ++++ /dev/null +@@ -1,104 +0,0 @@ +-= Comparisons +- +-.Syntax +-[source,unlang] +----- +-lhs OP rhs +----- +- +-The most common use-case for conditions is to perform comparisons. +-The `lhs` and `rhs` of a conditional comparison can be +-xref:attr.adoc[&Attribute-Name] or xref:type/index.adoc[data]. The +-the `OP` is an operator, commonly `==` or `\<=`. It is used to +-control how the two other portions of the condition are compared. +- +-== The Comparison Operators +- +-The comparison operators are given below. +- +-[options="header"] +-|===== +-| Operator | Description +-| < | less than +-| \<= | less than or equals +-| == | equals +-| != | not equals +-| >= | greater than or equals +-| > | greater than +-| xref:condition/regex.adoc[=~] | regular expression matches +-| xref:condition/regex.adoc[!~] | regular expression does not match +-|===== +- +-The comparison operators perform _type-specific_ comparisons. The +-only exceptions are the xref:condition/regex.adoc[regular expression] operators, +-which interpret the `lhs` as a printable string, and the `rhs` as a +-regular expression. +- +-== IP Address Comparisons +- +-The type-specific comparisons operate as expected for most data types. +-The only exception is data types that are IP addresses or IP address +-prefixes. For those data types, the comparisons are done via the +-following rules: +- +-* Any unqualified IP address is assumed to have a /32 prefix (IPv4) +- or a /128 prefix (IPv6). +- +-* If the prefixes of the left and right sides are equal, then the comparisons +- are performed on the IP address portion. +- +-* If the prefixes of the left and right sides are not equal, then the +- comparisons are performed as _set membership checks_. +- +-The syntax allows conditions such as `192.0.2.1 < 192.0.2/24`. This +-condition will return `true`, as the IP address `192.0.2.1' is within +-the network `192.0.2/24`. +- +-== Casting +- +-In some situations, it is useful to force the left side to be +-interpreted as a particular data type. +- +-[NOTE] +-The data types used by the cast *must* be a type taken from the RADIUS +-dictionaries, e.g., `ipaddr`, `integer`, etc. These types are not the +-same as the xref:type/index.adoc[data types] used in the +-configuration files. +- +-.Syntax +-[source,unlang] +----- +-lhs OP rhs +----- +- +-The `cast` text can be any one of the standard RADIUS dictionary data +-types, as with the following example: +- +-.Example +-[source,unlang] +----- +-&Class == 127.0.0.1 +----- +- +-In this example, the `Class` attribute is treated as if it was an IPv4 +-address and is compared to the address `127.0.0.1` +- +-Casting is most useful when the left side of a comparison is a +-dynamically expanded string. The cast ensures that the comparison is +-done in a type-safe manner, instead of performing a string comparison. +- +-.Example +-[source,unlang] +----- +-`/bin/echo 00` == 0 +----- +- +-In this example, the string output of the `echo` program is interpreted as an +-integer. It is then compared to the right side via integer +-comparisons. Since the integer `00` is equivalent to the integer `0`, +-the comparison will match. If the comparison had been performed via +-string equality checks, then the comparison would fail, because the +-strings `00` and `0` are different. +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/eq.adoc b/doc/antora/modules/unlang/pages/condition/eq.adoc +deleted file mode 100644 +index d9e51f3f13..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/eq.adoc ++++ /dev/null +@@ -1,30 +0,0 @@ +-= The == Operator +- +-.Syntax +-`(data-1 == data-2)` +- +-The `==` operator compares the result of evaluating `data-1` and +-`data-2`. As discussed in xref:type/index.adoc[Data Types], the `data-1` +-field may be interpreted as a reference to an attribute. +- +-The `data-2` field is interpreted in a type-specific manner. For +-example, if `data-1` refers to an attribute of type `ipaddr`, then +-`data-2` is evaluated as an IP address. If `data-1` refers to an +-attribute of type `integer`, then `data-2` is evaluated as an integer +-or as a named enumeration defined by a `VALUE` statement in a +-dictionary. Similarly, if `data-1` refers to an attribute of type +-`date`, then `data-2` will be interpreted as a date string. +- +-If the resulting data evaluates to be the same, then the operator +-returns `true`; otherwise, it returns `false`. +- +-.Example +-[source,unlang] +----- +-if (User-Name == "bob") { +- ... +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/index.adoc b/doc/antora/modules/unlang/pages/condition/index.adoc +deleted file mode 100644 +index b9d9d5f025..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/index.adoc ++++ /dev/null +@@ -1,85 +0,0 @@ +-= Conditional Expressions +- +-Conditions are evaluated when parsing xref:if.adoc[if] and +-xref:elsif.adoc[elsif] statements. These conditions allow the server to +-make complex decisions based on one of a number of possible criteria. +- +-.Syntax +-[source,unlang] +----- +-if ( condition ) { ... +- +-elsif ( condition ) { ... +----- +- +-Conditions are expressed using the following syntax: +- +-[options="header"] +-|===== +-| Syntax | Description +-| xref:attr.adoc[&Attribute-Name] | Check for attribute existence. +-| xref:condition/return_code.adoc[rcode] | Check return code of a previous module. +-| xref:condition/operands.adoc[data] | Check value of data. +-| xref:condition/cmp.adoc[lhs OP rhs] | Compare two kinds of data. +-| xref:condition/para.adoc[( condition )] | Check sub-condition +-| xref:condition/not.adoc[! condition] | Negate a conditional check +-| xref:condition/and.adoc[( condition ) && ...] | Check a condition AND the next one +-| xref:condition/or.adoc[( condition ) \|\| ...] | Check a condition OR the next one +-|===== +- +- +-.Examples +-[source,unlang] +----- +-if ( &User-Name == "bob" ) { +- ... +-} +- +-if ( &Framed-IP-Address == 127.0.0.1 ) { +- ... +-} +- +-if ( &Calling-Station-Id == "%{sql:SELECT ...}" ) { +- ... +-} +----- +- +-== Load-time Syntax Checks +- +-The server performs a number of checks when it loads the configuration +-files. Unlike version 2, all of the conditions are syntax checked +-when the server loads. This checking greatly aids in creating +-configurations that are correct. Where the configuration is +-incorrect, a descriptive error is produced. +- +-This error contains the filename and line number of the syntax error. +-In addition, it will print out a portion of the line that caused the +-error and will point to the exact character where the error was seen. +-These descriptive messages mean that most errors are easy to find and fix. +- +-== Load-time Optimizations +- +-The server performs a number of optimizations when it loads the +-configuration files. Conditions that have static values are +-evaluated and replaced with the result of the conditional comparison. +- +-.Example +-[source,unlang] +----- +-if ( 0 == 1 ) { +- ... +-} +----- +- +-The condition `0 == 1` is static and will evaluate to `false`. Since +-it evaluates to `false`, the configuration inside of the `if` +-statement is ignored. Any modules referenced inside of the `if` +-statement will not be loaded. +- +-This optimization is most useful for creating configurations that +-selectively load (or not) certain policies. If the condition above +-was used in version 2, then the configuration inside of the `if` statement +-would be loaded, even though it would never be used. +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/not.adoc b/doc/antora/modules/unlang/pages/condition/not.adoc +deleted file mode 100644 +index bde038e2de..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/not.adoc ++++ /dev/null +@@ -1,19 +0,0 @@ +-= The ! Operator +- +-.Syntax +-[source,unlang] +----- +-! condition +----- +- +-The `!` operator negates the result of the following condition. It +-returns `true` when _condition_ returns `false`. It returns `false` +-when _condition_ returns `true`. +- +-.Examples +- +-`(! (foo == bar))` + +-`! &User-Name` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/operands.adoc b/doc/antora/modules/unlang/pages/condition/operands.adoc +deleted file mode 100644 +index 4a2d00b2ae..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/operands.adoc ++++ /dev/null +@@ -1,37 +0,0 @@ +-= Operands +- +-.Syntax +-[source,unlang] +----- +-string +-integer +-"double-quoted string" +-'single-quoted string' +-`back-quoted string` +----- +- +-Any text not matching xref:attr.adoc[&Attribute-Name] or +-xref:condition/return_code.adoc[Return Code] is interpreted as a value for a +-particular xref:type/index.adoc[data type]. +- +-Double-quoted strings and back-quoted strings are dynamically expanded +-before the condition is evaluated. Single-quoted strings are static +-literals and are not dynamically expanded. +- +-When used as an existence check, the condition evaluates to `true` if +-the data is non-zero. Otherwise, the condition evaluates to `false`. +- +-For integer existence checks, `0` is `false`; all other values are `true`. +- +-For string existence checks, an empty string is `false`. All other +-strings are `true`. +- +-All other data types are disallowed in existence checks. +- +-.Examples +- +-`"hello there"` + +-`5` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/or.adoc b/doc/antora/modules/unlang/pages/condition/or.adoc +deleted file mode 100644 +index 80c2cb45a8..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/or.adoc ++++ /dev/null +@@ -1,21 +0,0 @@ +-= The || Operator +- +-.Syntax +-[source,unlang] +----- +-(expression-1 || expression-2) +----- +- +-The `||` operator performs a short-circuit "or" evaluation of the two +-expressions. This operator evaluates _condition-1_ and returns `true` +-if _condition-1_ returns true. Only if _condition-1_ returns `false` +-is _condition-2_ evaluated and its result returned. +- +-.Examples +-[source,unlang] +----- +-if (&User-Name || &NAS-IP-Address) { ... +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/para.adoc b/doc/antora/modules/unlang/pages/condition/para.adoc +deleted file mode 100644 +index bdb3f013c3..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/para.adoc ++++ /dev/null +@@ -1,19 +0,0 @@ +-= The ( ) Operator +- +-.Syntax +-[source,unlang] +----- +-( condition ) +----- +- +-The `( )` operator returns the result of evaluating the given +-`condition`. It is used to clarify policies or to explicitly define +-conditional precedence. +- +-.Examples +- +-`(foo)` + +-`(bar || (baz && dub))` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/regex.adoc b/doc/antora/modules/unlang/pages/condition/regex.adoc +deleted file mode 100644 +index 038faa647f..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/regex.adoc ++++ /dev/null +@@ -1,180 +0,0 @@ +-= Regular Expressions +- +-.Syntax +-==== +-[source,unlang] +----- +-( =~ //) +-( =~ //[imsux]) +- +-( !~ //) +-( !~ //[imsux]) +----- +-==== +- +-== Matching +-The regular expression operators perform regular expression matching +-on the data. The `` field can be an attribute reference or data, +-as with the other xref:condition/cmp.adoc[comparison] operators. The `//` +-field must be a valid regular expression. +- +-The `=~` operator evaluates to `true` when `data` matches the +-`//`. Otherwise, it evaluates to `false`. +- +-The `!~` operator evaluates to `true` when `data` does not match the +-`//`. Otherwise, it evaluates to `true`. +- +-The regular expression comparison is performed on the _string representation_ +-of the left side of the comparison. That is, if the left side is an +-xref:type/numb.adoc[integer], the regular expression will behave is if the +-value `0` was the literal string `"0"`. Similarly, if the left side is an +-xref:attr.adoc[&Attribute-Name], then the regular expression will behave is if +-the attribute was printed to a string, and the match was performed on the +-resulting string. +- +-.Checking if the `User-Name` attribute contains a realm of example.com +-==== +-[source,unlang] +----- +-if (&User-Name =~ /@example\.com$/) { +- ... +-} +----- +-==== +- +-== Dialects +- +-The syntax of the regular expression is defined by the regular +-expression library available on the local system. +- +-FreeRADIUS currently supports: +- +-* link:https://www.pcre.org/original/doc/html/[libpcre] and +-link:https://www.pcre.org/current/doc/html/[libpcre2] both of which +-provide +-link:https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions[Perl +-Compatible Regular expressions]. +-* Regex support provided by the local libc implementation, usually +-link:http://en.wikipedia.org/wiki/Regular_expression#POSIX_basic_and_extended[ +-Posix regular expressions]. +- +-[TIP] +-==== +-Use the output of `radiusd -Xxv` to determine which regular expression library is in use. +- +-.... +-... +-Debug : regex-pcre : no +-Debug : regex-pcre2 : yes +-Debug : regex-posix : no +-Debug : regex-posix-extended : no +-Debug : regex-binsafe : yes +-... +-Debug : pcre2 : 10.33 (2019-04-16) - retrieved at build time +-.... +-==== +- +-[WARNING] +-==== +-Depending on the regular expression library or libc implementation the server +-was built against, the pattern matching function available may not be binary +-safe (see `regex-binsafe` in the output of `radiusd -Xxv`). +- +-If a binary safe regex match function is not available, and a match is +-attempted against a subject that contains one or more `NUL` ('\0') bytes, the +-match will be aborted, any condition that uses the result will evaluate to false, +-and a warning will be emitted. +-==== +- +-== Flags +- +-The regular expression `//` may be followed by one or more flag +-characters. Again, which flags are available depends on the regular expression +-library the server was built with. Multiple flags may be specified per +-`/pattern/`. +- +-.Flags and their uses +- +-[options="header"] +-|===== +-| Flag Character | Available with | Effect +-| `i` | All | Enable case-insensitive matching. +-| `m` | All | '^' and '$' match newlines within the subject. +-| `s` | libpcre[2] | '.' matches anything, including newlines. +-| `u` | libpcre[2] | Treats subjects as UTF8. Invalid UTF8 +- sequences will result in the match failing. +- |`x` | libpcre[2] | Allows comments in expressions by ignoring +- whitespace, and text between '#' and the next +- newline character. +-|===== +- +-== Subcapture groups +- +-When the `=~` or `!~` operators are used, then parentheses in the regular +-expression will sub capture groups, which contain part of the subject string. +- +-The special expansion `%{0}` expands to the portion of the subject that +-matched. The expansions + +-`%{1}`..`%{32}` expand to the contents of any subcapture groups. +- +-When using libpcre[2], named capture groups may also be accessed using the +-built-in expansion + +-`%{regex:}`. +- +-Please see the xref:xlat/builtin.adoc#_0_32[xlat documentation] for +-more information on regular expression matching. +- +-.Extracting the 'user' portion of a realm qualified string +-==== +-[source,unlang] +----- +-if (&User-Name =~ /^(.*)@example\.com$/) { +- update reply { +- Reply-Message := "Hello %{1}" +- } +-} +----- +-==== +- +-== Pre-Compiled vs Runtime Compiled +- +-When the server starts any regular expressions comparisons it finds will be +-pre-compiled, and if support is available, JIT'd (converted to machine code) +-to ensure fast execution. +- +-If a pattern contains a xref:xlat/index.adoc[string expansion], the pattern +-cannot be compiled on startup, and will be compiled at runtime each time the +-expression is evaluated. The server will also turn off JITing for runtime +-compiled expressions, as the overhead is greater than the time that would be +-saved during evaluation. +- +-.A runtime compiled regular expression +-==== +-[source,unlang] +----- +-if (&User-Name =~ /^@%{Tmp-String-0}$/) { +- ... +-} +----- +-==== +- +-To ensure optimal performance you should limit the number of patterns +-containing xref:xlat/index.adoc[string expansions], and if using PCRE, combine +-multiple expressions operating on the same subject into a single expression +-using the PCRE alternation '|' operator. +- +-.Using multiple string expansions and the PCRE alternation operator +-==== +-[source,unlang] +----- +-if (&User-Name =~ /^@(%{Tmp-String-0}|%{Tmp-String-1})$/) { +- ... +-} +----- +-==== +- +- +-// Licenced under CC-by-NC 4.0. +-// Copyright (C) 2020 Network RADIUS SAS. +-// Copyright (C) 2019 Arran Cudbard-Bell +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/condition/return_codes.adoc b/doc/antora/modules/unlang/pages/condition/return_codes.adoc +deleted file mode 100644 +index ebc49ed5c7..0000000000 +--- a/doc/antora/modules/unlang/pages/condition/return_codes.adoc ++++ /dev/null +@@ -1,35 +0,0 @@ +-= The return code Operator +- +-.Syntax +-[source,unlang] +----- +-rcode +----- +- +-The Unlang interpreter tracks the return code of any module, string expansion +-or keyword that has been called. +- +-This return code can be checked in any condition. If the saved return code +-matches the `code` given here, then the condition evaluates to `true`. +-Otherwise, it evaluates to `false`. +- +-rcodes cannot be set in a condition. rcodes cannot be compared with anything else. +- +-The list of valid return codes is as follows: +- +-.Return Codes +- +-include::partial$rcode_table.adoc[] +- +-.Examples +- +-[source,unlang] +----- +-sql +-if (notfound) { +- ... +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/default.adoc b/doc/antora/modules/unlang/pages/default.adoc +deleted file mode 100644 +index 3b298f6a12..0000000000 +--- a/doc/antora/modules/unlang/pages/default.adoc ++++ /dev/null +@@ -1,47 +0,0 @@ +-= The case Statement +- +-.Syntax +-[source,unlang] +----- +-case [ ] { +- [ statements ] +-} +----- +- +-The `case` statement is used to match data inside of a +-xref:switch.adoc[switch] statement. The `case` statement cannot be used +-outside of a xref:switch.adoc[switch] statement. +- +- +-The `` text can be an attribute reference such as `&User-Name`, +-or it can be a xref:type/string/index.adoc[string]. If the match +-text is a dynamically expanded string, then the match is performed on +-the output of the string expansion. +- +-The keyword `default` can be used to specify the default action to +-take inside of a xref:switch.adoc[switch] statement. +- +-If no `` text is given, it means that the `case` statement is +-the "default" and will match all which is not matched by another +-`case` statement inside of the same xref:switch.adoc[switch]. +- +-.Example +-[source,unlang] +----- +-switch &User-Name { +- case "bob" { +- reject +- } +- +- case &Filter-Id { +- reject +- } +- +- default { +- ok +- } +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/else.adoc b/doc/antora/modules/unlang/pages/else.adoc +deleted file mode 100644 +index a795d0e12c..0000000000 +--- a/doc/antora/modules/unlang/pages/else.adoc ++++ /dev/null +@@ -1,30 +0,0 @@ +-= The else Statement +- +-.Syntax +-[source,unlang] +----- +-if (condition) { +- [ statements ] +-} +-else { +- [ statements ] +-} +----- +- +-An xref:if.adoc[if] statement can have an `else` clause. If _condition_ +-evaluates to `false`, the statements in the xref:if.adoc[if] subsection are skipped +-and the statements within the `else` subsection are executed. +- +-.Example +-[source,unlang] +----- +-if (&User-Name == "bob") { +- reject +-} +-else { +- ok +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/elsif.adoc b/doc/antora/modules/unlang/pages/elsif.adoc +deleted file mode 100644 +index ff5799c791..0000000000 +--- a/doc/antora/modules/unlang/pages/elsif.adoc ++++ /dev/null +@@ -1,43 +0,0 @@ +-= The elsif Statement +- +-.Syntax +-[source,unlang] +----- +-if (condition-1) { +- [ statements-1 ] +-} +-elsif (condition-2) { +- [ statements-2 ] +-} +-else { +- [ statements-3 ] +-} +----- +- +-An `elsif` statement is used to evaluate a subsequent +-xref:condition/index.adoc[condition] after a preceding xref:if.adoc[if] statement +-evaluates to `false`. In the example above, when _condition-1_ +-evaluates to false, then _statements-1_ are skipped and _condition-2_ +-is checked. When _condition-2_ evaluates true, then _statements-2_ +-are executed. When _condition-2_ evaluates false, then +-_statements-2_ are skipped and _statements-3_ are executed. +- +-As with xref:if.adoc[if], an `elsif` clause does not need to be followed by +-an xref:else.adoc[else] statement. However, any xref:else.adoc[else] statement +-must be the last statement in an `elsif` chain. An arbitrary number of +-`elsif` statements can be chained together to create a series of +-conditional checks and statements. +- +-.Example +-[source,unlang] +----- +-if (&User-Name == "bob") { +- reject +-} +-elsif (&User-Name == "doug") { +- ok +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/foreach.adoc b/doc/antora/modules/unlang/pages/foreach.adoc +deleted file mode 100644 +index 6ed3ddff67..0000000000 +--- a/doc/antora/modules/unlang/pages/foreach.adoc ++++ /dev/null +@@ -1,40 +0,0 @@ +-= The foreach Statement +- +-.Syntax +-[source,unlang] +----- +-foreach { +- [ statements ] +-} +----- +- +-The `foreach` statement loops over a set of attributes as given by +-``. The loop can be exited early by using the +-xref:break.adoc[break] keyword. +- +-:: +- +-The xref:attr.adoc[attribute reference] which will will be looped +-over. The reference can be to one attribute, to an array, a child, or +-be a subset. +- +-Inside of the `foreach` block, the attribute that is being looped over +-can be referenced as `Foreach-Variable-0`, through +-`Foreach-Variable-9`. The last digit is the depth of the loop, +-starting at "0". The loops can be nested up to eight (8) deep, though +-this is not recommended. +- +-The attributes being looped over cannot be modified or deleted. +- +-.Example +-[source,unlang] +----- +-foreach &Class { +- update reply { +- Reply-Message += "Contains %{Foreach-Variable-0}" +- } +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/group.adoc b/doc/antora/modules/unlang/pages/group.adoc +deleted file mode 100644 +index 98801fd280..0000000000 +--- a/doc/antora/modules/unlang/pages/group.adoc ++++ /dev/null +@@ -1,39 +0,0 @@ +-= The group Statement +- +-.Syntax +-[source,unlang] +----- +-group { +- [ statements ] +-} +----- +- +-The `group` statement collects a series of statements into a list. +-The default processing sections of the server (`authorize`, +-`accounting`, etc.) are also `group` statements. Those sections are +-given different name for management reasons, but they behave +-internally exactly like a `group`. +- +-[ statements ]:: The `unlang` commands which will be executed. +- +-All of the statements inside of the `group` are executed in sequence. +-The `group` statement is not normally used, as the statements within +-it can just be placed inside of the enclosing section. However, the +-`group` statement is included in the `unlang` syntax for completeness. +- +-.Examples +- +-[source,unlang] +----- +-group { +- sql +- ldap +- file +- if (updated) { +- ... +- } +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/if.adoc b/doc/antora/modules/unlang/pages/if.adoc +deleted file mode 100644 +index ea549efb52..0000000000 +--- a/doc/antora/modules/unlang/pages/if.adoc ++++ /dev/null +@@ -1,29 +0,0 @@ +-= The if Statement +- +-.Syntax +-[source,unlang] +----- +-if (condition) { +- [ statements ] +-} +----- +- +-.Description +-The `if` statement evaluates a xref:condition/index.adoc[condition]. When the +-_condition_ evaluates to `true`, the statements within the subsection +-are executed. When the _condition_ evaluates to `false`, those +-statements are skipped. +- +-An `if` statement can optionally be followed by an xref:else.adoc[else] or +-an xref:elsif.adoc[elsif] statement. +- +-.Example +-[source,unlang] +----- +-if (&User-Name == "bob") { +- reject +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/index.adoc b/doc/antora/modules/unlang/pages/index.adoc +deleted file mode 100644 +index fc812f873d..0000000000 +--- a/doc/antora/modules/unlang/pages/index.adoc ++++ /dev/null +@@ -1,162 +0,0 @@ +-= Unlang Policy Language +- +-The server supports a simple processing language called "Unlang", +-which is short for "un-language". The original intention of using an +-"un-language" was to avoid creating yet another programming language. +-Instead, the `unlang` syntax allows for simple _if / then / else_ +-checks, and attribute editing. It does not support recursion, +-subroutines, or more complex flow controls. +- +-Where more complicated functionality is required, we recommend using +-the `lua`, `perl` or `python` modules. Those modules allow the insertion of +-full-featured scripts at any point in the packet processing. +- +-NOTE: The documentation is this directory is _reference_ +-documentation. That is, it describes the syntax of `unlang` keywords, +-using minimal examples. The reference documentation does not, +-however, describe _when_ to use the keywords, or _how_ to create +-policies. Please see the xref:howto:index.adoc[howto] directory for +-more in-depth "how to" guides. +- +-The documentation is organized so that each item is on its own page. +-The page beings with a description of the item, followed by some text +-explaining what the item does. The page concludes with one or more +-examples of using the item in `unlang` policies. +- +-The `unlang` processing can be split into some high-level concepts. +- +-== Keywords +- +-xref:keywords.adoc[Keywords], which are the basic statements of the +-language, e.g., xref:load-balance.adoc[load-balance], +-xref:if.adoc[if], xref:else.adoc[else], etc. +- +-.Example +-[source,unlang] +----- +-load-balance { +- sql1 +- sql2 +- sql3 +-} +----- +- +-== Conditional Expressions +- +-xref:condition/index.adoc[Conditional expressions], which are used to check +-if conditions evaluate to _true_ or _false_. Conditional expressions +-can be used to control the flow of processing. +- +-.Example +-[source,unlang] +----- +-if ((&User-Name == "bob") && (&Calling-Station-Id == "00:01:03:04:05")) { +- ... +-} +----- +- +-== Update Statements +- +-xref:update.adoc[update] statements are used to edit attributes and +-lists of attributes. +- +-Most request packets will result in reply packets that contain +-additional information for the requestor. The `update` section allows +-policies to add attributes to requests, replies, or to other places. +- +-.Example +-[source,unlang] +----- +-update reply { +- &Session-Timeout := 3600 +- &Framed-IP-Address := 192.0.2.4 +-} +----- +- +-== String Expansions +- +-xref:xlat/index.adoc[String expansion] Using `%{...}` to perform dynamic +-string expansions. (also known as xref:xlat/index.adoc[xlat]) +- +-String expansions are usually performed in order to get additional +-information which is not immediately available to the policy. This +-information can be taken from almost any source, including other +-attributes, databases, and scripts. +- +-.Example +-[source,unlang] +----- +-update reply { +- &Framed-IP-Address := "%{sql:SELECT static_ip from table WHERE user = '%{User-Name}'}" +-} +----- +- +-== Data Types +- +-Each attribute used by the server has an associated +-xref:type/index.adoc[data type]. The `unlang` interpreter enforces +-restrictions on assignments, so that only valid data types can be +-assigned to an attribute. Invalid assignments result in a run-time +-error. +- +-.Example +-[source,unlang] +----- +-update reply { +- &Framed-IP-Address := 192.0.2.4 +- &Session-Timeout := 5 +- &Reply-Message := "hello" +-} +----- +- +-== Design Goals of Unlang +- +-The goal of `unlang` is to allow simple policies to be written with +-minimal effort. Conditional checks can be performed by the policies, +-which can then update the request or response attributes based on the +-results of those checks. `unlang` can only be used in a processing +-section, it cannot be used anywhere else, including in configuration +-sections for a client or a module. The reason for this limitation is +-that the language is intended to perform specific actions on requests +-and responses. The client and module sections contain definitions for +-a client or module; they do not define how a request is processed. +- +-`unlang` uses the same the basic syntax as the configuration files. +-The syntax of the configuration file for lines, comments, sections, +-sub-section, etc., all apply to `unlang`. +- +-Where `unlang` differs from the basic configuration file format is in +-complexity and operation. The normal configuration files are +-_declarative_ and they are _static_. That is, they declare variables +-and values for those variables. Those values do not change when the +-server is running. +- +-In contrast, `unlang` performs run-time processing of requests. +-Conditional statements such as xref:if.adoc[if] are evaluated for every +-packet that is received. Attribute editing statements such as +-xref:update.adoc[update] can be used to edit attribute contents or lists +-of attributes. +- +-.Example +-[source,unlang] +----- +-# First, the keyword 'if' +- +-# followed by condition which checks that the User-Name +-# attribute has value "bob" +- +-if (&User-Name == "bob") { +- # keyword "update" +- +- # followed by instructions to add the Reply-Message +- # attribute to the "reply" list, with contents +- # "Hello, bob" +- +- update reply { +- Reply-Message := "Hello, bob" +- } +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/keywords.adoc b/doc/antora/modules/unlang/pages/keywords.adoc +deleted file mode 100644 +index e6411ea984..0000000000 +--- a/doc/antora/modules/unlang/pages/keywords.adoc ++++ /dev/null +@@ -1,78 +0,0 @@ +-= Keywords +- +-The following tables list the keywords used in `Unlang`. These keywords +-implement the "flow control" of the policies. +- +-== Flow Control Keywords +- +-The _flow control_ keywords allow _if / then / else_ checks, simple +-looping, etc. +- +-.Flow Control +-[options="header"] +-[cols="30%,70%"] +-|===== +-| Keyword | Description +-| xref:break.adoc[break] | Exit early from a `foreach` loop. +-| xref:case.adoc[case] | Match inside of a `switch`. +-| xref:else.adoc[else] | Do something when an `if` does not match. +-| xref:elsif.adoc[elsif] | Check for condition when a previous `if` does not match. +-| xref:foreach.adoc[foreach] | Loop over a list of attributes. +-| xref:if.adoc[if] | Check for a condition, and execute a sub-policy if it matches. +-| xref:return.adoc[return] | Immediately stop processing a section. +-| xref:switch.adoc[switch] | Check for multiple values. +-|===== +- +-== Attribute Editing Keywords +- +-The _attribute editing_ keywords allow policies to add, delete, and +-modify attributes in any list or packet. +- +-.Attribute Editing +-[options="header"] +-[cols="30%,70%"] +-|===== +-| Keyword | Description +-| xref:update.adoc[update] | Add or filter attributes to a list +-|===== +- +-== Grouping Keywords +- +-The _grouping_ keywords allow policies to be organized into groups, +-including load-balancing. +- +-.Grouping +-[options="header"] +-[cols="30%,70%"] +-|===== +-| Keyword | Description +-| xref:group.adoc[group] | Group a series of statements. +-| xref:load-balance.adoc[load-balance] | Define a load balancing group without fail-over. +-| xref:redundant.adoc[redundant] | Define a redundant group with fail-over. +-| xref:redundant-load-balance.adoc[redundant-load-balance] | Define a redundant group with fail-over and load balancing. +-|===== +- +-== Module Keywords +- +-The _module_ keywords refer pre-packaged libraries that implement +-specific functionality, such as connecting to SQL, LDAP, etc. The +-name used here is not the literal string `module`. Instead, it is the +-name of an instance of a pre-packaged module such as `sql`, or `ldap`, or +-`eap`. +- +-The documentation below describes how to reference modules. That is, +-how to use `sql`, etc. in the policies. Please see +-`raddb/mods-available/` for configuration examples for each module. +- +-.Modules +-[options="header"] +-[cols="30%,70%"] +-|===== +-| Keyword | Description +-| xref:module.adoc[] | Execute a named module, e.g., `sql`. +-| xref:module_method.adoc[.] | Execute a particular method of a named module, e.g., `pap.authorize` +-| xref:module_builtin.adoc[reject] | Built-in modules, e.g., `reject`, or `ok`, etc. +-|===== +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/list.adoc b/doc/antora/modules/unlang/pages/list.adoc +deleted file mode 100644 +index a55a54f992..0000000000 +--- a/doc/antora/modules/unlang/pages/list.adoc ++++ /dev/null +@@ -1,72 +0,0 @@ +-= Attribute Lists +- +-An attribute list contains a set of attributes. The allowed lists +-are: +- +-`request`:: Attributes in the incoming request packet. +- +-`reply`:: Attributes in the outgoing reply packet. +- +-`control`:: Attributes in the internal "control" list that is +-associated with the request. +-+ +-The `control` attributes are used to manage how the request is +-processed. These attributes are never sent in any packet. +- +-`session-state`:: Attributes which are maintained across multi-packet +-exchanges. +- +-`proxy-request`:: Attributes in the proxied request packet to a home server. +- +-`proxy-reply`:: Attributes in the reply packet from the home server. +- +-`coa`:: Attributes in a CoA-Request packet which is sent to a home server. +- +-`disconnect`:: Attributes in a Disconnect-Request packet which is sent to a home server. +- +-There must be a colon `:` after the list name and before the attribute name. +-This syntax helps the server to distinguish between list names and attribute +-names. +- +-With the exception of `session-state`, all of the above lists are +-ephemeral. That is, they exist for one packet exchange, and only one +-packet exchange. When a reply is sent for a request, the above lists +-and all attributes are deleted. There is no way to reference an +-attribute from a previous packet. We recommend using a database to +-track complex state. +- +-The `coa` and `disconnect` lists can only be used when the server +-receives an Access-Request or Accounting-Request. Use `request` and +-`reply` instead of `coa` when the server receives a CoA-Request or +-Disconnect-Request packet. +- +-Adding one or more attributes to either of the `coa` or `disconnect` +-list causes server to originate a CoA-Request or Disconnect-Request +-packet. That packet is sent when the current Access-Request or +-Accounting-Request has been finished, and a reply sent to the NAS. +-See `raddb/sites-available/originate-coa` for additional information. +- +-In some cases, requests are associated a multi-packet exchange. For +-those situations, the `session-state` list is automatically saved when +-a reply is sent, and it is automatically restored when the next packet +-in sequence comes in. Once the packet exchange has been finished, the +-`session-state` list is deleted. +- +-In some cases, there is a parent-child relationship between requests. +-In those situations, it is possible for the policy rules in the child +-to refer to attributes in the parent. This reference can be made by +-prefixing the __ name with the `parent` qualifier. The key word +-`outer` is also a synonym for `parent`. If there are multiple +-parent-child relationships, the `parent` qualifier can be repeated. +- +-There is, however, no way for the parent to refer to the child. When +-the child is running, the parent is suspended. Once the child +-finishes, it is deleted, and is no longer accessible to the parent. +- +-.Examples +-`&parent.request.User-Name` + +-`&parent.reply.Reply-Message` + +-`&parent.parent.session-state.Filter-Id` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/load-balance.adoc b/doc/antora/modules/unlang/pages/load-balance.adoc +deleted file mode 100644 +index d64b161590..0000000000 +--- a/doc/antora/modules/unlang/pages/load-balance.adoc ++++ /dev/null +@@ -1,32 +0,0 @@ +-= The load-balance Statement +- +-.Syntax +-[source,unlang] +----- +-load-balance { +- [ statements ] +-} +----- +- +-The `load-balance` section is similar to the `redundant` section +-except that only one module in the subsection is ever called. +- +-In general, the +-xref:redundant-load-balance.adoc[redundant-load-balance] statement is +-more useful than this one. +- +-[ statements ]:: One or more `unlang` commands. Only one of the +-statements is executed. +- +-.Examples +- +-[source,unlang] +----- +-load-balance &User-Name { +- sql1 +- sql2 +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/module.adoc b/doc/antora/modules/unlang/pages/module.adoc +deleted file mode 100644 +index fd18f2f4ba..0000000000 +--- a/doc/antora/modules/unlang/pages/module.adoc ++++ /dev/null +@@ -1,86 +0,0 @@ +-= Modules +- +-.Syntax +-[source,unlang] +----- +- +----- +- +-The `` statement is a reference to the named module. Common +-module names include `pap`, `chap`, `files`, `eap`, and `sql`. The +-`modules { ... }` subsection of `radiusd.conf` contains all of the +-valid modules. +- +-When processing reaches a named module, the pre-compiled module is +-called. The module may succeed or fail and will return a status code +-to the `unlang` interpreter detailing success or failure. +- +-.Example +-[source,unlang] +----- +-chap +-sql +----- +- +-== Module Return Codes +- +-When a module is called, it returns one of the following codes to +-the interpreter; the meaning of each code is detailed to the right of +-the source, below: +- +-.Module Return Codes +- +-The below table describes the purpose of the rcodes that may be returned +-by a module call. In this case the 'operation' referenced in the table is +-the current module call. +- +-include::partial$rcode_table.adoc[] +- +-These return codes can be used in a subsequent +-xref:condition/index.adoc[conditional expression] thus allowing policies to +-perform different actions based on the behaviour of the modules. +- +-.Example +-[source,unlang] +----- +-sql +-if (notfound) { +- update reply { +- Reply-Message = "We don't know who you are" +- } +- reject +-} +----- +- +-== Module Return Code priority overrides +- +-In the case of modules, rcodes can be modified on a per-call basis. +- +-Module priority overrides are specified in a block inline with the module call. +-The format of an override is ` = (0+||return)` - That is, +-a number greater than or equal to 0, the priority of another rcode, or the special +-priority `return` which causes the current section to immediately exit. +- +-[source, unlang] +----- +-ldap { <1> +- fail = 1 <2> +- ok = handled <3> +- reject = return <4> +-} +----- +- +-<1> Call to the `ldap` module. +-<2> Sets the priority of the `fail` rcode to be `1`. If the priority +- of the rcode for the request is `0`, then the request request rcode +- will be set to `fail` if the module returns `fail`. +-<3> Sets the priority of the `ok` rcode to be whatever the default is for +- `handled` in this section. As the default for `handled` is usually +- `return`. If `ok` is returned, the current section will immediately +- exit. +-<4> Sets the priority of `reject` to be `return`. If the module returns +- `reject`, the current section will immediately exit. +- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/module_builtin.adoc b/doc/antora/modules/unlang/pages/module_builtin.adoc +deleted file mode 100644 +index f21a128953..0000000000 +--- a/doc/antora/modules/unlang/pages/module_builtin.adoc ++++ /dev/null +@@ -1,42 +0,0 @@ +-= Built-in Modules +- +-In some cases, it is useful to reject a request immediately or perform another +-action on it. The built-in modules can be used to perform these actions. These +-modules are named for the return codes given in the xref:module.adoc[module] +-section. +- +-In practice, these modules are implemented by the `always` module and +-exist so that a success or failure can be forced during the processing +-of a policy. +- +-The names and behaviours of these modules are given below: +- +-`fail`:: +-Causes the request to be treated as if a database failure had +-occurred. +- +-`noop`:: +-Do nothing. This also serves as an instruction to the +-configurable failover tracking that nothing was done in the current +-section. +- +-`ok`:: +-Instructs the server that the request was processed properly. This keyword can be used to over-ride earlier failures if the local +-administrator determines that the failures are not catastrophic. +- +-`reject`:: +-Causes the request to be immediately rejected. +- +-.Example +-[source,unlang] +----- +-if (!&User-Name) { +- update reply { +- Reply-Message := "We don't know who you are" +- } +- reject +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/module_method.adoc b/doc/antora/modules/unlang/pages/module_method.adoc +deleted file mode 100644 +index 98cd37582e..0000000000 +--- a/doc/antora/modules/unlang/pages/module_method.adoc ++++ /dev/null +@@ -1,27 +0,0 @@ +-= Module methods +- +-.Syntax +-[source,unlang] +----- +-. +----- +- +-This variant of xref:module.adoc[] is used in one processing +-section. It calls a module using the method of another processing +-section. For example, it can be used to call a module's `authorize` +-method while processing the `post-auth` section. +- +-The `` portion must refer to an existing module; the +-`` portion must refer to processing method supported by that +-module. Typically, the names of the processing method will be the +-same as the processing sections. +- +-.Example +-[source,unlang] +----- +-sql.recv.Accounting-Request +-files.recv.Access-Request +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/redundant-load-balance.adoc b/doc/antora/modules/unlang/pages/redundant-load-balance.adoc +deleted file mode 100644 +index 2322f726fd..0000000000 +--- a/doc/antora/modules/unlang/pages/redundant-load-balance.adoc ++++ /dev/null +@@ -1,39 +0,0 @@ +-= The redundant-load-balance Statement +- +-.Syntax +-[source,unlang] +----- +-redundant-load-balance { +- [ statements ] +-} +----- +- +-The `redundant-load-balance` section operates as a combination of the +-xref:redundant.adoc[redundant] and xref:load-balance.adoc[load-balance] +-sections. +- +-[ statements ]:: One or more `unlang` commands. +-+ +-If the selected statement succeeds, then the server stops processing +-the `redundant-load-balance` section. If, however, that statement fails, +-then the next statement in the list is chosen (wrapping around to the +-top). This process continues until either one statement succeeds or all +-of the statements have failed. +-+ +-All of the statements in the list should be modules, and of the same +-type (e.g., `ldap` or `sql`). All of the statements in the list should +-behave identically, otherwise different requests will be processed +-through different modules and will give different results. +- +-.Example +-[source,unlang] +----- +-redundant-load-balance &User-Name { +- sql1 +- sql2 +- sql3 +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/redundant.adoc b/doc/antora/modules/unlang/pages/redundant.adoc +deleted file mode 100644 +index e837d1f369..0000000000 +--- a/doc/antora/modules/unlang/pages/redundant.adoc ++++ /dev/null +@@ -1,42 +0,0 @@ +-= The redundant Statement +- +-.Syntax +-[source,unlang] +----- +-redundant { +- [ statements ] +-} +----- +- +-The `redundant` section executes a series of statements in sequence. +-As soon as one statement succeeds, the rest of the section is skipped. +- +-[ statements ]:: One or more `unlang` commands. Processing starts +-from the first statement in the list. +-+ +-If the selected statement succeeds, then the server stops processing +-the `redundant` section. If, however, that statement fails, then the +-next statement in the list is chosen. This process continues until +-either one statement succeeds or all of the statements have failed. +-+ +-All of the statements in the list should be modules, and of the same +-type (e.g., `ldap` or `sql`). All of the statements in the list should +-behave identically, otherwise different requests will be processed +-through different modules and will give different results. +- +-In general, we recommend using the +-xref:redundant-load-balance.adoc[redundant-load-balance] statement +-instead of `redundant`. +- +-.Example +-[source,unlang] +----- +-redundant { +- sql1 +- sql2 +- sql3 +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/return.adoc b/doc/antora/modules/unlang/pages/return.adoc +deleted file mode 100644 +index aea1bc2ab2..0000000000 +--- a/doc/antora/modules/unlang/pages/return.adoc ++++ /dev/null +@@ -1,36 +0,0 @@ +-= The return Statement +- +-.Syntax +-[source,unlang] +----- +-return +----- +- +-The `return` statement is used to exit a processing section such as +-`authorize`. It behaves similarly to the +-xref:break.adoc[break] statement, except that it is not limited to +-being used inside of a xref:foreach.adoc[foreach] loop. +- +-The `return` statement is not strictly necessary. It is mainly used +-to simplify the layout of `unlang` policies. If the `return` +-statement did not exist, then every xref:if.adoc[if] statement might need +-to have a matching xref:else.adoc[else] statement. +- +-The `return` statement will also exit a policy which is defined in the +-`policy { ... } ` subsection. This behavior allows policies to be +-treated as a function call. Any `return` inside of the policy section +-will only return from that policy. The `return` will _not_ return +-from the enclosing processing section which called the policy. +- +-.Example +-[source,unlang] +----- +-sql +-if (&reply.Filter-Id == "hello") { +- return +-} +-... +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/return_codes.adoc b/doc/antora/modules/unlang/pages/return_codes.adoc +deleted file mode 100644 +index 3b09c2dc52..0000000000 +--- a/doc/antora/modules/unlang/pages/return_codes.adoc ++++ /dev/null +@@ -1,17 +0,0 @@ +-= Return codes +- +-Many operations in the server produce a return code (rcode). +-The different rcodes give a course indication of whether a particular operation +-(a module call, string expansion, or keyword) was successful. +- +-Unlike return values in other languages, FreeRADIUS' rcodes are are always taken +-from a fixed compiled-in set. +- +-include::partial$rcode_table.adoc[] +- +-Return codes propagate through nested unlang sections based on their priority. +-If a rcode returned by an operation has a higher priority than the current rcode +-associated with the request, then the request rcode is overwritten. +- +-Return code priorities are assigned by the section the module call, expansion or +-keyword was used in. +diff --git a/doc/antora/modules/unlang/pages/switch.adoc b/doc/antora/modules/unlang/pages/switch.adoc +deleted file mode 100644 +index deff7032bd..0000000000 +--- a/doc/antora/modules/unlang/pages/switch.adoc ++++ /dev/null +@@ -1,83 +0,0 @@ +-= The switch Statement +- +-.Syntax +-[source,unlang] +----- +-switch { +- case { +- [ statements-1 ] +- } +- case { +- [ statements-2 ] +- } +- case { +- [ statements-3 ] +- } +-} +----- +- +-A `switch` statement causes the server to evaluate _expansion_, which +-can be an xref:attr.adoc[&Attribute-Name] or +-xref:condition/operands.adoc[data]. The result is compared against _match-1_ +-and _match-2_ to find a match. If no string matches, then the server +-looks for the default xref:case.adoc[case] statement, which has no +-associated match. +- +-The matching is done via equality. The `switch` statement is mostly +-syntactic sugar and is used to simplify the visual form of the +-configuration. It is mostly equivalent to the following use of +-xref:if.adoc[if] statements: +- +-.Nearly equivalent syntax +-[source,unlang] +----- +-if ( == ) { +- [ statements-1 ] +-} +-elsif ( == ) { +- [ statements-2 ] +-} +-else { +- [ statements-3 ] +-} +----- +- +-The only difference between the two forms is that for a `switch` +-statement, the _expansion_ is evaluated only once. For the equivalent +-xref:if.adoc[if] statement, the _expansion_ is evaluated again for every +-xref:if.adoc[if]. +- +-If a matching xref:case.adoc[case] is found, the statements within +-that xref:case.adoc[case] are evaluated. If no matching +-xref:case.adoc[case] is found, the `case` section with no "match" is +-evaluated. If there is no such `case { ...}` subsection, then the +-`switch` statement behaves as if the `case {...}` section was empty. +- +-//// +-For compatibility with version 3, and empty `case` statement can also +-be used instead of `default`. +-//// +- +-The _match_ text for the xref:case.adoc[case] statement can be an +-xref:attr.adoc[&Attribute-Name] or xref:type/index.adoc[data]. +- +-No statement other than xref:case.adoc[case] can appear in a `switch` +-statement, and the xref:case.adoc[case] statement cannot appear outside of a +-`switch` statement. +- +-.Example +-[source,unlang] +----- +-switch &User-Name { +- case "bob" { +- reject +- } +- +- case { +- ok +- } +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/all_types.adoc b/doc/antora/modules/unlang/pages/type/all_types.adoc +deleted file mode 100644 +index 0bace01354..0000000000 +--- a/doc/antora/modules/unlang/pages/type/all_types.adoc ++++ /dev/null +@@ -1,80 +0,0 @@ +-= List of Data Types +- +-The server support a wide range of data types, both in `unlang` and in +-the dictionaries. This page outlines the names and functionality of +-those data types. +- +-== Basic Data Types +- +-There are a number of "basic" data types. These data types are +-fixed-size, and encapsulate simple concepts such as "integer" or "IP +-address". +- +-Basic data types can be used in `unlang`, as they contain simple +-values which can be compared, or assigned to one attribute. In most +-cases, it is not necessary to know the name of the data type. It is +-possible to write values in the format you expect, The server will do +-"the right thing" when interpreting the values. +- +-.Basic Data Types +-[options="header"] +-[cols="15%,85%"] +-|===== +-| Data Type | Description +-| bool | boolean +-| date | calendar date +-| ethernet | Ethernet address +-| float32 | 32-bit floating point number +-| float64 | 64-bit floating point number +-| ifid | interface ID +-| int8 | 8-bit signed integer +-| int16 | 16-bit signed integer +-| int32 | 32-bit signed integer +-| int64 | 64-bit signed integer +-| ipaddr | IPv4 address +-| ipv6addr | IPv6 address +-| ipv4prefix | IPv4 network with address and prefix length +-| ipv6prefix | IPv6 network with address and prefix length +-| octets | raw binary, printed as hex strings +-| string | printable strings +-| time_delta | difference between two calendar dates +-| uint8 | 8-bit unsigned integer +-| uint16 | 16-bit unsigned integer +-| uint32 | 32-bit unsigned integer +-| uint64 | 64-bit unsigned integer +-|===== +- +-=== Structural Data Types +- +-The following data types are "structural", in that they form +-parent-child relationships between attributes. These data types can +-only be used in the dictionaries. They cannot be used in `unlang` +-statements. +- +-.Structural Data Types +-[options="header"] +-[cols="15%,85%"] +-|===== +-| Data Type | Description +-| struct | structure which contains fixed-width fields +-| tlv | type-length-value which contains other attributes +-| vsa | Encapsulation of vendor-specific attributes +-|===== +- +-=== Protocol-Specific Data Types +- +-The following data types are used only in certain protocols. These +-data types can be used only in the dictionaries. They cannot be used +-in `unlang` statements. +- +-.Protocol Specific Data Types +-[options="header"] +-[cols="15%,15%,70%"] +-|===== +-| Data Type | Protocol | Description +-| abinary | RADIUS | Ascend binary filters +-| extended | RADIUS | attributes which "extend" the number space +-|===== +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS +diff --git a/doc/antora/modules/unlang/pages/type/double.adoc b/doc/antora/modules/unlang/pages/type/double.adoc +deleted file mode 100644 +index 6c3e708eaa..0000000000 +--- a/doc/antora/modules/unlang/pages/type/double.adoc ++++ /dev/null +@@ -1,39 +0,0 @@ +-= Double-Quoted Strings +- +-.Syntax +-`"string"` +- +-A double-quoted string is interpreted via the usual rules in +-programming languages for double quoted strings. The double-quote +-character can be placed in a string by escaping it with a backslash. +-Carriage returns and line-feeds can also be used via the usual `\r` and +-`\n` syntax. +- +-The main difference between the single and double quoted strings is +-that the double quoted strings can be dynamically expanded. The syntax +-`${...}` is used for parse-time expansion and `%{...}` is used for +-run-time expansion. The difference between the two methods is that the +-`${...}` form is expanded when the server loads the configuration +-files and is valid anywhere in the configuration files. The `%{...}` +-link:xlat.adoc[string expansion] form is valid only in conditional +-expressions and attribute assignments. +- +-The output of the dynamic expansion can be interpreted as a string, +-a number, or an IP address, depending on its context. +- +-Note that the interpretation of text _strongly_ depends on the +-context. The text `"0000"` can be interpreted as a data type +-"integer", having value zero, or a data type "string", having value +-`"0000"`. In general when a particular piece of text is used, it is +-used with the context of a known attribute. That attribute has a +-link:data.adoc[data type], and the text will be interpreted as that +-data type. +- +-.Examples +- +-`"word"` + +-`"a string"` + +-`"this has embedded\ncharacters"` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/index.adoc b/doc/antora/modules/unlang/pages/type/index.adoc +deleted file mode 100644 +index 7d0d70f3ae..0000000000 +--- a/doc/antora/modules/unlang/pages/type/index.adoc ++++ /dev/null +@@ -1,117 +0,0 @@ +-= Data Types +- +-Unlang supports a number of data types. These data types are used in +-conditional expressions or when assigning a value to an attribute. +- +-== Using Data Types +- +-The server support a wide range of data types, as given in the +-xref:unlang/type/all_types.adoc[list of data types] page. The choice +-of which data type applies is determined by the context in which that +-data type is used. This context is usually taken from an attribute +-which is being assigned a value. +- +-The `unlang` interpreter uses pre-defined attributes which are defined +-in dictionaries. The dictionaries define both a name, and a data type +-for the attributes. In the interpreter, then, attributes can be +-assigned a value or compared to a value, without specifying the data +-type. The interpreter knows how to parse the value by using the data +-type assigned to the attribute. +- +-The result is that in most cases, it is not necessary to know the name +-of the data types. It is possible to write values in the format you +-expect, and he server will do "the right thing" when interpreting the +-values. +- +-.Attributes with Different Data Types +-[source,unlang] +----- +-Framed-IP-Address = 192.0.2.1 +-Framed-IPv6-Address = 2001:db8:: +-Reply-Message = "This is a reply" +-Port-Limit = 5 +-Boolean = true +-Octets-Thing = 0xabcdef0102030405 +-MAC-Address = 00:01:02:03:04:05 +----- +- +-== Parsing Data Types +- +-The interpreter is flexible when parsing data types. So long as the +-value can be parsed as the given data type without error, the value +-will be accepted. +- +-For example, a particular attribute may be of data type `ipaddr` in +-order to store IPv4 addresses. The interpreter will then accept the +-following strings as valid IPv4 addresses: +- +-`192.168.0.2`:: xref:type/string/unquoted.adoc[Unquoted text], interpreted as the data type +- +-`'192.168.0.2'`:: xref:type/string/single.adoc[Single-quoted string], the contents of the string are parsed as the data type. +-+ +-The single-quoted string form is most useful when the data type +-contains special characters that may otherwise confuse the parser. +- +-`"192.168.0.2"`:: xref:type/string/double.adoc[Double-quoted string]. +-+ +-The contents of the string are dynamically expanded as described in +-the xref:unlang/xlat/index.adoc[dynamic expansion] page. The +-resulting output is then interpreted as the given data type. +- +-`{backtick}/bin/echo 192.168.0.2{backtick}`:: xref:type/string/backticks.adoc[backtick-quoted string]. +-Run a script, and parse the resulting string as the data type. +- +-Similar processing rules are applied when parsing assignments and +-comparisons, for all attributes and data types. +- +-=== Casting Data Types +- +-In some cases, it is necessary to parse values which do not refer to +-attributes. This situation usually occurs when two values need to be +-compared, as in the following example: +- +-[source,unlang] +----- +-if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == 192.0.2.1) } +- .... +-} +----- +- +-Since there is no attribute on either side of the `==` operator, the +-interpreter has no way of knowing that the string `192.0.2.1` is an IP +-address. There is unfortunately no way of automatically parsing +-strings in order to determine the data type to use. Any such +-automatic parsing would work most of the time, but it would have +-error cases where the parsing was incorrect. +- +-The solution is to resolve these ambiguities by allowing the values to +-be cast to a particular type. Casting a value to a type tells the +-interpreter how that value should be parsed. Casting is done by +-prefixing a value with the type name, surrounded by angle brackets; +-`<...>`. +- +-.Syntax +----- +-<...>value +----- +- +-We can add a cast to the above example, as follows: +- +-[source,unlang] +----- +-if ("%{sql:SELECT ipaddress FROM table WHERE user=%{User-Name}}" == 192.0.2.1) } +- .... +-} +----- +- +-In this example, we prefix the IP address with the string ``. +-The interpreter then knows that the value `192.0.2.` should be +-interpreted as the data type `ipaddr`, and not as the literal string +-`"192.0.2."`. +- +-For a full list of data types which can be used in a cast, please see +-the xref:unlang/type/all_types.adoc[list of data types] page, and the +-"Basic Type Types" section. +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/ip.adoc b/doc/antora/modules/unlang/pages/type/ip.adoc +deleted file mode 100644 +index fc25ae8eb2..0000000000 +--- a/doc/antora/modules/unlang/pages/type/ip.adoc ++++ /dev/null +@@ -1,15 +0,0 @@ +-= IP Addresses +- +-.Examples +- +-`192.0.2.16` + +-`::1` + +-`example.com` +- +-Depending on the context, a "simple word", as above, may be +-interpreted as an IPv4 or an IPv6 address. This interpretation is +-usually done when the string is used in the context of an attribute, +-or to compare two addresses or assign an address to an attribute. +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/numb.adoc b/doc/antora/modules/unlang/pages/type/numb.adoc +deleted file mode 100644 +index 284cf819c1..0000000000 +--- a/doc/antora/modules/unlang/pages/type/numb.adoc ++++ /dev/null +@@ -1,11 +0,0 @@ +-= Numbers +- +-.Examples +- +-`0` + +-`563` +- +-Numbers are unsigned integers that are composed of decimal digits. +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/string/backticks.adoc b/doc/antora/modules/unlang/pages/type/string/backticks.adoc +deleted file mode 100644 +index 9372b4c736..0000000000 +--- a/doc/antora/modules/unlang/pages/type/string/backticks.adoc ++++ /dev/null +@@ -1,38 +0,0 @@ +-= Backtick-quoted string +- +-.Syntax +-`{backtick}string{backtick}` +- +-The backtick operator is used to perform a run-time expansion +-similar to what is done with the Unix shell. The contents of the string +-are split into one or more sub-strings, based on intermediate +-whitespace. Each substring is then expanded as described above for +-double quoted strings. The resulting set of strings is used to execute a +-program with the associated arguments. +- +-The output of the program is recorded, and the resulting data is +-used in place of the input string value. Where the output is composed of +-multiple lines, any carriage returns and line feeds are replaced by +-spaces. +- +-For safety reasons, the full path to the executed program should be +-given. In addition, the string is split into arguments _before_ the +-substrings are dynamically expanded. This step is done both to allow +-the substrings to contain spaces, and to prevent spaces in the +-expanded substrings from affecting the number of command-line +-arguments. +- +-For performance reasons, we recommend that the use of back-quoted +-strings be kept to a minimum. Executing external programs is +-relatively expensive, and executing a large number of programs for +-every request can quickly use all of the CPU time in a server. If many +-programs need to be executed, it is suggested that alternative ways to +-achieve the same result be found. In some cases, using a real +-programming language such as `lua`, `perl` or `python` may be better. +- +-.Examples +- +-`{backtick}/bin/echo hello{backtick}` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/string/double.adoc b/doc/antora/modules/unlang/pages/type/string/double.adoc +deleted file mode 100644 +index ea87bc5c45..0000000000 +--- a/doc/antora/modules/unlang/pages/type/string/double.adoc ++++ /dev/null +@@ -1,68 +0,0 @@ +-= Double Quoted Strings +- +-.Syntax +-`"string"` +- +-A double-quoted string allows escape sequences and xref:xlat/index.adoc[dynamic +-expansions]. As with xref:type/string/single.adoc[single-quoted strings], text +-within double quotes can include spaces. +- +-The main difference between the single and double quoted strings is +-that the double quoted strings can be dynamically expanded. The syntax +-`${...}` is used for parse-time expansion and `%{...}` is used for +-run-time expansion. The difference between the two methods is that the +-`${...}` form is expanded when the server loads the configuration +-files and is valid anywhere in the configuration files. The `%{...}` +-xref:xlat/index.adoc[string expansion] form is valid only in conditional +-expressions and attribute assignments. +- +-The output of the dynamic expansion can be interpreted as a string, +-a number, or an IP address, depending on its context. +- +-Note that the interpretation of text _strongly_ depends on the +-context. The text `"0000"` can be interpreted as a data type +-"integer", having value zero, or a data type "string", having value +-`"0000"`. In general when a particular piece of text is used, it is +-used with the context of a known attribute. That attribute has a +-xref:type/index.adoc[data type], and the text will be interpreted as that +-data type. +- +-NOTE: Most values retrieved from external datastores will be treated implicitly +-as double-quoted strings. +- +-== Escape sequences +- +-Escape sequences allow the inclusion of characters that may be difficult to +-represent in datastores, or the FreeRADIUS configuration files. +- +-.Escape sequences and their descriptions +-[options="header", cols="15%,85%"] +-|===== +-| Escape sequence | Character represented +-| `\\` | Literal backslash (0x5c) +-| `\r` | Carriage return (0x0d) +-| `\n` | Line feed (0x0a) +-| `\t` | Horizontal tab (0x09) +-| `\"` | Double quote (0x22) +-| `\x` | A byte whose numerical value is given by `` interpreted as a hexadecimal number. +-| `\x` | A byte whose numerical value is given by `` interpreted as an octal number. +-|===== +- +-.Examples +- +-`"word"` + +-`"a string"' + +-`"foo\"bar\""` + +-`"this is a long string"` + +-`"this has embedded\ncharacters"` + +-`"attribute\tvalue\nusername\t%{User-Name}\nreply-message\t%{reply.Reply-Message}"` +-`"The result of 'SELECT * FROM foo WHERE 1' is: %{sql:SELECT * FROM foo WHERE 1}"` +- +-// Licenced under CC-by-NC 4.0. +-// Copyright (C) 2019 Arran Cudbard-Bell +-// Copyright (C) 2019 The FreeRADIUS project. +-// Copyright (C) 2020 Network RADIUS SAS. +- +- +- +- +diff --git a/doc/antora/modules/unlang/pages/type/string/escaping.adoc b/doc/antora/modules/unlang/pages/type/string/escaping.adoc +deleted file mode 100644 +index e63a498ce0..0000000000 +--- a/doc/antora/modules/unlang/pages/type/string/escaping.adoc ++++ /dev/null +@@ -1,14 +0,0 @@ +-= Character Escaping +- +-The quotation characters in the above string data types can be +-escaped by using the backslash, or `\,` character. The backslash +-character itself can be created by using `\\`. Carriage returns and +-line feeds can be created by using `\n` and `\r`. +- +-.Examples +- +-`"I say \"hello\" to you"` + +-`"This is split\nacross two lines"` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/string/single.adoc b/doc/antora/modules/unlang/pages/type/string/single.adoc +deleted file mode 100644 +index fa2ac05255..0000000000 +--- a/doc/antora/modules/unlang/pages/type/string/single.adoc ++++ /dev/null +@@ -1,19 +0,0 @@ +-= Single Quoted Strings +- +-.Syntax +-`'string'` +- +-A single-quoted string is interpreted without any dynamic string +-expansion. The quotes allow the string to contain spaces, among other +-special characters. The single quote character can be placed in such a +-string by escaping it with a backslash. +- +-.Examples +- +-`'hello'` + +-`'foo bar`' + +-`'foo\\'bar'` + +-`'this is a long string'` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/type/string/unquoted.adoc b/doc/antora/modules/unlang/pages/type/string/unquoted.adoc +deleted file mode 100644 +index 9dd6e557b7..0000000000 +--- a/doc/antora/modules/unlang/pages/type/string/unquoted.adoc ++++ /dev/null +@@ -1,21 +0,0 @@ +-= Unquoted Strings +- +-Where a series of characters cannot be parsed as a decimal number, +-they are interpreted as a simple string composed of one word. This +-word is delimited by spaces, or by other tokens, such as `)` in +-conditional expressions. +- +-This unquoted text is interpreted as simple strings and are generally +-equivalent to placing the string in single quotes. +- +-The interpretation of the text depends on the context, which is +-usually defined by an attribute which has a xref:type/index.adoc[data type]. +- +-.Examples +- +-`Hello` + +-`192.168.0.1` + +-`00:01:02:03:04:05` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/update.adoc b/doc/antora/modules/unlang/pages/update.adoc +deleted file mode 100644 +index 645f4d8aba..0000000000 +--- a/doc/antora/modules/unlang/pages/update.adoc ++++ /dev/null +@@ -1,160 +0,0 @@ +-= The update Statement +- +-.Syntax +-[source,unlang] +----- +-update [ ] { +- +- ... +-} +----- +- +-The `update` statement adds attributes to, or edits the attributes in, +-the named __. +- +-The `update` statement consists of the following syntax elements: +- +-:: The attribute list which will be updated. The list is +-usually `request`, `reply`, or `control`. +-+ +-If the __ qualifier is omitted, then each entry inside of the +-`update` section *must* be prefixed with a list name. For example, +-`&request.User-Name ...` +- +-:: The server attribute which is assigned the +-__. +- +-:: The operator such as `=`, `:=`, etc. +- +-:: The value which is assigned to the attribute. If the field +-is a double-quoted string, it undergoes xref:xlat/index.adoc[string +-expansion], and the resulting value is assigned to the attribute. +- +-The update process is atomic, in that either all of the attributes are +-modified, or none of them are modified. If the `update` fails for any +-reason, then all of the results are discarded, and the `update` does +-not affect any server attributes. +- +-.Example +-[source,unlang] +----- +-update reply { +- &Reply-Message := "Hello!" +- &Framed-IP-Address := 192.0.2.4 +-} +----- +- +-== Lists +- +-The __ field sets the attribute list that will be updated. If +-the __ qualifier is omitted, then each entry inside of the +-`update` section *must* be prefixed with a list name. For example, +-`&request.User-Name ...` +- +-Please see the xref:list.adoc[list] page for valid list names. +- +-== Server Attributes +- +-The __ field is an attribute name, such as +-`&Reply-Message`. The attribute name may also be prefixed with a +-__ qualifier, which overrides the __ given at the start +-of the `update` section. +- +-NOTE: In version 3, the leading `&` is optional but recommended. +- +-== Editing Operators +- +-The `` field is used to define how the attribute is processed. +-Different operators allow attributes to be added, deleted, or +-replaced, as defined below. +- +-.Editing Operators +-[options="header"] +-[cols="10%,90%"] +-|===== +-| Operator | Description +-| = | Add the attribute to the list, if and only if an attribute of +-the same name is not already present in that list. +-| := | Add the attribute to the list. If any attribute of the same +-name is already present in that list, its value is replaced with the +-value of the current attribute. +-| += | Add the attribute to the tail of the list, even if attributes +-of the same name are already present in the list. +-| ^= | Add the attribute to the head of the list, even if attributes +-of the same name are already present in the list. +-| -= | Remove all attributes from the list that match __. +-| !* | Delete all occurances of the attribute, no matter what the value. +-|===== +- +-== Filtering Operators +- +-The following operators may also be used in addition to the ones +-listed above. These operators use the __ and +-__ fields to enforce limits on all attributes in the given +-__, and to edit attributes which have a matching +-__ name. All other attributes are ignored. +- +-.Filtering Operators +-[options="header] +-[cols="10%,90%"] +-|===== +-| Operator | Description +-| == | Keep only the attributes in the list that match __ +-| < | Keep only the attributes in the list that have values less than __. +-| \<= | Keep only the attributes in the list that have values less than or equal to __. +-| > | Keep only the attributes in the list that have values greater than __. +-| >= | Keep only the attributes in the list that have values greater than or equal to __. +-| =~ | Keep only the attributes in the list which match the regular expression given in __. +-| !~ | Keep only the attributes in the list which do not match the regular expression given in __. +-|===== +- +-The `==` operator is very different from the `=` operator listed +-above. The `=` operator is used to add new attributes to the list, +-while the `==` operator removes all attributes that do not match the +-given value. +- +-The comparison operators `<`, `<=`, `>`, and `>=` have some additional +-side effects. Any non-matching value is replaced by the __ +-given here. If no attribute exists, it is created with the given +-__. +- +-For IP addresses, the operators `>`, `>=`, `<`, and `\<=` check for +-membership in a network. The __ field should then be a IP +-network, given in `address/mask` format. +- +-.Example +-[source,unlang] +----- +-update reply { +- &Session-timeout := 86400 +-} +----- +- +-.Example +-[source,unlang] +----- +-update reply { +- &Reply-Message += "Rejected: Also, realm does not end with ac.uk" +-} +----- +- +-== Values +- +-The __ field is the value which is assigned to the +-__. The interpretation of the __ field +-depends on the data type of the contents. For example, if the string +-`"192.0.2.1"` is assigned to an attribute of the `string` data type, +-then the result is an ASCII string containing that value. However, if +-the same string is assigned to an attribute of the `ipaddr` data type, +-then the result is a 32-bit IPv4 address, with binary value `0xc0000201`. +- +-.Example +-[source,unlang] +----- +-update reply { +- &Session-Timeout <= 3600 +-} +----- +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/xlat/alternation.adoc b/doc/antora/modules/unlang/pages/xlat/alternation.adoc +deleted file mode 100644 +index adb76043dd..0000000000 +--- a/doc/antora/modules/unlang/pages/xlat/alternation.adoc ++++ /dev/null +@@ -1,24 +0,0 @@ +-= Alternation Syntax +- +-Alternation syntax similar to that used in Unix shells may also be +-used: +- +-`%{%{Foo}:-bar}` +- +-This code returns the value of `%{Foo}`, if it has a value. +-Otherwise, it returns a literal string bar. +- +-`%{%{Foo}:-%{Bar}}` +- +-This code returns the value of `%{Foo}`, if it has a value. +-Otherwise, it returns the expansion of `%{Bar}`. +- +-These conditional expansions can be nested to almost any depth, such +-as with `%{%{One}:-%{%{Two}:-%{Three}}}`. +- +-.Examples +-`%{%{Stripped-User-Name}:-%{User-Name}}` + +-`%{%{Framed-IP-Address}:-}` +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/xlat/attribute.adoc b/doc/antora/modules/unlang/pages/xlat/attribute.adoc +deleted file mode 100644 +index a3ee29bb06..0000000000 +--- a/doc/antora/modules/unlang/pages/xlat/attribute.adoc ++++ /dev/null +@@ -1,54 +0,0 @@ +-= Attribute References +- +-Attributes in a list may be referenced via one of the following two +-syntaxes: +- +-`%{Attribute-Name}` + +-`%{:Attribute-Name}` +- +-The `:` prefix is optional. If given, it must be a valid +-reference to an xref:list.adoc[attribute list]. +- +-If the `:` prefix is omitted, then the `request` list is +-assumed. +- +-For EAP methods with tunneled authentication sessions (i.e. PEAP and +-EAP-TTLS), the inner tunnel session can refer to a list for the outer +-session by prefixing the list name with `outer.` ; for example, +-`outer.request`. +- +-When a reference is encountered, the given list is examined for an +-attribute of the given name. If found, the variable reference in the +-string is replaced with the value of that attribute. Otherwise, the +-reference is replacedd with an empty string. +- +-.Examples +- +-`%{User-Name}` + +-`%{request.User-Name} # same as above` + +-`%{reply.User-Name}` + +-`%{outer.request.User-Name} # from inside of a TTLS/PEAP tunnel` +- +-Examples of using references inside of a string: +- +-`"Hello %{User-Name}"` + +-`"You, %{User-Name} are not allowed to use %{NAS-IP-Address}"` +- +-== Additional Variations +- +-`%{Attribute-Name[#]}`:: +-Returns an integer containing the number of named attributes +- +-`%{Attribute-Name[0]}`:: +- +-When an attribute appears multiple times in a list, this syntax allows +-you to address the attributes as with array entries. `[0]` refers to +-the first attributes, `[1]` refers to the second attribute, etc. +- +-`%{Attribute-Name[*]}`:: +- +-Returns a comma-separated string containing all values for the named +-attributes. +- +-// Copyright (C) 2020 Network RADIUS SAS. Licenced under CC-by-NC 4.0. +-// Development of this documentation was sponsored by Network RADIUS SAS. +diff --git a/doc/antora/modules/unlang/pages/xlat/builtin.adoc b/doc/antora/modules/unlang/pages/xlat/builtin.adoc +deleted file mode 100644 +index f236a575d7..0000000000 +--- a/doc/antora/modules/unlang/pages/xlat/builtin.adoc ++++ /dev/null +@@ -1,891 +0,0 @@ +-= Built-In Expansions +- +-In addition to storing attribute references, the server has a number +-of built-in expansions. These expansions act largely as functions +-which operate on inputs, and produce an output. +- +- +- +-== Attribute Manipulation +- +-=== %{length: ... } +- +-The `length` expansion returns the size of the input as an integer. +-When the input is a string, then the output is identical to the +-`strlen` expansion. +- +-When the input is an attribute reference, the output is the size of +-the attributes data as encoded "on the wire". +- +-.Return: _size_ +- +-.Determining the length of fixed and variable length attributes +-==== +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "Caipirinha" +- &Framed-IP-Address := 192.0.2.1 +-} +- +-update reply { +- &Reply-Message := "The length of %{control:Tmp-String-0} is %{length:&control:Tmp-String-0}" +- &Reply-Message += "The length of %{control:Framed-IP-Address} is %{length:&control:Framed-IP-Address}" +-} +----- +- +-.Output +-.... +-The length of Caipirinha is 10 +-The length of 192.168.0.2 is 4 +-.... +-==== +- +-`length` is built in to the server core. +- +- +- +-=== %{integer:<&ref>} +- +-Print the value of the attribute an integer. +- +-In normal operation, `integer` attributes are printed using the name +-given by a `VALUE` statement in a dictionary. Similarly, date +-attributes are printed as dates, i.e., "January 1 2010. +- +-The `integer` expansion applies only to attributes which can be +-converted to an integer. For all other inputs, it returns `0`. +- +-A common usage is to find the difference between two dates. +- +-For example, if a request contains `Service-Type = Login-User`, the +-expansion of `%{integer:&Service-Type}` will yield `1`, which is the +-value associated with the `Login-User` name. Using +-`%{integer:&Event-Timestamp}` will return the event timestamp as an +-unsigned 32-bit number. +- +-.Return: _string_ +- +-.Determining the integer value of an enumerated attribute +-==== +-[source,unlang] +----- +-update { +- &control:Service-Type := Login-User +-} +-update reply { +- &Reply-Message := "The value of Service-Type is %{integer:&control:Service-Type}" +-} +----- +- +-.Output +- +-``` +-The value of Service-Type is 1 +-``` +-==== +- +-`integer` is built in to the server core. +- +- +- +-=== %{rand:} +- +-Generate random number from `0` to `-1`. +- +-.Return: _uint64_ +- +-.Generating a random number between 0 and 511 +-==== +-[source,unlang] +----- +-update reply { +- &Reply-Message := "The random number is %{rand:512}" +-} +----- +- +-.Output +- +-``` +-The random number is 347 +-``` +-==== +- +-`rand` is provided by the `rlm_expr` module. +- +- +- +-=== %{tag:} +- +-CAUTION: This expansion is deprecated and will likely be removed. +- +-Returns a list of tags for any attributes found using ````. +- +-.Return: _int8_ +- +-.Determining the tag value of the second instance of the `radius.Tunnel-Server-Endpoint` attribute +-==== +-[source,unlang] +----- +-update request { +- &Tunnel-Server-Endpoint := '192.0.1.1' +- &Tunnel-Server-Endpoint:1 := '192.0.5.2' +- &Tunnel-Server-Endpoint:1 += '192.0.3.8' +- &Tunnel-Server-Endpoint:2 := '192.0.2.1' +- &Tunnel-Server-Endpoint:2 += '192.0.3.4' +-} +- +-update reply { +- &Reply-Message := "The tag value of the second instance of Tunnel-Server-Enpoint is %{request:Tunnel-Server-Endpoint[1]}" +-} +----- +- +-.Output +- +-``` +-The tag value of the second instance of Tunnel-Server-Enpoint is 192.0.5.2 +-``` +-==== +- +-`tag` is built in to the server core. +- +- +- +-=== %{string:} +- +-Convert input to a string (if possible). For _octets_ type attributes, this +-means interpreting the data as a UTF8 string, and inserting octal escape +-sequences where appropriate. +- +-For other types, this means printing the value in its _presentation_ format, +-i.e. dotted quads for IPv4 addresses, link:https://en.wikipedia.org/wiki/ISO_8601[ISO 8601] +-time for date types, enumeration values for attributes such as `radius.Service-Type` etc. +- +-.Return: _string_ +- +-.String interpolation using the raw octets value of Tmp-Octets-0, and the stringified version +-==== +-[source,unlang] +----- +-update control { +- &Tmp-Octets-0 := 0x7465737431 +-} +-update reply { +- &Reply-Message := "The string value of %{control:Tmp-Octets-0} is %{string:%{control:Tmp-Octets-0}}" +-} +----- +-==== +- +-.Output +- +-``` +-The string value of 0x7465737431 is test1 +-``` +- +-`string` is built in to the server core. +- +- +- +-== Server Manipulation +- +-=== %{config:} +- +-Refers to a variable in the configuration file. See the documentation +-on configuration file references. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-"Server installed in %{config:prefix}" +-"Module rlm_exec.shell_escape = %{config:modules.exec.shell_escape}" +----- +- +-.Output +- +-``` +-Server installed in /opt/freeradius +-Module rlm_exec.shell_escape = yes +-``` +- +-`config` is built in to the server core. +- +- +- +-=== %{client:} +- +-Refers to a variable that was defined in the client section for the +-current client. See the sections `client { ... }` in `clients.conf`. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-"The client ipaddr is %{client:ipaddr}" +----- +- +-.Output +- +-``` +-The client ipaddr is 192.168.5.9 +-``` +- +-`client` is built in to the server core. +- +- +- +-=== %{debug:} +- +-Dynamically change the debug level to something high, recording the old level. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-authorize { +- if (&request:User-Name == "bob") { +- "%{debug:4}" +- } else { +- "%{debug:0}" +- } +- ... +-} +----- +- +-.Output (_extra informations only for that condition_) +- +-``` +-... +-(0) authorize { +-(0) if (&request:User-Name == "bob") { +-(0) EXPAND %{debug:4} +-(0) --> 2 +-(0) } # if (&request:User-Name == "bob") (...) +-(0) filter_username { +-(0) if (&State) { +-(0) ... +-(0) } +-... +-``` +- +-`debug` is built in to the server core. +- +- +- +-=== %{debug_attr:} +- +-Print to debug output all instances of current attribute, or all attributes in a list. +-expands to a zero-length string. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-authorize { +- if (&request:User-Name == "bob") { +- "%{debug_attr:request[*]}" +- } +- ... +-} +----- +- +-.Output +- +-``` +-... +-(0) authorize { +-(0) if (&request:User-Name == "bob") { +-(0) Attributes matching "request[*]" +-(0) &request:User-Name = bob +-(0) &request:User-Password = hello +-(0) &request:NAS-IP-Address = 127.0.1.1 +-(0) &request:NAS-Port = 1 +-(0) &request:Message-Authenticator = 0x9210ee447a9f4c522f5300eb8fc15e14 +-(0) EXPAND %{debug_attr:request[*]} +-(0) } # if (&request:User-Name == "bob") (...) +-... +-``` +- +-`debug_attr` is built in to the server core. +- +- +- +-== String manipulation +- +-=== %{lpad:<&ref> } +- +-Left-pad a string. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "123" +-} +-update reply { +- &Reply-Message := "Maximum should be %{lpad:&control:Tmp-String-0 11 0}" +-} +----- +- +-.Output +- +-``` +-Maximum should be 00000000123 +-``` +- +-`lpad` is provided by the `rlm_expr` module. +- +- +- +-=== %{rpad:<&ref> } +- +-Right-pad a string. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "123" +-} +-update reply { +- &Reply-Message := "Maximum should be %{rpad:&control:Tmp-String-0 11 0}" +-} +----- +- +-.Output +- +-``` +-Maximum should be 12300000000 +-``` +- +-`rpad` is provided by the `rlm_expr` module. +- +- +- +-=== %{pairs:<&list:[*]>} +- +-Serialize attributes as comma-delimited string. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update { +- &control:Tmp-String-0 := "This is a string" +- &control:Tmp-String-0 += "This is another one" +-} +- +-update reply { +- &Reply-Message := "Serialize output: %{pairs:&control[*]}" +-} +----- +- +-.Output +- +-``` +-Serialize output: Tmp-String-0 = \"This is a string\"Tmp-String-0 = \"This is another one\" +-``` +- +-`pairs` is provided by the `rlm_expr` module. +- +- +- +-=== %{randstr: ...} +- +-Get random string built from character classes. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update reply { +- &Reply-Message := "The random string output is %{randstr:aaaaaaaa}" +-} +----- +- +-.Output +- +-``` +-The random string output is 4Uq0gPyG +-``` +- +-`randstr` is provided by the `rlm_expr` module. +- +- +- +-=== %{strlen: ... } +- +-Length of given string. +- +-.Return: _integer_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "Caipirinha" +-} +-update reply { +- &Reply-Message := "The length of %{control:Tmp-String-0} is %{strlen:&control:Tmp-String-0}" +-} +----- +- +-.Output +- +-``` +-The length of Caipirinha is 21 +-``` +- +-`strlen` is built in to the server core. +- +- +- +-=== %{tolower: ... } +- +-Dynamically expands the string and returns the lowercase version of +-it. This definition is only available in version 2.1.10 and later. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "CAIPIRINHA" +-} +-update reply { +- &Reply-Message := "tolower of %{control:Tmp-String-0} is %{tolower:%{control:Tmp-String-0}}" +-} +----- +- +-.Output +- +-``` +-tolower of CAIPIRINHA is caipirinha +-``` +- +-`tolower` is provided by the `rlm_expr` module. +- +- +- +-=== %{toupper: ... } +- +-Dynamically expands the string and returns the uppercase version of +-it. This definition is only available in version 2.1.10 and later. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "caipirinha" +-} +-update reply { +- &Reply-Message := "toupper of %{control:Tmp-String-0} is %{toupper:%{control:Tmp-String-0}}" +-} +----- +- +-.Output +- +-``` +-toupper of caipirinha is CAIPIRINHA +-``` +- +-`toupper` is provided by the `rlm_expr` module. +- +- +- +-== String Conversion +- +-=== %{base64: ... } +- +-Encode a string using Base64. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "Caipirinha" +-} +-update reply { +- &Reply-Message := "The base64 of %{control:Tmp-String-0} is %{base64:%{control:Tmp-String-0}}" +-} +----- +- +-.Output +- +-``` +-The base64 of foo is Q2FpcGlyaW5oYQ== +-``` +- +-`base64` is provided by the `rlm_expr` module. +- +- +- +-=== %{base64tohex: ... } +- +-Decode a base64 string (e.g. previously encoded using `base64`) to +-hex. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "Q2FpcGlyaW5oYQ==" +-} +-update reply { +- &Reply-Message := "The base64tohex of %{control:Tmp-String-0} is %{base64tohex:%{control:Tmp-String-0}}" +-} +----- +- +-.Output +- +-``` +-The base64decode of Q2FpcGlyaW5oYQ== is 436169706972696e6861 +-``` +- +-`base64tohex` is provided by the `rlm_expr` module. +- +- +- +-=== %{hex: ... } +- +-Convert to hex. +- +-.Return: _string_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "12345" +-} +-update reply { +- &Reply-Message := "The value of %{control:Tmp-String-0} in hex is %{hex:%{control:Tmp-String-0}}" +-} +----- +- +-.Output +- +-``` +-The value of 12345 in hex is 3132333435 +-``` +- +-`hex` is built in to the server core. +- +- +- +-=== %{urlquote: ... } +- +-Quote URL special characters. +- +-.Return: _string_. +- +-.Example +- +-[source,unlang] +----- +-update { +- &control:Tmp-String-0 := "http://example.org/" +-} +-update reply { +- &Reply-Message += "The urlquote of %{control:Tmp-String-0} is %{urlquote:%{control:Tmp-String-0}}" +-} +----- +- +-.Output +- +-``` +-The urlquote of http://example.org/ is http%3A%2F%2Fexample.org%2F +-``` +- +-`urlquote` is provided by the `rlm_expr` module. +- +- +- +-=== %{urlunquote: ... } +- +-Unquote URL special characters. +- +-.Return: _string_. +- +-.Example +- +-[source,unlang] +----- +-update { +- &control:Tmp-String-0 := "http%%3A%%2F%%2Fexample.org%%2F" # Attention for the double %. +-} +-update reply { +- &Reply-Message += "The urlunquote of %{control:Tmp-String-0} is %{urlunquote:%{control:Tmp-String-0}}" +-} +----- +- +-.Output +- +-``` +-The urlunquote of http%3A%2F%2Fexample.org%2F is http://example.org/ +-``` +- +-`urlunquote` is provided by the `rlm_expr` module. +- +- +- +-== Hashing and Encryption +- +-=== %{hmacmd5: } +- +-Generate `HMAC-MD5` of string. +- +-.Return: _octal_ +- +-.Example +- +-[source,unlang] +----- +-update { +- &control:Tmp-String-0 := "mykey" +- &control:Tmp-String-1 := "Caipirinha" +-} +-update { +- &control:Tmp-Octets-0 := "%{hmacmd5:%{control:Tmp-String-0} %{control:Tmp-String-1}}" +-} +- +-update reply { +- &Reply-Message := "The HMAC-MD5 of %{control:Tmp-String-1} in octets is %{control:Tmp-Octets-0}" +- &Reply-Message += "The HMAC-MD5 of %{control:Tmp-String-1} in hex is %{hex:control:Tmp-Octets-0}" +-} +----- +- +-.Output +- +-``` +-The HMAC-MD5 of Caipirinha in octets is \317}\264@K\216\371\035\304\367\202,c\376\341\203 +-The HMAC-MD5 of Caipirinha in hex is 636f6e74726f6c3a546d702d4f63746574732d30 +-``` +- +-`hmacmd5` is provided by the `rlm_expr` module. +- +- +- +-=== %{hmacsha1: } +- +-Generate `HMAC-SHA1` of string. +- +-.Return: _octal_ +- +-.Example +- +-[source,unlang] +----- +-update { +- &control:Tmp-String-0 := "mykey" +- &control:Tmp-String-1 := "Caipirinha" +-} +-update { +- &control:Tmp-Octets-0 := "%{hmacsha1:%{control:Tmp-String-0} %{control:Tmp-String-1}}" +-} +- +-update reply { +- &Reply-Message := "The HMAC-SHA1 of %{control:Tmp-String-1} in octets is %{control:Tmp-Octets-0}" +- &Reply-Message += "The HMAC-SHA1 of %{control:Tmp-String-1} in hex is %{hex:control:Tmp-Octets-0}" +-} +----- +- +-.Output +- +-``` +-The HMAC-SHA1 of Caipirinha in octets is \311\007\212\234j\355\207\035\225\256\372ʙ>R\"\341\351O) +-The HMAC-SHA1 of Caipirinha in hex is 636f6e74726f6c3a546d702d4f63746574732d30 +-``` +- +-`hmacsha1` is provided by the `rlm_expr` module. +- +- +- +-=== %{md5: ... } +- +-Dynamically expands the string and performs an MD5 hash on it. The +-result is binary data. +- +-.Return: _binary data_ +- +-.Example +- +-[source,unlang] +----- +-update control { +- &Tmp-String-0 := "Caipirinha" +-} +-update reply { +- &Reply-Message := "md5 of %{control:Tmp-String-0} is octal=%{md5:%{control:Tmp-String-0}}" +- &Reply-Message := "md5 of %{control:Tmp-String-0} is hex=%{hex:%{md5:%{control:Tmp-String-0}}}" +-} +----- +- +-.Output +- +-``` +-md5 of Caipirinha is octal=\024\204\013md||\230\243\3472\3703\330n\251 +-md5 of Caipirinha is hex=14840b6d647c7c98a3e732f833d86ea9 +-``` +- +-`md5` is provided by the `rlm_expr` module. +- +- +- +-== Miscellaneous Expansions +- +-=== +%{0}+..+%{32}+ +- +-`%{0}` expands to the portion of the subject that matched the last regular +-expression evaluated. `%{1}`..`%{32}` expand to the contents of any capture +-groups in the pattern. +- +-Every time a regular expression is evaluated, whether it matches or not, +-the numbered capture group values will be cleared. +- +- +- +-=== +%{regex:}+ +- +-Return named subcapture value from the last regular expression evaluated. +- +-Results of named capture groups are available using the `%{regex:}` expansion. They will also be accessible using the numbered expansions +-described xref:builtin.adoc#_0_32[above]. +- +-Every time a regular expression is evaluated, whether it matches or not, +-the named capture group values will be cleared. +- +-[NOTE] +-==== +-This expansion is only available if the server is built with libpcre or libpcre2. +-Use the output of `radiusd -Xxv` to determine which regular expression library in use. +- +-.... +-... +-Debug : regex-pcre : no +-Debug : regex-pcre2 : yes +-Debug : regex-posix : no +-Debug : regex-posix-extended : no +-Debug : regex-binsafe : yes +-... +-Debug : pcre2 : 10.33 (2019-04-16) - retrieved at build time +-.... +-==== +- +-`regex` is built in to the server core. +- +- +- +-=== +%{nexttime: