58d6a6708a
Resolves: RHEL-46784 Signed-off-by: Antonio Torres <antorres@redhat.com>
9268 lines
308 KiB
Diff
9268 lines
308 KiB
Diff
From: Antonio Torres <antorres@redhat.com>
|
||
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 <antorres@redhat.com>
|
||
---
|
||
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 @@
|
||
-<?xml version="1.0" encoding="utf-8"?>
|
||
-<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||
- viewBox="0 0 160 160" style="enable-background:new 0 0 160 160;" xml:space="preserve">
|
||
-<style type="text/css">
|
||
- .st0{fill:none;stroke:#FFD62B;stroke-width:3;stroke-miterlimit:10;}
|
||
- .st1{fill:#B0C3C6;}
|
||
- .st2{fill:none;stroke:#DEE7E8;stroke-miterlimit:10;}
|
||
- .st3{fill:#00A6E2;}
|
||
- .st4{fill:none;stroke:#B0C3C6;stroke-width:2;stroke-miterlimit:10;}
|
||
- .st5{fill:#666666;}
|
||
- .st6{fill:none;stroke:#B0C3C6;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||
- .st7{fill:#00C9ED;}
|
||
- .st8{fill:#FFFFFF;stroke:#B0C3C6;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;}
|
||
- .st9{fill:#303030;}
|
||
- .st10{opacity:0.4;fill:#F6F6F6;}
|
||
- .st11{fill:none;stroke:#999999;stroke-width:2;stroke-miterlimit:10;}
|
||
- .st12{fill:#999999;}
|
||
- .st13{fill:#FFFFFF;}
|
||
- .st14{clip-path:url(#SVGID_2_);fill:#2F3537;}
|
||
- .st15{opacity:0.3;fill:none;stroke:#9FB1B3;stroke-width:2;stroke-miterlimit:10;}
|
||
- .st16{fill:none;stroke:#FFFFFF;stroke-miterlimit:10;}
|
||
- .st17{fill:#FFFFFF;stroke:#FFFFFF;stroke-miterlimit:10;}
|
||
- .st18{fill:none;stroke:#303030;stroke-miterlimit:10;}
|
||
- .st19{opacity:0.8;fill:#B0C3C6;}
|
||
- .st20{opacity:0.7;}
|
||
- .st21{opacity:0.8;clip-path:url(#SVGID_4_);fill:#00A6E2;}
|
||
- .st22{opacity:0.8;fill:#00A6E2;}
|
||
- .st23{opacity:0.8;clip-path:url(#SVGID_6_);fill:#00A6E2;}
|
||
- .st24{clip-path:url(#SVGID_8_);}
|
||
- .st25{clip-path:url(#SVGID_10_);}
|
||
- .st26{fill:none;stroke:#B0C3C6;stroke-width:3;stroke-linejoin:round;stroke-miterlimit:10;}
|
||
- .st27{opacity:0.3;fill:none;stroke:#9FB1B3;stroke-width:3;stroke-miterlimit:10;}
|
||
- .st28{fill:#FFFFFF;stroke:#B0C3C6;stroke-width:3;stroke-linejoin:round;stroke-miterlimit:10;}
|
||
- .st29{clip-path:url(#SVGID_12_);fill:#2F3537;}
|
||
- .st30{clip-path:url(#SVGID_14_);fill:#B0C3C6;}
|
||
- .st31{fill:#33B8E8;}
|
||
- .st32{fill:#238DB4;}
|
||
- .st33{fill:#E2E7E8;}
|
||
- .st34{clip-path:url(#SVGID_16_);}
|
||
- .st35{fill:#FFFFFF;stroke:#B0C3C6;stroke-width:2;stroke-miterlimit:10;}
|
||
- .st36{fill:#B4CBCE;}
|
||
- .st37{fill:#003147;}
|
||
- .st38{fill:#FFD62B;}
|
||
- .st39{fill:#00B78E;}
|
||
- .st40{fill:#FF7824;}
|
||
- .st41{fill:#FF3223;}
|
||
- .st42{fill:#7955DF;}
|
||
- .st43{fill:none;stroke:#FF3223;stroke-width:2;stroke-miterlimit:10;}
|
||
- .st44{fill:none;stroke:#00A6E2;stroke-width:2;stroke-miterlimit:10;}
|
||
- .st45{clip-path:url(#SVGID_18_);fill:#303030;}
|
||
- .st46{fill:#F5C81F;}
|
||
- .st47{fill:#F49F90;}
|
||
- .st48{fill:#F3EEDE;}
|
||
- .st49{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
|
||
- .st50{fill:#00131F;}
|
||
- .st51{clip-path:url(#SVGID_20_);fill:#303030;}
|
||
- .st52{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
|
||
- .st53{clip-path:url(#SVGID_22_);fill:#303030;}
|
||
- .st54{clip-path:url(#SVGID_24_);fill:#303030;}
|
||
-</style>
|
||
-<path class="st0" d="M72.3,25.6c0,0-2.3-3.2-6-2.3"/>
|
||
-<g>
|
||
- <polygon class="st50" points="79.2,73 20.3,37.9 86.2,19.3 145.1,54.4 "/>
|
||
- <g>
|
||
- <g>
|
||
- <g>
|
||
- <g>
|
||
- <path class="st3" d="M126.2,113.6c-4.4,0-8.2-3-9.3-7.1c2.8,1,5.7,1.6,8.8,1.6c4.4,0,7.9-3.5,7.9-7.9c0-4.4-3.5-7.9-7.9-7.9
|
||
- c-5.3,0-9.9-4.3-9.9-9.6c0-0.7,0-2.1,0-2.1v-6.1c0-19.4-15.7-35.2-35.2-35.2c-19.4,0-35.2,15.7-35.2,35.2v6.1c0,0,0,1.3,0,2.1
|
||
- c0,5.3-4.6,9.6-9.9,9.6c-4.4,0-7.9,3.5-7.9,7.9c0,4.4,3.5,7.9,7.9,7.9c3.5,0,6.8-0.7,9.8-2c-1,4.3-4.8,7.5-9.4,7.5
|
||
- c-4.4,0-7.9,3.5-7.9,7.9c0,4.4,3.5,7.9,7.9,7.9c6.9,0,13.2-2.8,17.8-7.3v10.4c0,4.4,3.5,7.9,7.9,7.9c4.4,0,7.9-3.5,7.9-7.9
|
||
- v-14.8h3.1v18.7c0,4.4,3.5,7.9,7.9,7.9c4.4,0,7.9-3.5,7.9-7.9v-18.7h3.1v14.8c0,4.4,3.5,7.9,7.9,7.9c4.4,0,7.9-3.5,7.9-7.9
|
||
- v-11.4c4.7,5.1,11.3,8.2,18.7,8.2c4.4,0,7.9-3.5,7.9-7.9C134.1,117.1,130.5,113.6,126.2,113.6z"/>
|
||
- <g>
|
||
- <circle class="st13" cx="80" cy="76.9" r="17.5"/>
|
||
- <g>
|
||
- <defs>
|
||
- <circle id="SVGID_19_" cx="80" cy="76.9" r="17.5"/>
|
||
- </defs>
|
||
- <use xlink:href="#SVGID_19_" style="overflow:visible;fill:#FFFFFF;"/>
|
||
- <clipPath id="SVGID_2_">
|
||
- <use xlink:href="#SVGID_19_" style="overflow:visible;"/>
|
||
- </clipPath>
|
||
- <path style="clip-path:url(#SVGID_2_);fill:#303030;" d="M73.3,85.5c-6.7,0-12.2-5.5-12.2-12.2c0-6.7,5.5-12.2,12.2-12.2
|
||
- s12.2,5.5,12.2,12.2C85.5,80,80.1,85.5,73.3,85.5z"/>
|
||
- </g>
|
||
- </g>
|
||
- </g>
|
||
- </g>
|
||
- </g>
|
||
- </g>
|
||
- <g>
|
||
- <path class="st50" d="M46,65.8c0-19.1,15.5-29.7,34.6-29.7s34.6,10.6,34.6,29.7c0,0-9.6-9.8-34.2-9.8S46,65.8,46,65.8z"/>
|
||
- </g>
|
||
- <g>
|
||
- <path class="st0" d="M66.3,23.3c0,0-10.7,2.8-10.2,9.7v20.8"/>
|
||
- <line class="st0" x1="56" y1="53.7" x2="59.3" y2="66"/>
|
||
- <line class="st0" x1="56" y1="53.7" x2="54" y2="64.7"/>
|
||
- <line class="st0" x1="56" y1="53.7" x2="62" y2="59.2"/>
|
||
- <line class="st0" x1="56" y1="53.7" x2="50.8" y2="60.4"/>
|
||
- </g>
|
||
-</g>
|
||
-</svg>
|
||
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 <<EOF | radclient -x localhost:18121 status adminsecret
|
||
- > 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 <<EOF | radclient -x localhost:18121 status adminsecret
|
||
-FreeRADIUS-Statistics-Type = 0x01
|
||
-Message-Authenticator=0x00
|
||
-EOF
|
||
-Sent Status-Server Id 90 from 0.0.0.0:e008 to 127.0.0.1:18121 length 50
|
||
- FreeRADIUS-Statistics-Type = Authentication
|
||
- Message-Authenticator = 0x00
|
||
-Received Access-Accept Id 90 from 127.0.0.1:46c9 to 127.0.0.1:57352 length 152
|
||
- FreeRADIUS-Total-Access-Requests = 133
|
||
- FreeRADIUS-Total-Access-Accepts = 114
|
||
- FreeRADIUS-Total-Access-Rejects = 13
|
||
- FreeRADIUS-Total-Access-Challenges = 0
|
||
- FreeRADIUS-Total-Auth-Responses = 127
|
||
- 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
|
||
-----
|
||
-
|
||
-=== Global server authentication and accounting requests
|
||
-
|
||
-Sending `0x01` requests authentication statistics, and `0x02`
|
||
-requests accounting stats. To get both in one result, add them
|
||
-together, so we requst `0x03`. In this example we send decimal
|
||
-rather than hexadecimal.
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-# cat <<EOF | radclient -x localhost:18121 status adminsecret
|
||
-FreeRADIUS-Statistics-Type = 3
|
||
-Message-Authenticator=0x00
|
||
-EOF
|
||
-Sent Status-Server Id 216 from 0.0.0.0:ce7b to 127.0.0.1:18121 length 50
|
||
- FreeRADIUS-Statistics-Type = Auth-Acct
|
||
- Message-Authenticator = 0x00
|
||
-Received Access-Accept Id 216 from 127.0.0.1:46c9 to 127.0.0.1:52859 length 248
|
||
- FreeRADIUS-Total-Access-Requests = 542
|
||
- FreeRADIUS-Total-Access-Accepts = 451
|
||
- FreeRADIUS-Total-Access-Rejects = 81
|
||
- FreeRADIUS-Total-Access-Challenges = 0
|
||
- FreeRADIUS-Total-Auth-Responses = 532
|
||
- 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
|
||
- FreeRADIUS-Total-Accounting-Requests = 0
|
||
- FreeRADIUS-Total-Accounting-Responses = 0
|
||
- FreeRADIUS-Total-Acct-Duplicate-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Malformed-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Invalid-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Dropped-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Unknown-Types = 0
|
||
- FreeRADIUS-Total-Acct-Conflicts = 0
|
||
-----
|
||
-
|
||
-=== Internal server stats
|
||
-
|
||
-The value `0x10` requests information about the server such as queue
|
||
-lengths and thread state.
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-# cat <<EOF | radclient -x localhost:18121 status adminsecret
|
||
-FreeRADIUS-Statistics-Type = 0x10
|
||
-Message-Authenticator=0x00
|
||
-EOF
|
||
-Sent Status-Server Id 158 from 0.0.0.0:a090 to 127.0.0.1:18121 length 50
|
||
- FreeRADIUS-Statistics-Type = Internal
|
||
- Message-Authenticator = 0x00
|
||
-Received Access-Accept Id 158 from 127.0.0.1:46c9 to 127.0.0.1:41104 length 164
|
||
- FreeRADIUS-Stats-Start-Time = "Aug 3 2023 13:36:24 UTC"
|
||
- FreeRADIUS-Stats-HUP-Time = "Aug 3 2023 13:36:24 UTC"
|
||
- FreeRADIUS-Queue-Len-Internal = 0
|
||
- FreeRADIUS-Queue-Len-Proxy = 0
|
||
- FreeRADIUS-Queue-Len-Auth = 0
|
||
- FreeRADIUS-Queue-Len-Acct = 0
|
||
- FreeRADIUS-Queue-Len-Detail = 0
|
||
- FreeRADIUS-Queue-PPS-In = 0
|
||
- FreeRADIUS-Queue-PPS-Out = 0
|
||
- FreeRADIUS-Stats-Threads-Active = 0
|
||
- FreeRADIUS-Stats-Threads-Total = 0
|
||
- FreeRADIUS-Stats-Threads-Max = 0
|
||
-----
|
||
-
|
||
-=== Complete global server information
|
||
-
|
||
-A useful common request is all information about the server on a
|
||
-global basis: internal stats (16 / `0x10`) plus authentications (1
|
||
-/ `0x01`), accounting (2 / `0x02`), proxy authentications (4 /
|
||
-`0x04`) and proxy accounting (8 / `0x08`). The value `All` is
|
||
-defined in the dictionary as `0x1f` (decimal 31) to cover
|
||
-this common eventuality, and is what we demonstrate here.
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-# cat <<EOF | radclient -x localhost:18121 status adminsecret
|
||
-FreeRADIUS-Statistics-Type = All
|
||
-Message-Authenticator=0x00
|
||
-EOF
|
||
-Sent Status-Server Id 4 from 0.0.0.0:9ee4 to 127.0.0.1:18121 length 50
|
||
- FreeRADIUS-Statistics-Type = All
|
||
- Message-Authenticator = 0x00
|
||
-Received Access-Accept Id 4 from 127.0.0.1:46c9 to 127.0.0.1:40676 length 596
|
||
- FreeRADIUS-Total-Access-Requests = 792
|
||
- FreeRADIUS-Total-Access-Accepts = 659
|
||
- FreeRADIUS-Total-Access-Rejects = 122
|
||
- FreeRADIUS-Total-Access-Challenges = 0
|
||
- FreeRADIUS-Total-Auth-Responses = 781
|
||
- 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
|
||
- FreeRADIUS-Total-Accounting-Requests = 0
|
||
- FreeRADIUS-Total-Accounting-Responses = 0
|
||
- FreeRADIUS-Total-Acct-Duplicate-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Malformed-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Invalid-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Dropped-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Unknown-Types = 0
|
||
- FreeRADIUS-Total-Acct-Conflicts = 0
|
||
- FreeRADIUS-Total-Proxy-Access-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Access-Accepts = 0
|
||
- FreeRADIUS-Total-Proxy-Access-Rejects = 0
|
||
- FreeRADIUS-Total-Proxy-Access-Challenges = 0
|
||
- FreeRADIUS-Total-Proxy-Auth-Responses = 0
|
||
- FreeRADIUS-Total-Proxy-Auth-Duplicate-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Auth-Malformed-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Auth-Invalid-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Auth-Dropped-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Auth-Unknown-Types = 0
|
||
- FreeRADIUS-Total-Proxy-Accounting-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Accounting-Responses = 0
|
||
- FreeRADIUS-Total-Proxy-Acct-Duplicate-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Acct-Malformed-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Acct-Invalid-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Acct-Dropped-Requests = 0
|
||
- FreeRADIUS-Total-Proxy-Acct-Unknown-Types = 0
|
||
- FreeRADIUS-Stats-Start-Time = "Aug 3 2023 13:36:24 UTC"
|
||
- FreeRADIUS-Stats-HUP-Time = "Aug 3 2023 13:36:24 UTC"
|
||
- FreeRADIUS-Queue-Len-Internal = 0
|
||
- FreeRADIUS-Queue-Len-Proxy = 0
|
||
- FreeRADIUS-Queue-Len-Auth = 0
|
||
- FreeRADIUS-Queue-Len-Acct = 0
|
||
- FreeRADIUS-Queue-Len-Detail = 0
|
||
- FreeRADIUS-Queue-PPS-In = 0
|
||
- FreeRADIUS-Queue-PPS-Out = 0
|
||
- FreeRADIUS-Stats-Threads-Active = 0
|
||
- FreeRADIUS-Stats-Threads-Total = 0
|
||
- FreeRADIUS-Stats-Threads-Max = 0
|
||
-----
|
||
-
|
||
-=== Client statistics
|
||
-
|
||
-Data can be provided about each RADIUS client defined in the
|
||
-server. Note that this is for the client definition, not for each
|
||
-client that connects - if a client definition has a wide netmask
|
||
-and permits multiple clients to connect, the statistics will be
|
||
-aggregate for all clients using that definition.
|
||
-
|
||
-[NOTE]
|
||
-====
|
||
-It is not possible to request global server statistics
|
||
-concurrently with client statistics as both use the same reply
|
||
-attributes.
|
||
-====
|
||
-
|
||
-Here we request accounting data for one particular client by IP
|
||
-address.
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-# cat <<EOF | radclient -x localhost:18121 status adminsecret
|
||
-FreeRADIUS-Statistics-Type = 0x2f
|
||
-FreeRADIUS-Stats-Client-IP-Address = 172.16.0.10
|
||
-Message-Authenticator=0x00
|
||
-EOF
|
||
-Sent Status-Server Id 194 from 0.0.0.0:d897 to 127.0.0.1:18121 length 62
|
||
- FreeRADIUS-Statistics-Type = 47
|
||
- FreeRADIUS-Stats-Client-IP-Address = 172.16.0.10
|
||
- Message-Authenticator = 0x00
|
||
-Received Access-Accept Id 194 from 127.0.0.1:46c9 to 127.0.0.1:55447 length 236
|
||
- FreeRADIUS-Stats-Client-IP-Address = 172.16.0.10
|
||
- FreeRADIUS-Total-Access-Requests = 1491
|
||
- FreeRADIUS-Total-Access-Accepts = 1240
|
||
- FreeRADIUS-Total-Access-Rejects = 246
|
||
- FreeRADIUS-Total-Access-Challenges = 0
|
||
- FreeRADIUS-Total-Auth-Responses = 1486
|
||
- 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-Accounting-Requests = 0
|
||
- FreeRADIUS-Total-Accounting-Responses = 0
|
||
- FreeRADIUS-Total-Acct-Duplicate-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Malformed-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Invalid-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Dropped-Requests = 0
|
||
- FreeRADIUS-Total-Acct-Unknown-Types = 0
|
||
-----
|
||
diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/enable.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/enable.adoc
|
||
deleted file mode 100644
|
||
index 2824bd0f48..0000000000
|
||
--- a/doc/antora/modules/howto/pages/protocols/dhcp/enable.adoc
|
||
+++ /dev/null
|
||
@@ -1,213 +0,0 @@
|
||
-== Enabling the DHCP service
|
||
-
|
||
-A major difference between configuring FreeRADIUS as a DHCP server versus most
|
||
-other DHCP software such as ISC DHCP is that other software typically uses a
|
||
-single monolithic configuration file whereas FreeRADIUS has a collection of
|
||
-configuration files. This reflects the modularity of FreeRADIUS; attempting to
|
||
-put the entire configuration in a single file would result in a very difficult
|
||
-to read configuration.
|
||
-
|
||
-The root of the FreeRADIUS configuration may be in a different location on the
|
||
-filesystem depending on how FreeRADIUS has been installed. This directory will
|
||
-be referred to as `<raddb>` 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 `<raddb>/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 `<conf>/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 <raddb>/sites-enabled
|
||
-ln -s ../sites-available/dhcp .
|
||
-----
|
||
-
|
||
-or:
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-cd <raddb>/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
|
||
-`<raddb>/mods-available`.
|
||
-These should be symlinked or copied into `<raddb>/mods-enabled` in order to
|
||
-enable them.
|
||
-
|
||
-
|
||
-==== Configure the `dhcp_sql` module
|
||
-
|
||
-Add the `dhcp_sql` module to the active configuration:
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-cd <raddb>/mods-enabled
|
||
-ln -s ../mods-available/dhcp_sql .
|
||
-----
|
||
-
|
||
-or:
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-cd <raddb>/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_<dialect>`, 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 <raddb>/mods-enabled
|
||
-ln -s ../mods-available/dhcp_sqlippool .
|
||
-----
|
||
-
|
||
-or
|
||
-
|
||
-[source,shell]
|
||
-----
|
||
-cd <raddb>/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 `<raddb>/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 `<interface>` for DHCP packets
|
||
-==================================================================
|
||
- # ss -lunp
|
||
- Netid Recv-Q Send-Q Local Address:Port ...
|
||
- udp 0 0 0.0.0.0%<interface>: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
|
||
-`<raddb>/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
|
||
-`<raddb>/mods-available/dhcp_passwd` into `<raddb>/mods-enabled/`. The
|
||
-suggested configuration expects the group membership file to be in
|
||
-`<raddb>/mods-config/files/dhcp_groups` and take the form of:
|
||
-
|
||
-[source,config]
|
||
-----
|
||
-<group1 name>|<hardware address>,<hardware address>,<hardware address>
|
||
-<group2 name>|<hardware address>,<hardware address>
|
||
-----
|
||
-
|
||
-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
|
||
-`<raddb>/policy.d/dhcp` in the `dhcp_group_options` policy and in
|
||
-`<raddb>/mods-available/dhcp_files` as the `dhcp_set_group_options` instance.
|
||
-
|
||
-The same data file `<raddb>/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 = <MAC-Address>, groupname = <group>, priority =
|
||
- <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 <<EOF > 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 `<raddb>/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 <pool_name> -s <range_start> -e <range_end> \
|
||
- -t <table_name> (-d <sql_dialect> | -f <raddb_dir> [ -i <instance> ]) \
|
||
- [ -c <capacity> ] [ -x <existing_ips_file> ]
|
||
-----
|
||
-
|
||
-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 <dhcpd.<raddb> -t <table_name> -k <mac|id> \
|
||
- (-d <sql_dialect> | -f <raddb_dir> [-i <instance>])
|
||
-----
|
||
-
|
||
-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
|
||
-`<raddb>/sites-enabled/dhcp`.
|
||
-====
|
||
-
|
||
-To use the provided example `files` module instance for DHCP, symlink or copy
|
||
-`<raddb>/mods-available/dhcp_files` into `<raddb>/mods-enabled/` and then
|
||
-uncomment the calls to `dhcp_network` in `<raddb>/sites-enabled/dhcp`.
|
||
-
|
||
-A template configuration file `<raddb>/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 `<Attribute>
|
||
-<op> <Value>`. In the case of the second block we match the
|
||
-`DHCP-Network-Subnet` to an enclosing subnet with
|
||
-`DHCP-Network-Subnet < <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 `<Attribute> := <Value>`. 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
|
||
-`<raddb>/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 <<EOF > 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 <<EOF > 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 <<EOF > 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 `<raddb>/mods-available/dhcp_files`:
|
||
-
|
||
-[source,config]
|
||
-----
|
||
-files dhcp_subnets {
|
||
- filename = ${modconfdir}/files/dhcp
|
||
- key = "subnet"
|
||
-}
|
||
-----
|
||
-
|
||
-Additionally, uncomment the `dhcp_subnets` policy in `<raddb>/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 `<raddb>/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
|
||
-`<raddb>/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 <<EOF > 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:
|
||
-
|
||
-<https://networkradius.com/packages/>
|
||
-
|
||
-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:
|
||
-
|
||
-<https://networkradius.com/packages/>
|
||
-
|
||
-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/<dialect>/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 `<instance>-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 (<ipaddr>"%{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[<integer>]
|
||
-----
|
||
-
|
||
-When an attribute appears multiple times in a list, this syntax allows
|
||
-you to address the attributes as if they were array entries. The
|
||
-`<integer>` 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 [ <match> ] {
|
||
- [ 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 `<match>` 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 `<match>` 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]
|
||
-----
|
||
-<cast>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]
|
||
-----
|
||
-<ipaddr>&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]
|
||
-----
|
||
-<integer>`/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]
|
||
-----
|
||
-(<subject> =~ /<pattern>/)
|
||
-(<subject> =~ /<pattern>/[imsux])
|
||
-
|
||
-(<subject> !~ /<pattern>/)
|
||
-(<subject> !~ /<pattern>/[imsux])
|
||
-----
|
||
-====
|
||
-
|
||
-== Matching
|
||
-The regular expression operators perform regular expression matching
|
||
-on the data. The `<subject>` field can be an attribute reference or data,
|
||
-as with the other xref:condition/cmp.adoc[comparison] operators. The `/<pattern>/`
|
||
-field must be a valid regular expression.
|
||
-
|
||
-The `=~` operator evaluates to `true` when `data` matches the
|
||
-`/<pattern>/`. Otherwise, it evaluates to `false`.
|
||
-
|
||
-The `!~` operator evaluates to `true` when `data` does not match the
|
||
-`/<pattern>/`. 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 `/<pattern>/` 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:<named capture group>}`.
|
||
-
|
||
-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 <a.cudbardb@freeradius.org>
|
||
-// 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 [ <match> ] {
|
||
- [ 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 `<match>` 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 `<match>` 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 <attribute-reference> {
|
||
- [ statements ]
|
||
-}
|
||
-----
|
||
-
|
||
-The `foreach` statement loops over a set of attributes as given by
|
||
-`<attribute-reference>`. The loop can be exited early by using the
|
||
-xref:break.adoc[break] keyword.
|
||
-
|
||
-<attribute-reference>::
|
||
-
|
||
-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[<module>] | Execute a named module, e.g., `sql`.
|
||
-| xref:module_method.adoc[<module>.<method>] | 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 _<list>_ 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]
|
||
-----
|
||
-<module>
|
||
-----
|
||
-
|
||
-The `<module>` 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 `<rcode> = (0+|<rcode>|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]
|
||
-----
|
||
-<module>.<method>
|
||
-----
|
||
-
|
||
-This variant of xref:module.adoc[<module>] 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 `<module>` portion must refer to an existing module; the
|
||
-`<method>` 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 <expansion> {
|
||
- case <match-1> {
|
||
- [ statements-1 ]
|
||
- }
|
||
- case <match-2> {
|
||
- [ 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 (<expansion> == <match-1>) {
|
||
- [ statements-1 ]
|
||
-}
|
||
-elsif (<expansion> == <match-2>) {
|
||
- [ 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}}" == <ipaddr>192.0.2.1) }
|
||
- ....
|
||
-}
|
||
-----
|
||
-
|
||
-In this example, we prefix the IP address with the string `<ipaddr>`.
|
||
-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<hex><hex>` | A byte whose numerical value is given by `<hex><hex>` interpreted as a hexadecimal number.
|
||
-| `\x<oct><oct><oct>` | A byte whose numerical value is given by `<oct><oct><oct>` 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 <a.cudbardb@freeradius.org>
|
||
-// 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 [ <list> ] {
|
||
- <server-attribute> <op> <value>
|
||
- ...
|
||
-}
|
||
-----
|
||
-
|
||
-The `update` statement adds attributes to, or edits the attributes in,
|
||
-the named _<list>_.
|
||
-
|
||
-The `update` statement consists of the following syntax elements:
|
||
-
|
||
-<list>:: The attribute list which will be updated. The list is
|
||
-usually `request`, `reply`, or `control`.
|
||
-+
|
||
-If the _<list>_ qualifier is omitted, then each entry inside of the
|
||
-`update` section *must* be prefixed with a list name. For example,
|
||
-`&request.User-Name ...`
|
||
-
|
||
-<server-attribute>:: The server attribute which is assigned the
|
||
-_<value>_.
|
||
-
|
||
-<op>:: The operator such as `=`, `:=`, etc.
|
||
-
|
||
-<value>:: 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 _<list>_ field sets the attribute list that will be updated. If
|
||
-the _<list>_ 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 _<server-attribute>_ field is an attribute name, such as
|
||
-`&Reply-Message`. The attribute name may also be prefixed with a
|
||
-_<list>_ qualifier, which overrides the _<list>_ given at the start
|
||
-of the `update` section.
|
||
-
|
||
-NOTE: In version 3, the leading `&` is optional but recommended.
|
||
-
|
||
-== Editing Operators
|
||
-
|
||
-The `<op>` 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 _<value>_.
|
||
-| !* | 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 _<server-attribute>_ and
|
||
-_<value>_ fields to enforce limits on all attributes in the given
|
||
-_<list>_, and to edit attributes which have a matching
|
||
-_<server-attribute>_ name. All other attributes are ignored.
|
||
-
|
||
-.Filtering Operators
|
||
-[options="header]
|
||
-[cols="10%,90%"]
|
||
-|=====
|
||
-| Operator | Description
|
||
-| == | Keep only the attributes in the list that match _<value>_
|
||
-| < | Keep only the attributes in the list that have values less than _<value>_.
|
||
-| \<= | Keep only the attributes in the list that have values less than or equal to _<value>_.
|
||
-| > | Keep only the attributes in the list that have values greater than _<value>_.
|
||
-| >= | Keep only the attributes in the list that have values greater than or equal to _<value>_.
|
||
-| =~ | Keep only the attributes in the list which match the regular expression given in _<value>_.
|
||
-| !~ | Keep only the attributes in the list which do not match the regular expression given in _<value>_.
|
||
-|=====
|
||
-
|
||
-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 _<value>_
|
||
-given here. If no attribute exists, it is created with the given
|
||
-_<value>_.
|
||
-
|
||
-For IP addresses, the operators `>`, `>=`, `<`, and `\<=` check for
|
||
-membership in a network. The _<value>_ 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 _<value>_ field is the value which is assigned to the
|
||
-_<server-attribute>_. The interpretation of the _<value>_ 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}:-<none>}`
|
||
-
|
||
-// 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}` +
|
||
-`%{<list>:Attribute-Name}`
|
||
-
|
||
-The `<list>:` prefix is optional. If given, it must be a valid
|
||
-reference to an xref:list.adoc[attribute list].
|
||
-
|
||
-If the `<list>:` 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:<number>}
|
||
-
|
||
-Generate random number from `0` to `<number>-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:<attribute ref>}
|
||
-
|
||
-CAUTION: This expansion is deprecated and will likely be removed.
|
||
-
|
||
-Returns a list of tags for any attributes found using ``<attribute ref>``.
|
||
-
|
||
-.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:<data>}
|
||
-
|
||
-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:<key>}
|
||
-
|
||
-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:<key>}
|
||
-
|
||
-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:<level>}
|
||
-
|
||
-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:<list:[index]>}
|
||
-
|
||
-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> <val> <char>}
|
||
-
|
||
-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> <val> <char>}
|
||
-
|
||
-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:<shared_key> <string>}
|
||
-
|
||
-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:<shared_key> <string>}
|
||
-
|
||
-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:<named capture group>}+
|
||
-
|
||
-Return named subcapture value from the last regular expression evaluated.
|
||
-
|
||
-Results of named capture groups are available using the `%{regex:<named capture
|
||
-group>}` 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:<time>}+
|
||
-
|
||
-Calculate number of seconds until next n hour(`s`), day(`s`), week(`s`), year(`s`).
|
||
-
|
||
-.Return: _string_
|
||
-
|
||
-.Example:
|
||
-
|
||
-With the current time at 16:18, `%{nexttime:1h}` will expand to `2520`.
|
||
-
|
||
-[source,unlang]
|
||
-----
|
||
-update reply {
|
||
- &Reply-Message := "You should wait for %{nexttime:1h}s"
|
||
-}
|
||
-----
|
||
-
|
||
-.Output
|
||
-
|
||
-```
|
||
-You should wait for 2520s
|
||
-```
|
||
-
|
||
-`nexttime` is provided by the `rlm_expr` module.
|
||
-
|
||
-
|
||
-
|
||
-=== +%{Packet-Type}+
|
||
-
|
||
-The packet type (`Access-Request`, etc.)
|
||
-
|
||
-
|
||
-
|
||
-=== +%{Packet-Src-IP-Address} and %{Packet-Src-IPv6-Address}+
|
||
-
|
||
-The source IPv4 or IPv6 address of the packet. See also the expansions
|
||
-`%{client:ipaddr}` and `%{client:ipv6addr}`. The two expansions
|
||
-should be identical, unless `%{client:ipaddr}` contains a DNS hostname.
|
||
-
|
||
-
|
||
-
|
||
-=== +%{Packet-Dst-IP-Address} and %{Packet-Dst-IPv6-Address}+
|
||
-
|
||
-The destination IPv4 or IPv6 address of the packet. See also the
|
||
-expansions `%{listen:ipaddr}` and `%{listen:ipv6addr}`. If the socket
|
||
-is listening on a "wildcard" address, then these two expansions will be
|
||
-different, as follows: the `%{listen:ipaddr}` will be the wildcard
|
||
-address and `%{Packet-DST-IP-Address}` will be the unicast address to
|
||
-which the packet was sent.
|
||
-
|
||
-
|
||
-
|
||
-=== +%{Packet-Src-Port} and %{Packet-Dst-Port}+
|
||
-
|
||
-The source/destination ports associated with the packet.
|
||
-
|
||
-.Return: _string_.
|
||
-
|
||
-.Example
|
||
-
|
||
-[source,unlang]
|
||
-----
|
||
-update control {
|
||
- &Tmp-String-0 := "user@example.com"
|
||
-}
|
||
-
|
||
-if (&control:Tmp-String-0 =~ /^(?<login>(.*))@(?<domain>(.*))$/) {
|
||
- update reply {
|
||
- &Reply-Message := "The %{control:Tmp-String-0} { login=%{regex:login}, domain=%{regex:domain} }"
|
||
- }
|
||
-}
|
||
-----
|
||
-
|
||
-.Output
|
||
-
|
||
-```
|
||
-The user@example.com { login=user, domain=example.com }
|
||
-```
|
||
-
|
||
-// 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/character.adoc b/doc/antora/modules/unlang/pages/xlat/character.adoc
|
||
deleted file mode 100644
|
||
index 84a148cf1b..0000000000
|
||
--- a/doc/antora/modules/unlang/pages/xlat/character.adoc
|
||
+++ /dev/null
|
||
@@ -1,80 +0,0 @@
|
||
-= Single Letter Expansions
|
||
-
|
||
-The following are single letter expansions. These expansions do not
|
||
-use the typical `%{...}` format. Instead, they are short-cuts for
|
||
-simple, common cases.
|
||
-
|
||
-== Miscellaneous
|
||
-
|
||
-`%%`::
|
||
-
|
||
-Returns `%`.
|
||
-
|
||
-
|
||
-== Current Time
|
||
-
|
||
-`%c`::
|
||
-
|
||
-The current Unix epoch time in seconds. This is an unsigned decimal number.
|
||
-It should be used with time-based calculations.
|
||
-
|
||
-`%C`::
|
||
-
|
||
-The microsecond component of the current epoch time. This is an unsigned
|
||
-decimal number. It should be used with time-based calculations.
|
||
-
|
||
-
|
||
-== Request Time
|
||
-
|
||
-`%l`::
|
||
-
|
||
-The Unix timestamp of when the request was received. This is an unsigned
|
||
-decimal number. It should be used with time-based calculations.
|
||
-
|
||
-`%Y`::
|
||
-
|
||
-Four-digit year when the request was received.
|
||
-
|
||
-`%m`::
|
||
-
|
||
-Numeric month when the request was received.
|
||
-
|
||
-`%d`::
|
||
-
|
||
-Numeric day of the month when the request was received.
|
||
-
|
||
-`%H`::
|
||
-
|
||
-Hour of the day when the request was received.
|
||
-
|
||
-`%G`::
|
||
-
|
||
-Minute component of the time when the request was received.
|
||
-
|
||
-`%e`::
|
||
-
|
||
-Second component of the time when the request was received.
|
||
-
|
||
-`%M`::
|
||
-
|
||
-Microsecond component of the time when the request was received.
|
||
-
|
||
-`%D`::
|
||
-
|
||
-Request date in the format `YYYYMMDD`.
|
||
-
|
||
-`%S`::
|
||
-
|
||
-Request timestamp in SQL format, `YYYY-mmm-ddd HH:MM:SS`.
|
||
-
|
||
-`%t`::
|
||
-
|
||
-Request timestamp in _ctime_ format, `Www Mmm dd HH:MM:SS YYYY`.
|
||
-
|
||
-`%T`::
|
||
-
|
||
-Request timestamp in ISO format, `YYYY-mm-ddTHH:MM:SS.000`.
|
||
-
|
||
-
|
||
-// 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/index.adoc b/doc/antora/modules/unlang/pages/xlat/index.adoc
|
||
deleted file mode 100644
|
||
index b42f725e6e..0000000000
|
||
--- a/doc/antora/modules/unlang/pages/xlat/index.adoc
|
||
+++ /dev/null
|
||
@@ -1,56 +0,0 @@
|
||
-= String Expansion
|
||
-
|
||
-String expansion is a feature that allows strings to dynamically
|
||
-define their value at run time. For historical reasons, these string
|
||
-expansions are called "xlats".
|
||
-
|
||
-String expansion is performed via the following syntax:
|
||
-
|
||
-`%{...}`
|
||
-
|
||
-Where the `%{` signals the start of a dynamic expansion, and `}`
|
||
-signals the end of the dynamic expansion. The contents of the
|
||
-expansion can be many things:
|
||
-
|
||
-.String Expansions
|
||
-[options="header"]
|
||
-|=====
|
||
-| Keyword | Description
|
||
-| xref:xlat/attribute.adoc[attributes] | Expand the value of a named attribute.
|
||
-| xref:xlat/character.adoc[single character] | Single character expansions.
|
||
-| xref:xlat/module.adoc[modules] | Pass a string to a module such as `sql`.
|
||
-| xref:xlat/alternation.adoc[condition] | Conditionally expand a string.
|
||
-| xref:xlat/builtin.adoc[built-in expansions] | Such as string length, tolower, etc...
|
||
-|=====
|
||
-
|
||
-This feature is used to create policies which refer to concepts rather
|
||
-than to specific values. For example, a policy can be created that
|
||
-refers to the User-Name in a request, via:
|
||
-
|
||
-`%{User-Name}`
|
||
-
|
||
-This string expansion is done only for double-quoted strings and for
|
||
-the back-tick operator.
|
||
-
|
||
-== Caveats
|
||
-
|
||
-Unlike other languages, there is no way to define new variables. All
|
||
-of the string expansions must refer to attributes that already exist,
|
||
-or to modules that will return a string value.
|
||
-
|
||
-== Character Escaping
|
||
-
|
||
-Some characters need to be escaped within a dynamically expanded
|
||
-string `%{...}`. The `%` character is used for variable expansion, so a
|
||
-literal `%` character can be created by using `%%`.
|
||
-
|
||
-Other than within a dynamically expanded string, very little
|
||
-character escaping is needed. The rules of the enclosing string context
|
||
-determine whether or not a space or " character needs to be escaped.
|
||
-
|
||
-.Example
|
||
-
|
||
-`Reply-Message := "%{User-Name} with a literal %%`
|
||
-
|
||
-// 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/module.adoc b/doc/antora/modules/unlang/pages/xlat/module.adoc
|
||
deleted file mode 100644
|
||
index 3ce43228b1..0000000000
|
||
--- a/doc/antora/modules/unlang/pages/xlat/module.adoc
|
||
+++ /dev/null
|
||
@@ -1,18 +0,0 @@
|
||
-= Module References
|
||
-
|
||
-Individual modules may be referenced via the following syntax:
|
||
-
|
||
-`%{module:string}`
|
||
-
|
||
-These references are allowed only by a small number of modules that
|
||
-usually perform database lookups. The module name is the actual name of
|
||
-the module, as described earlier. The string portion is specific to each
|
||
-module and is not documented here. It is, however, usually dynamically
|
||
-expanded to allow for additional flexibility.
|
||
-
|
||
-.Examples
|
||
-
|
||
-`%{sql:SELECT name FROM mytable WHERE username = %{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/partials/rcode_table.adoc b/doc/antora/modules/unlang/partials/rcode_table.adoc
|
||
deleted file mode 100644
|
||
index e114e74507..0000000000
|
||
--- a/doc/antora/modules/unlang/partials/rcode_table.adoc
|
||
+++ /dev/null
|
||
@@ -1,39 +0,0 @@
|
||
-[options="header"]
|
||
-[cols="15%,85%"]
|
||
-|=====
|
||
-| Return code | Description
|
||
-| `fail` | The operation failed. Usually as a result of an
|
||
- external dependency like a database being unavailable
|
||
- or an internal error.
|
||
-| `handled` | The request has been "handled", no further policies
|
||
- in the current section should be called, and the section
|
||
- should immediately exit.
|
||
-| `invalid` | The request, or operation, was invalid. In the case of
|
||
- requests this usually indicates absent or malformed
|
||
- attribute values.
|
||
-| `noop` | The operation did nothing.
|
||
-| `notfound` | A 'lookup' operation returned no results.
|
||
-| `ok` | Operation completed successfully but did not change any
|
||
- attributes in the request.
|
||
-| `reject` | The operation indicates the current request should be
|
||
- 'rejected'. What this actually means is different from
|
||
- protocol to protocol. It usually means that access to
|
||
- the requested resource should be denied, or that the
|
||
- current request should be NAKd. Usually returned when
|
||
- provided credentials were invalid.
|
||
-| `updated` | The operation completed successfully and updated one
|
||
- or more attributes in the request.
|
||
-| `disallow` | Access to a particular resource is
|
||
- denied. This is similar to `reject` but is the result
|
||
- of an authorizational check failing, as opposed to
|
||
- credentials being incorrect.
|
||
-| `yield` | Returned by an operation when execution of a request should
|
||
- be suspended.
|
||
-|=====
|
||
-
|
||
-[NOTE]
|
||
-====
|
||
-In versions ≤ v3.0.x the `disallow` rcode was called `userlock`. `disallow` and
|
||
-`userlock` have an identical meaning. `disallow` will be returned in any
|
||
-instance where `userlock` was returned in v3.0.x
|
||
-====
|