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://issues.redhat.com/browse/RHEL-31184 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: