From c91ab185fbc88952b6a35c2dc5634bda4c4f0f2f Mon Sep 17 00:00:00 2001 From: Antonio Torres Date: Tue, 2 Sep 2025 10:44:48 +0200 Subject: [PATCH] Rebase to upstream 3.2.8 Resolves: RHEL-107671 Signed-off-by: Antonio Torres --- .gitignore | 1 + ...nfiguration-to-fit-Red-Hat-specifics.patch | 8 +- freeradius-disable-perl-script.patch | 4 +- freeradius-no-antora-docs.patch | 9267 ----------------- freeradius-no-buildtime-cert-gen.patch | 8 +- freeradius.spec | 18 +- sources | 2 +- 7 files changed, 26 insertions(+), 9282 deletions(-) delete mode 100644 freeradius-no-antora-docs.patch diff --git a/.gitignore b/.gitignore index 86328e1..b6aeba3 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ freeradius-*.src.rpm /freeradius-server-3.2.2.tar.bz2 /freeradius-server-3.2.3.tar.bz2 /freeradius-server-3.2.5.tar.bz2 +/freeradius-server-3.2.8.tar.bz2 diff --git a/freeradius-Adjust-configuration-to-fit-Red-Hat-specifics.patch b/freeradius-Adjust-configuration-to-fit-Red-Hat-specifics.patch index 6b2329b..a5da9e3 100644 --- a/freeradius-Adjust-configuration-to-fit-Red-Hat-specifics.patch +++ b/freeradius-Adjust-configuration-to-fit-Red-Hat-specifics.patch @@ -9,12 +9,12 @@ Subject: [PATCH] Adjust configuration to fit Red Hat specifics 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/raddb/mods-available/eap b/raddb/mods-available/eap -index 2621e183c..94494b2c6 100644 +index 97c7435a7c..26daec88d0 100644 --- a/raddb/mods-available/eap +++ b/raddb/mods-available/eap -@@ -533,7 +533,7 @@ - # You should also delete all of the files - # in the directory when the server starts. +@@ -696,7 +696,7 @@ eap { + # and create the temporary directory with the + # systemd `RuntimeDirectory` unit option. # - # tmpdir = /tmp/radiusd + # tmpdir = /var/run/radiusd/tmp diff --git a/freeradius-disable-perl-script.patch b/freeradius-disable-perl-script.patch index 58f4705..db02ed9 100644 --- a/freeradius-disable-perl-script.patch +++ b/freeradius-disable-perl-script.patch @@ -12,11 +12,11 @@ Signed-off-by: Antonio Torres 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/all.mk b/src/main/all.mk -index f3db386a2a..2517cd215a 100644 +index 0251b85800..06c57cf64c 100644 --- a/src/main/all.mk +++ b/src/main/all.mk @@ -1,3 +1,3 @@ SUBMAKEFILES := radclient.mk radiusd.mk radsniff.mk radmin.mk radattr.mk \ - radwho.mk radlast.mk radtest.mk radzap.mk checkrad.mk radsecret.mk \ + radwho.mk radlast.mk radtest.mk radzap.mk checkrad.mk \ - libfreeradius-server.mk unittest.mk + libfreeradius-server.mk unittest.mk fuzzer.mk diff --git a/freeradius-no-antora-docs.patch b/freeradius-no-antora-docs.patch deleted file mode 100644 index 5ac1ab0..0000000 --- a/freeradius-no-antora-docs.patch +++ /dev/null @@ -1,9267 +0,0 @@ -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. - -Generated by removing doc/antora directory in FreeRADIUS repo, and requesting the diff: -git diff --patch --stat - -Binary files such as *.png might need to be removed manually from patch. - -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/concepts/nav.adoc | 6 - - doc/antora/modules/concepts/pages/aaa.adoc | 60 -- - doc/antora/modules/concepts/pages/index.adoc | 8 - - .../pages/modules/ldap/authentication.adoc | 203 ----- - doc/antora/modules/developers/nav.adoc | 7 - - doc/antora/modules/developers/pages/bugs.adoc | 194 ----- - .../modules/developers/pages/coding-methods.adoc | 235 ------ - .../modules/developers/pages/contributing.adoc | 126 --- - doc/antora/modules/developers/pages/coverage.adoc | 11 - - doc/antora/modules/developers/pages/index.adoc | 18 - - doc/antora/modules/developers/pages/profile.adoc | 41 - - .../modules/developers/pages/release-method.adoc | 55 -- - doc/antora/modules/howto/nav.adoc | 22 - - doc/antora/modules/howto/pages/index.adoc | 17 - - .../modules/howto/pages/monitoring/index.adoc | 67 -- - .../modules/howto/pages/monitoring/statistics.adoc | 336 -------- - .../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 --- - .../modules/howto/pages/simultaneous_use.adoc | 78 -- - doc/antora/modules/installation/nav.adoc | 5 - - .../modules/installation/pages/dependencies.adoc | 35 - - 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 - - 98 files changed, 8578 deletions(-) - -diff --git a/doc/antora/antora.yml b/doc/antora/antora.yml -deleted file mode 100644 -index 263945a943..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.5' --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/concepts/nav.adoc b/doc/antora/modules/concepts/nav.adoc -deleted file mode 100644 -index 493b956641..0000000000 ---- a/doc/antora/modules/concepts/nav.adoc -+++ /dev/null -@@ -1,6 +0,0 @@ --* xref:index.adoc[Concepts] --** General --*** xref:aaa.adoc[AAA] --** Modules --*** LDAP --**** xref:modules/ldap/authentication.adoc[Authentication] -diff --git a/doc/antora/modules/concepts/pages/aaa.adoc b/doc/antora/modules/concepts/pages/aaa.adoc -deleted file mode 100644 -index 294305cb5b..0000000000 ---- a/doc/antora/modules/concepts/pages/aaa.adoc -+++ /dev/null -@@ -1,60 +0,0 @@ --= AAA -- --== Authorization, Authentication, and Accounting request handling -- --There are a lot of questions about misconfigured FreeRADIUS servers --because of misunderstanding of FreeRADIUS operations. This document --explains how the server operates. -- --Normally there are two steps in processing an authentication request --coming from a NAS in FreeRADIUS: authorization and authentication. --If we use FreeRADIUS as a proxy to re-send the request to another --RADIUS server there will be additional steps. -- --=== Authorization -- --Authorization is the process of finding and returning information --about what the user is allowed to do. For example, finding out what --kind of authentication methods they are allowed to run, and what VLAN --the user should be placed into. -- --Authorization modules generally "get data" from somewhere, --e.g. `ldap`, `sql`, `files`, etc. -- --The authentication method is usually determined when the server gets --the users credentials from a database. Once the credentials are --available, the server can authenticate the user. -- --=== Authentication -- --Authentication is simply a process of comparing user’s credentials in --request with the "known good" credentials retrieved from a --database. Authentication usually deals with password --encryption. The modules `pap`, `chap`, `mschap`, etc. do authentication. -- --Some modules do both authentication and limited authorization. For --example, the `mschap` module authenticates MS-CHAP credentials, but it --may also be used as an authorization module, which verifies that --request contains `MS-CHAP` related attribute. If so, the module --instructs the server to use `mschap` for authentication, too -- --These dual modules are usually related to protocol-specific --attributes, such as the `pap` module for the `User-Password` --attribute, `chap` for `CHAP-Password`, `mschap` for `MS-CHAP-*`, etc. -- --=== Request Processing -- --When the server processes requests, it manages four --xref:unlang:list.adoc[attribute lists]: -- --`request`:: attributes taken from the received packet -- --`reply`:: attributes which will be sent in the reply -- --`control`:: attributes used to control how the server operates. These are never sent in a packet -- --`session-state`:: attributes which are saved and restroed across multiple request / reply exchanges. -- --All of these lists are available to all modules. All of these --lists are available in xref:unlang:index.adoc[Unlang]. -- -diff --git a/doc/antora/modules/concepts/pages/index.adoc b/doc/antora/modules/concepts/pages/index.adoc -deleted file mode 100644 -index f2bc25f36f..0000000000 ---- a/doc/antora/modules/concepts/pages/index.adoc -+++ /dev/null -@@ -1,8 +0,0 @@ --= Concepts -- --This section documents concerning the protocols and modules used by the --FreeRADIUS server. -- --It intended to provide more theoretical information about particular subjects --than would be appropriate to include inline in module configurations or as --sidebars in howto guides. -diff --git a/doc/antora/modules/concepts/pages/modules/ldap/authentication.adoc b/doc/antora/modules/concepts/pages/modules/ldap/authentication.adoc -deleted file mode 100644 -index edc553e80a..0000000000 ---- a/doc/antora/modules/concepts/pages/modules/ldap/authentication.adoc -+++ /dev/null -@@ -1,203 +0,0 @@ --== Authenticating Users with LDAP -- --Please be aware the FreeRADIUS is an AAA server, and LDAP --is a _database_. This separation of roles means that FreeRADIUS --supports multiple kinds of authentication protocols such as `PAP`, --`CHAP`, `MS-CHAP`, etc. An LDAP database supports only one --authentication method: "bind as user". This authentication method is --compatible only with PAP. -- --Our recommendation is to use LDAP as a database. FreeRADIUS should --read the "known good" password from LDAP, and then use that --information to authenticate the user. It is almost always wrong to --use the LDAP "bind as user" method for authenticating users. -- --The only caveat to the above recommendation is Active Directory. For --"security" reasons, Active Directory will not return the "known good" --password to FreeRADIUS over a standard LDAP query. Therefore when --Active Directory is used, the choices are: -- --PAP:: --Use "bind as user" -- --MS-CHAP:: --Use xref:raddb:mods-available/ntlm_auth.adoc[`ntlm`] or xref:raddb:mods-available/winbind.adoc[`winbind`]. -- --Due to the limitations of Active Directory, There are unfortunately no --other possible choices. -- --== LDAP Security Recommendations -- --The credentials (username *and* password) for FreeRADIUS to use to --connect to your LDAP server(s) should be secure. We make the --following recommendations for LDAP "best practices" security. -- --* Create a dedicated account for use by FreeRADIUS -- --* Ensure that this account does not have administrator access -- --* Ensure that this account is read-only, and has no write permissions -- --* Start by using 'simple authentication' instead of -- https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer[SASL]. -- The SASL protocol should be attempted only after 'simple -- authentication' has been verified to work. -- --* Use TLS for connecting between FreeRADIUS and the LDAP server. See -- the `tls` sub-section of the default `ldap` module for instructions -- --* When storing RADIUS user profiles (quotas, `Simultaneous-Use` flags, -- access time restrictions, etc) in LDAP, the LDAP schema -- `doc/schemas/ldap/openldap/freeradius-radius.schema` must first be imported -- into the LDAP server. -- --== Authentication method compatibility -- --The LDAP module is compatible a few different kinds of authentication --methods. Note that we say _compatible_, and not _supports_. LDAP --servers are databases, and do not support authentication protocols --such as CHAP, MS-CHAP, or EAP. -- --PAP:: --The user supplies a `User-Password` (plaintext or EAP-TTLS/PAP) --+ --FreeRADIUS reads the "known good" password from LDAP, and compares --that to what the user entered. -- --Bind as user:: --The user supplies a `User-Password` (plaintext or EAP-TTLS/PAP) --+ --FreeRADIUS uses that password to "bind as the user" to LDAP, using the --supplied `User-Name` and `User-Password. If the bind is successfull, --the user is authenticated. Otherwise, authentication fails. -- --CHAP:: --The user supplies a `CHAP` password attribute. --+ --FreeRADIUS reads the "known good" password from LDAP in cleartext, and --compares that to what the user entered. -- --MS-CHAP:: --The user supplies a `MS-CHAP` password attribute. Either as --MS-CHAPv2, or as PEAP/MSCHAPv2, or as EAP-TTLS/MS-CHAPv2. --+ --FreeRADIUS reads the "known good" password from LDAP in cleartext, or --as an NT hash, and compares that to what the user entered. -- --All of above authentication methods other than "bind as user" require --that FreeRADIUS obtain the `userPassword` field from LDAP. If that --field is not returned to FreeRADIUS, then normal authentication is --impossible. Either FreeRADIUS has to be configured to use "bind as --user" for authentication, or the LDAP database has to be updated to --return the `userPassword` field to FreeRADIUS. This change usually --involves giving the FreeRADIUS "read-only" user permission to read the --`userPassword` field. -- --Again, the best method is to test authentication is with the --xref:howto:modules/ldap/ldapsearch/index.adoc[ldapsearch] tool. --These tests *must* be run prior to configuring FreeRADIUS. We strongly --recommend having the LDAP database return the `userPassword` field to --FreeRADIUS, so that FreeRADIUS can authenticate the user. -- --We also strongly recommend that the passwords be stored in LDAP as --cleartext. Otherwise, the only authentication methods that will work --are PAP and EAP-TTLS/PAP. The next section explains these issues in --more detail. -- --== Password Storage Methods -- --If the `userPassword` field is returned from LDAP to FreeRADIUS, that --information can be stored in a number of different formats: -- --* the value can be cleartext --* the value can be prepended with a string enclosed by braces, such as with `{crypt}` or `{ssha3}`. --* the value can be have a suffix of `::`, in which case the password is generally a https://en.wikipedia.org/wiki/Base64[base64] encoded version of the real password -- --TIP: Base64 values can be decoded via the command: `printf "%s" --"VALUE" | base64 -d` -- --FreeRADIUS is capable of understanding and parsing all of the above --formats. There is sufficient information in the password values to --determine what format it is in (base64, binary, or text), and what --password "encryption" mechanism has been used (crypt, MD5, SHA, SSHA2, --SHA3, etc). All that is necessary is that the --xref:raddb:mods-available/ldap.adoc[ldap module] be configured to map --the `userPassword` LDAP field to the `&control.Password.With-Header` --attribute in FreeRADIUS. FreeRADIUS will then "do the right thing" to --authenticate the user. -- --This mapping is done in the default module configuration. There are --no additional changes required for FreeRADIUS to correctly read and --decode the `userPassword` field from LDAP. Please see the --xref:raddb:mods-available/pap.adoc[pap module] for a full list of --supported password "encryption" formats. -- --== Additional Considerations -- --There are some major caveats with the above authentication methods. --The first is that we *strongly recommend* against using "bind as --user". This process is slow, and causes unnecessary churn in the --connections used to contact the LDAP server. Further, the "bind as --user" process works _only_ when a `User-Password attribute exists in --the request. If any other authentication type is used in the request, --then the "bind as user" _will not work_. There is no amount of --"fixing" things or configuration changes which will make it work. -- --The second caveat is that the `CHAP` authentication type works _only_ --when a "clear text" password is stored in the LDAP database. The --`CHAP` calclulations are designed around having access to the "clear --text" password. It is impossible to use any "encrypted" or "hashed" --passwords with `CHAP`. -- --The third caveat is that the `MS-CHAP` authentication type works --_only_ when a "clear text" password or "NT hashed" passwords which are --stored in the LDAP database. The `MS-CHAP` calculations are designed --around having access to "known good" passwords in those formats. It --is impossible to use any other kind of "encrypted" or "hashed" --passwords with `MS-CHAP`. -- --The final caveat is that when the LDAP database contains "encrypted" --or "hashed" passwords, the _only_ authentication type which is --compatible with those passwords is PAP. i.e. when the `User-Password` --is supplied to FreeRADIUS. -- --For recommendations on password storage methods in LDAP, please see --the LDAP --https://openldap.org/doc/admin24/security.html#Password%20Storage[password --storage] page. Please note that the recommendations there are made --for LDAP security, and pay no attention to the caveats described --above. When both RADIUS and LDAP are used together, then the --requirements of _both_ systems must be met in order for them to work --together. In many cases, a naive approach to LDAP security will --prevent RADIUS from working. -- --The issue of a database storing passwords in clear-text has to be --balanced against the users sending clear-text passwords in --authentication protocols. While those passwords are protected by TLS --(EAP-TTLS) or by RADIUS (in it's own "encryption" mechanism), it is --generally better to use a stronger authentication method than just --PAP. -- --In the end, there is no perfect solution to security requirements. --The choice may be either to give up on using a particular --authentication method, or to relax the security requirements on LDAP --and on password storage. The final decision as to which choice is --best can only be made by a local administrator. -- --== Integrating Novell eDirectory with FreeRADIUS -- --You can integrate Novell eDirectoryTM 8.7.1 or later with FreeRADIUS --1.0.2 onwards to allow wireless authentication for eDirectory users. By --integrating eDirectory with FreeRADIUS, you can do the following: -- --* Use universal password for RADIUS authentication. Universal password --provides single login and authentication for eDirectory users. --Therefore, the users need not have a separate password for RADIUS and --eDirectory authentication. --* Enforce eDirectory account policies for users. The existing eDirectory --policies on the user accounts can still be applied even after --integrating with RADIUS. Also, you can make use of the intruder lockout --facility of eDirectory by logging the failed logins into eDirectory. -- --For configuration information please refer to the Novell documentation --https://www.netiq.com/documentation/edir_radius/ -diff --git a/doc/antora/modules/developers/nav.adoc b/doc/antora/modules/developers/nav.adoc -deleted file mode 100644 -index ed6962a734..0000000000 ---- a/doc/antora/modules/developers/nav.adoc -+++ /dev/null -@@ -1,7 +0,0 @@ --* xref:index.adoc[Developers] --** xref:bugs.adoc[Bugs] --** xref:coding-methods.adoc[Coding Methods] --** xref:coverage.adoc[Code Coverage] --** xref:profile.adoc[Profiling] --** xref:contributing.adoc[Contributing] --** xref:release-method.adoc[Release Method] -diff --git a/doc/antora/modules/developers/pages/bugs.adoc b/doc/antora/modules/developers/pages/bugs.adoc -deleted file mode 100644 -index b63329c0bb..0000000000 ---- a/doc/antora/modules/developers/pages/bugs.adoc -+++ /dev/null -@@ -1,194 +0,0 @@ --= Bugs -- --== Introduction -- --The FreeRADIUS web site is at https://freeradius.org/, and most --information referenced in this document can be found there. -- --This document is primarily for non-developers of the FreeRADIUS --server. If you are able to patch the code to work correctly, then --we invite you to join the development list to discuss it. If --you’re the type who know little about how to code, then this is --the place for you! -- --== You found a bug -- --Where the server terminates ungracefully due to a bus error, --segmentation violation, or other memory error, you should create a new --issue in the issue tracker https://bugs.freeradius.org/, including --information from the debugging sections below. -- --For any other issues, you should first discuss them on the --https://freeradius.org/support/[FreeRADIUS users list], to --see if anyone can reproduce them. Often there’s a simple explanation of --why the server behaves as it does, and it’s not necessarily a bug in the --code, so browse the lists’ archives of the last two months, and if you --don’t see messages about it, ask! -- --If the behavior is correct but confusing, we think that’s a bug too, and --you should file a bug against our documentation. -- --For more information about the users list, the lists’ archives and the --faq, please visit https://www.freeradius.org/list/users.html Please make --sure to READ and RESPECT the house-rules. You will get much better --response and much faster if you do! -- --== Core dumps -- --If the server (or one of the accompanying programs) core dumps, then you --should rebuild the server as follows: -- --``` --$ ./configure --enable-developer --$ make --$ make install --``` -- --and then run the program again. You may have to to enable core dumps, --via: -- --``` --$ ulimit -c unlimited --``` -- --When it core dumps, do: -- --``` --$ gdb /path/to/executable /path/to/core/file --``` -- --Enable logging in `gdb` via the following commands: -- --``` --(gdb) set logging file gdb-radiusd.log --(gdb) set logging on --``` -- --and follow the instructions in the proceeding section. -- --You can also enable the `panic_action` given in --`raddb/radiusd.conf`. See the comments in that file for more details --about automatically collecting gdb debugging information when the server --crashes. -- --== Debugging a live server -- --If you can’t get a core dump, or the problem doesn’t result in a core --dump, you may have to run the server under gdb. To do this, ensure that --you have symbols in the binaries (i.e. a 'non-stripped' binary) by --re-building the server as described in the previous section. Then, run --the server under gdb as follows: -- --``` --$ gdb radiusd --``` -- --Enable logging in `gdb` via the following commands: -- --``` --(gdb) set logging file gdb-radiusd.log --(gdb) set logging on --``` -- --Tell `gdb` to pass any necessary command-line arguments to the server: -- --``` --(gdb) set args ... --``` -- --Where the ``…'' are the command-line arguments you normally pass to --radiusd. For debugging, you probably want to do: -- --``` --(gdb) set args -fxx --``` -- --Then, do: -- --``` --(gdb) run --``` -- --When something interesting happens, you can hit CTRL-C in the window, --and you should be back at the gdb prompt: -- --``` --(gdb) --``` -- --And follow the instructions in the next section. -- --== Obtaining useful information -- --Once you have a core dump loaded into gdb, or FreeRADIUS running under --gdb, you may use the commands below to get useful information about the --state of the server. -- --If the server was built with threads, you can do: -- --``` --(gdb) info threads --``` -- --Which will give you information about the threads. If the server isn’t --threaded, that command-line will print a message saying so. -- --Then, do: -- --``` --(gdb) thread apply all bt full --``` -- --If the server isn’t threaded, the `thread apply` section isn’t --necessary -- --The output should be printed to the screen, and also sent to the --`gdb-radiusd.log` file. -- --You should then submit the information from the log file, along with any --server output, the output of `radiusd -xv`, and information about your --operating system to: -- --https://bugs.freeradius.org/ -- --Submitting it to the bug database ensures that the bug report won’t get --forgotten, and that it will be dealt with in due course. -- --You should provide the issue number in any mail sent to the user’s list. -- --== Valgrind -- --On Linux systems, `valgrind` is a useful tool that can catch certain --classes of bugs. To use it, run the server via: -- --``` --$ valgrind --tool=memcheck --leak-check=full radiusd -Xm --``` -- --It will print out certain kinds of errors to the screen. There may be a --number of errors related to OpenSSL, dlopen(), or libtldl. We cannot do --anything about those problems. However, any errors that are inside of --the FreeRADIUS source should be brought to our attention. -- --== Running with `screen` -- --If the bug is a crash of the server, and it takes a long time for the --crash to happen, perform the following steps: -- --* Log in as root. --* Open a https://www.gnu.org/software/screen/[screen] session: `$ screen bash`. --* Make sure FreeRADIUS is not running. --* Make sure you have all the debug symbols about, or a debugable version --of the server installed (one built with `--enable-developer` as above). --* Configure screen to log to a file by pressing `Ctrl+a`, then `h`. --* Type `gdb /path/to/radiusd` (or /path/to/freeradius on Debian). --* At the `(gdb)` prompt, type `run -X`. --* Detach from screen with `Ctrl+a`, `d`. --* When you notice FreeRADIUS has died, reconnect to your screen session --`$ screen -D -r`. --* At the `(gdb)` prompt type `where` or for _lots_ of info try --`thread apply all bt full`. --* Tell screen to stop logging, `Ctrl+a`, `h`. --* Logout from screen. -- --FreeRADIUS Project, copyright 2019 -diff --git a/doc/antora/modules/developers/pages/coding-methods.adoc b/doc/antora/modules/developers/pages/coding-methods.adoc -deleted file mode 100644 -index 3de92c460e..0000000000 ---- a/doc/antora/modules/developers/pages/coding-methods.adoc -+++ /dev/null -@@ -1,235 +0,0 @@ --= Coding Methods -- --The following is a short set of guidelines to follow while programming. It does --not address coding styles, function naming methods, or debugging methods. --Rather, it describes the processes which should go on in the programmer’s mind --while they are programming. -- --Coding standards apply to function names, the look of the code, and coding --consistency. Coding methods apply to the daily practices used by the programmer --to write code. -- --== Comment your code -- --If you don’t, you’ll be forced to debug it six months later, when you have no clue --as to what it’s doing. -- --If someone _really_ hates you, you’ll be forced to debug un-commented code that --someone else wrote. You don’t want to do that. -- --For FreeRADIUS, use doxygen `@`-style comments so you get the --benefits of the developer documentation site, https://doc.freeradius.org/. -- --== Give things reasonable names -- --Variables and functions should have names. Calling them `x`, `xx`, --and `xxx` makes your life hell. Even `foo` and `i` are --problematic. -- --Avoid smurfs. Don’t re-use struct names in field names, i. e. -- --[source,c] ------ --struct smurf { -- char *smurf_pappa_smurf; --} ------ -- --If your code reads as full English sentences, you’re doing it right. -- --== Check input parameters in the functions you write -- --Your function _cannot_ do anything right if the user passed in garbage --and you were too lazy to check for garbage input. -- --`assert()` (`fr_assert()`) is ugly. Use it. -- --[NOTE] --==== --GIGO, "Garbage In, Garbage Out," is wrong. If your function gets --garbage input, it should complain loudly and with great --descriptiveness. --==== -- --== Write useful error messages -- --"Function failed" is useless as an error message. It makes debugging the code --impossible without source-level instrumentation. -- --If you’re going to instrument the code at source level for error messages, leave --the error messages there, so the next sucker won’t have to do the same work all --over again. -- --== Check error conditions from the functions you call -- --Your function _cannot_ do anything right if you called another function, and --they gave you garbage output. -- --One of the most common mistakes is: -- --[source,c] ------ --fp = fopen(...); --fgetc(fp); /* core dumps! */ ------ -- --If the programmer had bothered to check for a `NULL` fp (error --condition), then they could have produced a descriptive error message --instead of having the program core dump. -- --== Core dumps are for weenies -- --If your program core dumps accidentally, you’re a bad programmer. You don’t know --what your program is doing, or what it’s supposed to be doing when anything goes --wrong. -- --If it hits an `assert()` and calls `abort()`, you’re a genius. You’ve thought --ahead to what _might_ go wrong, and put in an assertion to ensure that it fails --in a _known manner_ when something _does_ go wrong. (As it usually does…) -- --== Initialize your variables -- --`memset()` (`talloc_zero()`) is your friend. `ptr = NULL` is nice, --too. -- --Having variables containing garbage values makes it easy for the code to do --garbage things. The contents of local variables are inputs to your function. See --xref:#_check_input_parameters_in_the_functions_you_write[#3]. -- --It’s also nearly impossible for you to debug any problems, as you can’t tell the --variables with garbage values from the real ones. -- --== Don’t allow buffer over-runs -- --They’re usually accidental, but they cause core dumps. `strcpy()` and `strcat()` --are ugly. Use them under duress. -- --`sizeof()` is your friend. -- --== `const` is your friend -- --If you don’t mean to modify an input structure to your function, declare it --`const`. Declare string constants `const`. It can’t hurt, and it allows more --errors to be found at compile time. -- --Use `const` everywhere. Once you throw a few into your code, and have it save --you from stupid bugs, you’ll blindly throw in `const` everywhere. It’s a --life-saver. -- --== Use C compiler warnings -- --Turn on all of the C compiler warnings possible. You might have to turn some off --due to broken system header files, though. But the more warnings the merrier. -- --Getting error messages at compile time is much preferable to getting core dumps --at run time. See xref:#_initialize_your_variables[#7]. -- --Notice that the C compiler error messages are helpful? You should write error --messages like this, too. See xref:#_write_useful_error_messages[#4]. -- --== Avoid UNIXisms and ASCIIisms and visualisms -- --You don’t know under what system someone will try to run your code. Don’t demand --that others use the same OS or character set as you use. -- --Never assign numbers to pointers. If foo is a `char*`, and you want it to be be --`NULL`, assign `NULL`, not `0`. The zeroth location is perfectly as addressable --as any other on plenty of OSes. Not all the world runs on Unix (though it should --:) ). -- --Another common mistake is to assume that the zeroth character in the character --set is the string terminator. Instead of terminating a string with `0`, use --`'\0'`, which is always right. Similarly, `memset()` with the appropriate value: --`NULL`, `'\0'`, or `0` for pointers, chars, and numbers. -- --Don’t put tabs in string constants, either. Always use `'\t'` to represent a --tab, instead of ASCII 9. Literal tabs are presented to readers of your code as --arbitrary whitespace, and it’s easy to mess up. -- --== Make conditionals explicit -- --Though it’s legal to test `if (foo) {}` if you test against the appropriate --value (like `NULL` or `'\0'`), your code is prettier and easier for others to --read without having to eyeball your prototypes continuously to figure out what --you’re doing (especially if your variables aren’t well-named). See --xref:#_give_things_reasonable_names[#2]. -- --== Test your code -- --Even Donald Knuth writes buggy code. You’ll never find all of the bugs in your --code. But writing a test program definitely helps. -- --This means that you’ll have to write your code so that it will be easily --testable. As a result, it will look better and be easier to debug. -- --== Hints, Tips, and Tricks -- --This section lists many of the common `rules` associated with code submitted to --the project. There are always exceptions… but you must have a really good reason --for doing so. -- --== Read the Documentation and follow the CodingStyle -- --The FreeRADIUS server has a common coding style. Use real tabs to indent. There --is whitespace in variable assignments (`i = 1`, not `i=1`). -- --When in doubt, format your code to look the same as code already in the server. --If your code deviates too much from the current style, it is likely to be --rejected without further review, and without comment. -- --== #ifdefs are ugly -- --Code cluttered with `#ifdef` s is difficult to read and maintain. Don’t do it. --Instead, put your `#ifdef` s in a header, and conditionally define `static --inline` functions, or macros, which are used in the code. Let the compiler --optimize away the 'no-op' case. -- --Simple example, of poor code: -- --[source,c] ------ --#ifdef CONFIG_MY_FUNKINESS -- init_my_stuff(foo); --#endif ------ -- --Cleaned-up example: -- --(in header): -- --[source,c] ------ --#ifndef CONFIG_MY_FUNKINESS -- static inline void init_my_stuff(char *foo) {} --#endif ------ -- --(in the code itself): -- --[source,c] ------ --init_my_stuff(dev); ------ -- --== `static inline` is better than a macro -- --Static inline functions are greatly preferred over macros. They provide type --safety, have no length limitations, no formatting limitations, and under gcc --they are as cheap as macros. -- --Macros should only be used for cases where a static inline is clearly suboptimal --(there a few, isolated cases of this in fast paths), or where it is impossible --to use a static inline function (such as string-izing). -- --`static inline` is preferred over `$$static __inline__$$`, `extern inline`, and --`$$extern __inline__$$`. -- --== Don’t over-design -- --Don’t try to anticipate nebulous future cases which may or may not be useful: --_Make it as simple as you can, and no simpler._ -- --Split up functionality as much as possible. If your code needs to do two --unrelated things, write two functions. Mashing two kinds of work into one --function makes the server difficult to debug and maintain. -- -diff --git a/doc/antora/modules/developers/pages/contributing.adoc b/doc/antora/modules/developers/pages/contributing.adoc -deleted file mode 100644 -index e4a4b0a1c5..0000000000 ---- a/doc/antora/modules/developers/pages/contributing.adoc -+++ /dev/null -@@ -1,126 +0,0 @@ --= Contributing -- --== Submitting patches or diff’s to the FreeRADIUS project -- --For a person or company wishing to submit a change to the FreeRADIUS --project the process can sometimes be daunting if you’re not familiar --with "the system." This text is a collection of suggestions which can --greatly increase the chances of your change being accepted. -- --Note: Only trivial patches will be accepted via email. Large patches, or --patches that modify a number of files MUST be submitted as a --https://github.com/FreeRADIUS/freeradius-server/pulls[pull-request via GitHub]. -- --== Hints and tips -- --=== 1. Describe your changes -- --Describe the technical detail of the change(s) your patch or commit --includes. -- --Be as specific as possible. The WORST descriptions possible include --things like "update file X", "bug fix for file X", or "this patch --includes updates for subsystem X. Please apply." -- --If your description starts to get long, that’s a sign that you probably --need to split up your commit. See the next point. -- --=== 2. Separate your changes -- --Separate each logical change into its own commit. -- --For example, if your changes include both bug fixes and performance --enhancements for a single module, separate those changes into two or --more patches. -- --On the other hand, if you make a single change to numerous files, group --those changes into a single commit. Thus a single LOGICAL change is --contained within a single commit. -- --If one commit depends on another commit in order for a change to be --complete, that is OK. Simply note "this commit depends on commit X" in --the extended commit description. -- --If your commit includes significant whitespace changes these should also --be broken out into another, separate, commit. -- --== Submitting patches via GitHub -- --See the following links for more details about submitting via github: -- --* https://help.github.com/articles/fork-a-repo --* http://wiki.freeradius.org/contributing/GitHub -- --== Submitting patches via email -- --=== 1. diff -u -- --Use `diff -u` or `diff -urN` to create patches. -- --All changes to the source occur in the form of patches, as generated by --diff(1). When creating your patch, make sure to create it in unified --diff format, as supplied by the `-u` argument to diff(1). Patches --should be based in the root source directory, not in any lower --subdirectory. -- --To create a patch for a single file, it is often sufficient to do:: -- --``` --SRCTREE=/home/user/src/freeradiusd/ --MYFILE=src/modules/rlm_foo/foo.c -- --cd $SRCTREE --cp $MYFILE $MYFILE.orig --vi $MYFILE # make your change --diff -u $MYFILE.orig $MYFILE > /tmp/patch --``` -- --To create a patch for multiple files, you should unpack a `vanilla`, --or unmodified source tree, and generate a diff against your own source --tree. For example: -- --``` --MYSRC=/home/user/src/freeradiusd-feature/ -- --gunzip freeradiusd-version.tar.gz --tar xvf freeradiusd-version.tar --diff -urN freeradiusd-version $MYSRC > ~/feature-version.patch --``` -- --=== 2. Select e-mail destination -- --If you are on the developers mailing list, send the patch there. --mailto:freeradius-devel@lists.freeradius.org[freeradius-devel@lists.freeradius.org] -- --Otherwise, send the patch to --mailto:patches@freeradius.org[patches@freeradius.org] -- --=== 3. No MIME, no links, no compression, no attachments. Just plain text -- --The developers need to be able to read and comment on the changes you --are submitting. It is important for a developer to be able to `quote` --your changes, using standard e-mail tools, so that they may comment on --specific portions of your code. -- --For this reason, all patches should be submitting e-mail `inline`. -- --Do not attach the patch as a MIME attachment, compressed or not. Many --popular e-mail applications will not always transmit a MIME attachment --as plain text, making it impossible to comment on your code. A MIME --attachment also takes a bit more time to process, decreasing the --likelihood of your MIME-attached change being accepted. -- --Compressed patches are generally rejected outright. If the developer has --to do additional work to read your patch, the odds are that it will be --ignored completely. -- --=== 4. E-mail size -- --Large changes are not appropriate for mailing lists, and some --maintainers. If your patch, exceeds 5Kb in size, you must submit the --patch via GitHub instead. -- --=== 5. Name the version of the server -- --It is important to note, either in the subject line or in the patch --description, the server version to which this patch applies. -diff --git a/doc/antora/modules/developers/pages/coverage.adoc b/doc/antora/modules/developers/pages/coverage.adoc -deleted file mode 100644 -index af6048e39e..0000000000 ---- a/doc/antora/modules/developers/pages/coverage.adoc -+++ /dev/null -@@ -1,11 +0,0 @@ --= Code Coverage -- --We use the link:https://gcc.gnu.org/onlinedocs/gcc/Gcov-Intro.html#Gcov-Intro[gcov] tool to know our tests coverage. -- --[source,shell] ------ --$ make clean --$ make coverage ------ -- --If completed with success, a pretty report will be available in `${source_tree}/build/coverage/index.html` -diff --git a/doc/antora/modules/developers/pages/index.adoc b/doc/antora/modules/developers/pages/index.adoc -deleted file mode 100644 -index e66ef61382..0000000000 ---- a/doc/antora/modules/developers/pages/index.adoc -+++ /dev/null -@@ -1,18 +0,0 @@ --= FreeRADIUS Development -- --List with some usual howtos for FreeRADIUS. -- --Programming reference documentation can be found at the --https://doc.freeradius.org/[Doxygen] site. -- --== Topics -- --* xref:bugs.adoc[Bugs] --* xref:coding-methods.adoc[Coding Methods] --* xref:coverage.adoc[Code Coverage] --* xref:profile.adoc[Profiling] --* xref:contributing.adoc[Contributing] --* xref:release-method.adoc[Release Method] -- --Also see the xref:installation:dependencies.adoc[build --dependencies] page. -diff --git a/doc/antora/modules/developers/pages/profile.adoc b/doc/antora/modules/developers/pages/profile.adoc -deleted file mode 100644 -index ca94f53a40..0000000000 ---- a/doc/antora/modules/developers/pages/profile.adoc -+++ /dev/null -@@ -1,41 +0,0 @@ --= Profiling -- --Build with gperftools, and ensure that it's built: -- --[source,shell] ------ --$ grep profile Make.inc --GPERFTOOLS_LIBS = -lprofiler ------ -- --Run your test using the profiling tools. One signal will start the --profiling, another will stop it. -- --[source,shell] ------ --env CPUPROFILE=/tmp/freeradius.prof CPUPROFILESIGNAL=12 freeradius ... --killall -12 freeradius -- ... wait ... --killall -12 freeradius ------ -- --View the results -- --[source,shell] ------ --pprof --text /path/to/freeradius /tmp/freeradius.prof ------ -- --or as a graph -- --[source,shell] ------ --pprof --gv /path/to/freeradius /tmp/freeradius.prof ------ -- --or as cachgrind output -- --[source,shell] ------ --pprof --cachegrind /path/to/freeradius /tmp/freeradius.prof ------ -diff --git a/doc/antora/modules/developers/pages/release-method.adoc b/doc/antora/modules/developers/pages/release-method.adoc -deleted file mode 100644 -index 1de9e2dc17..0000000000 ---- a/doc/antora/modules/developers/pages/release-method.adoc -+++ /dev/null -@@ -1,55 +0,0 @@ --= Release Method -- --== Topics -- --[arabic] --. As of 2.0, the release process is much simpler. Edit the Changelog --with the version number and any last updates. -- --``` --# vi doc/ChangeLog --# git commit doc/ChangeLog --``` -- --[arabic, start=2] --. Change version numbers in the VERSION file: -- --``` --# vi VERSION --# git commit VERSION --``` -- --[arabic, start=3] --. Make the files -- --NOTE: It also does `make dist-check`, which checks the build rules for --various packages. -- --``` --# make dist --``` -- --[arabic, start=4] --. Validate that the packages are OK. If so, tag the release. -- --NOTE: This does NOT actually do the tagging! You will have to run the --command it prints out yourself. -- --``` --# make dist-tag --``` -- --[arabic, start=5] --. Sign the packages. You will need the correct GPG key for this to work. -- --``` --# make dist-sign --``` -- --[arabic, start=6] --. Push to the FTP site. You will need write access to the FTP site for --this to work. -- --``` --# make dist-publish --``` -diff --git a/doc/antora/modules/howto/nav.adoc b/doc/antora/modules/howto/nav.adoc -deleted file mode 100644 -index dab23f80d6..0000000000 ---- a/doc/antora/modules/howto/nav.adoc -+++ /dev/null -@@ -1,22 +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] --** xref:monitoring/index.adoc[Monitoring] --*** xref:monitoring/statistics.adoc[Server statistics] --** xref:simultaneous_use.adoc[Simultaneous-Use] -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/monitoring/index.adoc b/doc/antora/modules/howto/pages/monitoring/index.adoc -deleted file mode 100644 -index a08ffb4194..0000000000 ---- a/doc/antora/modules/howto/pages/monitoring/index.adoc -+++ /dev/null -@@ -1,67 +0,0 @@ --= Monitoring -- --Any good systems administrator will want to know how well --their systems are operating, both to catch issues before they --become a serious problem, or for long term analysis. --The term "monitoring" can encompass all kinds of watching how the --system is working, from generating and watching logs, gathering --statistics or ensuring that the service daemon is still running --and serving requests. -- --We break the different types of monitoring down into the following --sections. -- --== Service checking -- --Checking the running service can include the following: -- --* Ensuring the daemon is still running, i.e. process monitoring --* Sending regular RADIUS authentication or accounting requests and checking they are correctly responded to --* Sending Status-Server RADIUS requests -- --Within a proxy environment FreeRADIUS needs to know if upstream --proxies are available. It can do this itself using the latter two --options above. -- --== Logging -- --System logs are often the most critical part of a RADIUS system. --They are necessary for the administrator to know who has logged in --and when, for debugging purposes such as when an end user cannot --connect, and often for regulatory or compliance purposes. -- --RADIUS server logs are also often used as a basic form of --recording accounting requests, which are in and of themselves a --form of logging by the NAS. Getting correct logging systems --operational is key to running an efficient and easy to maintain --RADIUS server. -- --FreeRADIUS has many options for being able to generate and store --logs, including the following: -- --* Main daemon logging, configured in `radiusd.conf` --* Line-based text logging, using `rlm_linelog` --* Detailed RADIUS packet logs, using `rlm_detail` -- --As well as recording direct to disk, the above can be sent via a --local syslog server, which opens up many opportunities for central --logging. -- --It is possible to integrate FreeRADIUS into other more complicated --logging systems, some options may include: -- --* To CSV files, for example via `rlm_linelog` --* Writing entries to an SQL database using `rlm_sql` --* Into a log management system such as Elasticsearch or Graylog -- -- --== Statistics gathering -- --It is often useful to collect statistics from a running RADIUS --server. These are often plotted on graphs to show current load or --for trend analysis, as well as an indication of system operation. -- --Statistics are usually gathered in two ways: -- --* FreeRADIUS xref:monitoring/statistics.adoc[internal statistics] --* Analysing logs with some external tool -diff --git a/doc/antora/modules/howto/pages/monitoring/statistics.adoc b/doc/antora/modules/howto/pages/monitoring/statistics.adoc -deleted file mode 100644 -index 0583f0adc0..0000000000 ---- a/doc/antora/modules/howto/pages/monitoring/statistics.adoc -+++ /dev/null -@@ -1,336 +0,0 @@ --= Server statistics -- --FreeRADIUS collects statistics internally about certain operations --it is doing, such as the number of authentication and accounting --requests, how many accepts and failures, and server queue lengths. --These can be queried by sending a specially-crafted RADIUS --`Status-Server` packet to a "status" virtual server. -- --== Configuring the status virtual server -- --The `status` virtual server is present in the default --configuration, but needs to be enabled before it can be used. To --do this, create a symlink from `sites-enabled/status` to --`../sites-available/status`: -- --[source,shell] ------ --# cd raddb/sites-enabled --# ln -s ../sites-available/status ------ -- --[NOTE] --==== --If you are not starting from the default configuration, check that --`status_server` is still set to `yes` in `raddb/radiusd.conf` as --well. --==== -- --While the default configuration will work for most setups, you may --edit the virtual server configuration in `sites-enabled/status`. --No major changes are necessary here, though the default secret, --`adminsecret`, should be changed. Other possible changes may be --the listening IP address and port, and the clients that are --allowed to connect. By default, connections are restricted to the --local host only. -- --Having enabled and configured the status server, restart --FreeRADIUS to make it active. -- --== Querying the server -- --To get the current statistics from the server, send a RADIUS --request of type `Status-Server` to the status port. Unless edited --above, the request must come from the same server that FreeRADIUS --is running on, and be sent to port 18121 with the secret --'adminsecret' . At a minimum, the `FreeRADIUS-Statistics-Type` --attribute must be set. For example: -- -- $ cat < FreeRADIUS-Statistics-Type = 0x01 -- > Message-Authenticator = 0x00 -- > EOF -- Sent Status-Server Id 145 from 0.0.0.0:b852 to 127.0.0.1:18121 length 62 -- FreeRADIUS-Statistics-Type = Authentication -- Message-Authenticator = 0x00 -- Received Access-Accept Id 145 from 127.0.0.1:46c9 to 127.0.0.1:47186 length 152 -- FreeRADIUS-Total-Access-Requests = 27 -- FreeRADIUS-Total-Access-Accepts = 20 -- FreeRADIUS-Total-Access-Rejects = 1 -- FreeRADIUS-Total-Access-Challenges = 0 -- FreeRADIUS-Total-Auth-Responses = 5 -- FreeRADIUS-Total-Auth-Duplicate-Requests = 0 -- FreeRADIUS-Total-Auth-Malformed-Requests = 0 -- FreeRADIUS-Total-Auth-Invalid-Requests = 0 -- FreeRADIUS-Total-Auth-Dropped-Requests = 0 -- FreeRADIUS-Total-Auth-Unknown-Types = 0 -- FreeRADIUS-Total-Auth-Conflicts = 0 -- --The `FreeRADIUS-Statistics-Type` attribute is a bitmask - add --together the following numbers to select the statistics required. --Some options are mutually exclusive, so it might be necessary to --send multiple requests to collect all information. -- --[%header,cols="2,1,1,5"] --|=== --|Name|Hex value|Decimal value|Description -- --|Authentication --|0x01 --|1 --|Stats about authentications -- --|Accounting --|0x02 --|2 --|Stats about accounting -- --|Proxy Auth --|0x04 --|4 --|Proxied authentication requests -- --|Proxy Accounting --|0x08 --|8 --|Proxied accounting requests -- --|Internal --|0x10 --|16 --|Queue lengths, thread information etc. -- --|Client --|0x20 --|32 --|Statistics about RADIUS clients e.g. defined in `clients.conf` -- --|Server --|0x40 --|64 --|Statistics about server 'listen' sockets e.g. in `sites-enabled/*` -- --|Home Server --|0x80 --|128 --|Statistics about a proxy home servers e.g. in `proxy.conf` --|=== -- --== Worked examples -- --To show the statistics available, a few examples follow. -- --=== Global server authentications -- --Using `FreeRADIUS-Statistics-Type = 0x01` requests stats about --authentications. Because, for example, no "Client" qualifier has --been added (`0x20`) the numbers are global to the server. -- --[source,shell] ------ --# cat <` 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 ca4d98fee5..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: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 a4ab3dbada..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/howto/pages/simultaneous_use.adoc b/doc/antora/modules/howto/pages/simultaneous_use.adoc -deleted file mode 100644 -index b4a97abb91..0000000000 ---- a/doc/antora/modules/howto/pages/simultaneous_use.adoc -+++ /dev/null -@@ -1,78 +0,0 @@ --= Simultaneous-Use checking -- --There are a whole lot of pieces which have to work together for --`Simultaneous-Use` to work. In this guide, we assume that user --sessions are stored in SQL. -- --For `Simultaneous-Use` to work. the server needs to know who is --online, which means that accounting must be configured and working. --Start off by checking the basics, independent of `Simultaneous-Use`. -- --As always, start off with reading the debug output, and use that --information to answer a few questions. -- --== Did the user get Access-Accept? -- --*No* - Fix that. Make sure that the user can be authenticated! -- --*Yes* - FreeRADIUS told the NAS to allow the user online. This usually -- works, but perhaps the NAS disagreed, and still dropped the user. It happens. -- --The only way you know that a user is actually online is to check the --accounting data. So we will do that next. -- --== Did the server then get an Accounting-Request for that user? -- --*No* - The NAS isn't sending accounting packets, Simultaneous-Use will never work. -- --Go fix the NAS so that it sends accounting packets. -- --*Yes* - The NAS is telling FreeRADIUS that it allowed the user online, -- and the user has an active session. We now have to see where that data is stored. -- --== Did the accounting data go into the radacct table? -- --As always, Read the debug output. -- --*No* - There is nothing in the debug output about radacct? Configure the server to write accounting data to SQL -- --ou can use `radclient` to send fake accounting packets for testing. --Use a real accounting packet as a template for input to `radclient`, --but change the `User-Name` so that the tests don't affect real users. -- -- --*Yes* - You see successful `INSERT` or `UPDATE` lines in `radacct`. That's good! -- --== One last check -- --Double-check the radacct database using an SQL client. Just to be sure that the data is really there. -- --== It is now set up correctly to track user sessions -- --If all that works, then the server is set up correctly to authenticate --users, and to store their data in SQL. This is the foundation for --`Simultaneous-Use`. -- --== Set Simultaneous-Use -- --Then, configure the server to set `Simultaneous-Use=1`. That tells the server to enforce `Simultaneous-Use`. That configuration can go into the `files` module, `sql`, or whereever else you want. -- --You will also need to configure the `default` virtual server to check session data in SQL. Look for `Simultaneous-Use` in `sites-available/default`. Uncomment the line containing `sql` -- --== Double check that a user can still log in! -- --Go through all of the above steps _again_, checking that the user can --log in, and that the server is receiving accounting packets. -- --This time, also look for the debug output to contain: -- --``` --# Executing section session from file ... --session { --``` -- --That shows it is checking the `session` database. If all goes well, the next few lines after that should show that it is checking `sql`. -- --If the above text doesn't appear, then the server isn't getting told to set `Simultaneous-Use = 1`. You will have to fix that before going to the next step. -- --If the user has not logged in yet, you will see an `Access-Accept`. Otherwise, if the user already has an active session, the server should say that the user is being rejected due to multiple logins. -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 3fb366796a..0000000000 ---- a/doc/antora/modules/installation/pages/dependencies.adoc -+++ /dev/null -@@ -1,35 +0,0 @@ --= FreeRADIUS Dependencies -- --Some external dependencies must be installed before building or --running FreeRADIUS. For version 3, the core depends on one --mandatory library: `libtalloc` for memory management. -- --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, CentOS, Rocky Linux or equivalent* -- --``` --# yum install libtalloc-devel --``` -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 e2d68b30e0..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_codes.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 2d5749dd8e..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/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 10a84c8485..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_codes.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 5b19af32f0..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_codes.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 30912ef40a..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/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 f26489b179..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: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: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: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 10d31482fc..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:#_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: