]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
docs-v4: update/rewrite content for proxy tutorials (v4) . Replaces PR 5739.
authornolade <nola.aunger@inkbridge.io>
Thu, 5 Mar 2026 20:27:03 +0000 (15:27 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 10 Mar 2026 17:27:46 +0000 (13:27 -0400)
doc/antora/modules/tutorials/nav.adoc
doc/antora/modules/tutorials/pages/proxy.adoc
doc/antora/modules/tutorials/pages/proxy_receive.adoc

index dffc1339d88a824dffbbb14cb169447323e8a5e2..70a5dadc6301e1147539c9def735cfe78da99586 100644 (file)
@@ -33,7 +33,7 @@
 
 *** xref:variables.adoc[Variables]
 *** xref:dynamic-translation.adoc[Dynamic-Translation]
-*** xref:multiple_modules.adoc[Module instances]
+*** xref:multiple_modules.adoc[Module Instances]
 *** xref:module_fail_over.adoc[Module-Fail-Over]
 *** xref:prepaid.adoc[Prepaid]
 *** xref:dictionary.adoc[Dictionary]
index 767689b9007dce9431245d3ed1ba8eb15f20b791..cd9e14663e6d9bb7a5a837cdf9c3ac78ab3b57be 100644 (file)
@@ -1,4 +1,4 @@
-= Configuring a server to proxy requests
+= Proxying
 
 *Goal:* To configure the server to proxy packets to a remote (home)
 RADIUS server and to perform test authentications against both the
@@ -13,9 +13,9 @@ proxy server and the home server.
 
 *Diagram:*
 
-image::access-request-proxy.svg[Fig. Proxy]
+image::proxy.svg[Fig. Proxy]
 
-We assume:
+*Prerequisites:*
 
 * You already have a working *second FreeRADIUS server* (the "home" server) running on another machine / IP.
 * It accepts authentication on port 1812 with a known shared secret.
@@ -41,7 +41,7 @@ The entry for the user "bob" from the xref:new_user.adoc[New User]
 exercise, typically located in `mods-config/files/authorize`, will be
 used here.
 
-You can use the `radclient` commands shown in the testing section to
+You can use the `radclient` commands shown in the <<Testing>> section to
 simulate the authentication requests.
 
 First, you should verify that authentication requests for user "bob"
@@ -53,9 +53,9 @@ Once proxying is verified, the home server will be halted. You should
 then re-attempt to authenticate `bob@realm1.com`, and observe how the
 proxy server behaves when the home server does not respond.
 
-== Step 1. Create the proxy module instance (pointing to your home server)
+== 1. Create the proxy module instance
 
-Create this file: `mods-available/proxy-realm1`
+Create the file: `mods-available/proxy-realm1`. Add the configuration below and verify that your proxy server points to your home server.
 
 [source,text]
 ----
@@ -71,7 +71,7 @@ radius proxy-realm1 {
         secret = testing123secret
     }
 
-    # What packets to proxy
+    # What type of packets to proxy
     type = Access-Request
     type = Accounting-Request
 
@@ -93,7 +93,7 @@ $ cd mods-enabled
 $ ln -s ../mods-available/proxy-realm1 proxy-realm1
 ----
 
-== Step 2. Modify the virtual server to decide when to proxy
+== 2. Modify the virtual server to decide when to proxy
 
 Edit `sites-enabled/default`
 
@@ -127,7 +127,7 @@ authenticate proxy-realm1 {
 ----
 
 
-== Step 3. Verify the config & restart
+== 3. Verify the configuration and restart
 
 [source,text]
 ----
@@ -139,7 +139,7 @@ $ radiusd -X
 ----
 
 
-== Step 4. Testing
+== Testing
 
 Once the configuration is there, you can test each piece of
 functionality, one at a time.
@@ -151,7 +151,7 @@ functionality, one at a time.
 echo 'User-Name = "bob", User-Password = "hello"' | radclient -x 127.0.0.1 auth testing123
 ----
 
-=== Radclient output
+*Radclient output*
 
 [source,text]
 ----
@@ -164,7 +164,7 @@ Received Access-Accept Id 200 from 127.0.0.1:1812 to 0.0.0.0:58423 via lo length
         User-Name = "bob"
 ----
 
-=== Server debug output (main / proxy server with a local user)
+*Server debug output (main / proxy server with a local user)*
 
 [source,text]
 ----
@@ -195,6 +195,7 @@ Received Access-Accept Id 200 from 127.0.0.1:1812 to 0.0.0.0:58423 via lo length
 (0)          files - Password.Cleartext := hello
 (0)        files (ok)
 ----
+====
 
 === Proxied authentication
 
@@ -205,7 +206,7 @@ You can now test a proxied authentication.
 echo 'User-Name = "bob@realm1.com", User-Password = "hello"' | radclient -x 127.0.0.1 auth testing123
 ----
 
-=== Radclient output
+* Radclient output:
 
 [source,text]
 ----
@@ -218,7 +219,7 @@ Received Access-Accept Id 130 from 127.0.0.1:1812 to 0.0.0.0:43437 via lo length
         User-Name = "bob@realm1.com"
 ----
 
-=== Server debug output (main / proxy server with proxied user)
+* Server debug output (main / proxy server with proxied user):
 
 [source,text]
 ----
@@ -247,8 +248,9 @@ Received Access-Accept Id 130 from 127.0.0.1:1812 to 0.0.0.0:43437 via lo length
 (0)        proxy-realm1 - proxy-realm1 - Resuming execution
 (0)        proxy-realm1 (ok)
 ----
+====
 
-=== Proxy server debug output (when proxied packet arrives)
+* Proxy server debug output (when proxied packet arrives on a v3 server):
 
 [source,text]
 ----
index f05f58f4d10cbb77ab444ebb12f86e5d0bcf3902..80d68a46154bb9112d6d4be15c4260b103f116a4 100644 (file)
-= Configuring a server to send and receive proxy requests
+= Proxy Receive
 
-include::ROOT:partial$v3_warning.adoc[]
-
-*Goal:* To configure the server to proxy packets to a remote (home)
-RADIUS server and to receive packets from another proxy server.
+*Goal:* Configure the server to handle local authentication and proxy requests to different remote RADIUS servers based on the user-name (realm) suffix.
 
 *Time:* 15-25 minutes
 
-*Files:*
+*Files to create or edit:*
 
-- `proxy.conf`
+- `mods-available/proxy-realm1`
+- `mods-available/proxy-realm2`
+- `mods-enabled/proxy-realm1` (symlink)
+- `mods-enabled/proxy-realm2` (symlink)
 - `clients.conf`
+- `sites-enabled/default`
+
+*Diagram:*
+
+image::proxy.svg[Fig. Proxy Request-Receive]
+
+*Prerequisites:*
+
+* You already have a working *second FreeRADIUS server* (the "home" server) running on another machine / IP.
+* It accepts authentication on port 1812 with a known shared secret.
+* It can authenticate users like `bob` with password `hello`.
+
+Configure your proxy server to:
+
+* Authenticate `bob` locally using the `files` module
+* Proxy `bob@realm1.com` to remote server 1
+* Proxy `bob@realm2.com` to remote server 2
+
+You can use the radclient commands shown in the Testing section to simulate the authentication requests.
+
+== 1. Create the proxy modules
+
+Create the file `mods-available/proxy-realm1` and add the following configuration.
+
+[source,unlang]
+----
+# Proxies requests for @realm1.com to remote server 1
+
+radius proxy-realm1 {
+    mode = proxy
+    transport = udp
+
+    udp {
+        # replace with real IP of realm1 server
+        ipaddr = 192.168.100.51
+        port   = 1812
+        secret = testing123
+    }
+
+    type = Access-Request
+    type = Accounting-Request
+
+    status_check = none
+
+    connect_timeout  = 3.0
+    response_timeout = 3.0
+    zombie_period    = 40
+}
+----
+
+Create the file `mods-available/proxy-realm2` and add the following configuration.
+
+[source,unlang]
+----
+# Proxies requests for @realm2.com to remote server 2
+
+radius proxy-realm2 {
+    mode = proxy
+    transport = udp
+
+    udp {
+        # replace with real IP of realm2 server
+        ipaddr = 192.168.100.52
+        port   = 1812
+        secret = testing123
+    }
+
+    type = Access-Request
+    type = Accounting-Request
+
+    status_check = none
+
+    connect_timeout  = 3.0
+    response_timeout = 3.0
+    zombie_period    = 40
+}
+----
+
+Enable both modules by creating symlinks / softlinks in the mods-enabled directory.
+
+[source,bash]
+----
+$ cd ../mods-enabled
+$ ln -s ../mods-available/proxy-realm1 .
+$ ln -s ../mods-available/proxy-realm2 .
+----
+
+== 2. Register remote servers as clients
+
+Edit `clients.conf` and add:
+
+[source]
+----
+client realm1_remote {
+    # same IP as proxy-realm1
+    ipaddr = 192.168.100.51
+    secret = testing123
+    shortname = realm1-server
+    nas_type = other
+}
+
+client realm2_remote {
+    # same IP as proxy-realm2
+    ipaddr = 192.168.100.52
+    secret = testing123
+    shortname = realm2-server
+    nas_type = other
+}
+----
+
+== 3. Modify the virtual server logic to control when to proxy
+
+Edit `sites-enabled/default` file with the following configuration.
+
+Update the `recv Access-Request { … }` section:
+
+[source,unlang]
+----
+recv Access-Request {
+    if (&User-Name =~ /@realm1\.com$/) {
+        proxy-realm1
+
+        if (ok) {
+            accept
+        }
+    }
+    elsif (&User-Name =~ /@realm2\.com$/) {
+        proxy-realm2
+
+        if (ok) {
+            accept
+        }
+    }
+    else {
+        files
+        pap
+    }
+}
+----
+
+Update (or add) the `authenticate` section:
+
+[source,unlang]
+----
+authenticate PAP {
+        pap
+    }
+
+authenticate proxy-realm1 {
+        proxy-realm1
+    }
+
+authenticate proxy-realm2 {
+        proxy-realm2
+    }
+
+----
+
+== 4. Verify that the local user exists
+
+In `mods-config/files/authorize` (or your users file):
+
+[source,text]
+----
+bob     Cleartext-Password := "hello"
+----
+
+If the user doesn't exist, add the user to the authorize file as you did in the xref:new_user.adoc[New User] tutorial.
+
+== 5. Testing
+
+Run server in debug mode:
+
+[source,bash]
+----
+$ radiusd -X
+----
+
+All radclient tests below assume secret = `testing123`
+
+=== Local user (no realm)
+
+[source,text]
+----
+echo 'User-Name = "bob", User-Password = "hello"' | radclient -x 127.0.0.1 auth testing123
+----
+
+* Radclient output:
+
+[source,text]
+----
+Sent Access-Request Id 200 from 0.0.0.0:58423 to 127.0.0.1:1812 length 61
+  Message-Authenticator = 0x
+        User-Name = "bob"
+        User-Password = "hello"
+Received Access-Accept Id 200 from 127.0.0.1:1812 to 0.0.0.0:58423 via lo length 43
+        Message-Authenticator = 0x31d0d6a1aba5a83a6d77b4187c0562a5
+        User-Name = "bob"
+----
+
+* Server debug output (main / proxy server – local user):
+
+[source,text]
+----
+(0)      if (User-Name =~ /@realm1\.com$/)  {
+(0)        | =~
+(0)            | User-Name
+(0)              | %{User-Name}
+(0)              | --> bob
+(0)        | ({bob} =~ (null))
+(0)        | --> false
+(0)        ...
+----
+[%collapsible]
+====
+----
+(0)      }
+(0)      else {
+(0)          files - | ||
+(0)          files - | %logical_or()
+(0)            files - | Stripped-User-Name
+(0)              files - | %{Stripped-User-Name}
+(0)              files - (null)
+(0)            files - | User-Name
+(0)            files - | %logical_or(...)
+(0)              files - | %{User-Name}
+(0)              files - | --> bob
+(0)            files - | %logical_or(...)
+(0)            files - | --> bob
+(0)        files - files - Looking for key "bob"
+(0)        files - files - Found match "bob" on line 1 of ../mods-config/files/authorize
+(0)        files - files - Preparing attribute updates:
+(0)          files - Password.Cleartext := hello
+(0)        files (ok)
+----
+====
+
+
+=== Proxy to realm1.com
+
+[source,text]
+----
+echo 'User-Name = "bob@realm1.com", User-Password = "hello"' | radclient -x 127.0.0.1 auth testing123
+----
+
+* Radclient output:
+
+[source,text]
+----
+Sent Access-Request Id 130 from 0.0.0.0:43437 to 127.0.0.1:1812 length 72
+  Message-Authenticator = 0x
+        User-Name = "bob@realm1.com"
+        User-Password = "hello"
+Received Access-Accept Id 130 from 127.0.0.1:1812 to 0.0.0.0:43437 via lo length 54
+        Message-Authenticator = 0x591568951632aae69f913f707912e464
+        User-Name = "bob@realm1.com"
+----
+
+* Server debug output (main / proxy server – proxied user):
+
+[source,text]
+----
+(0)      if (User-Name =~ /@realm1\.com$/)  {
+(0)        | =~
+(0)            | User-Name
+(0)              | %{User-Name}
+(0)              | --> bob@realm1.com
+(0)        | ({bob@realm1.com} =~ (null))
+(0)        | --> true
+(0)        proxy-realm1 - proxy-realm1 - [1] Trunk connection assigned request 1
+----
+[%collapsible]
+====
+----
+(0)        proxy-realm1 - Sending Access-Request ID 0 length 0 over connection proto udp local 10.0.16.96 port 37726 remote 44.222.160.231 port 1812
+(0)          proxy-realm1 - Message-Authenticator = 0xb8c474a818edf42917887303b3181172
+(0)          proxy-realm1 - User-Name = "bob@realm1.com"
+(0)          proxy-realm1 - User-Password = "hello"
+(0)          proxy-realm1 - Packet {
+(0)            proxy-realm1 - Id = 130
+(0)            proxy-realm1 - Authenticator = 0x970cd7fde6e8fefc4d155017d1a0bed1
+(0)          proxy-realm1 - }
+(0)          proxy-realm1 - Packet-Type = ::Access-Request
+(0)          proxy-realm1 - Proxy-State = 0x6836cf35495baced
+(0)        proxy-realm1 - Proxied request.  Relying on NAS to perform more retransmissions
+(0)        proxy-realm1 - Received Access-Accept ID 0 length 48 reply packet on connection proto udp local 10.0.16.96 port 37726 remote 44.222.160.231 port 1812
+(0)          proxy-realm1 - Message-Authenticator = 0xb0438c94e081c9c66b194a770b38bd5f
+(0)          proxy-realm1 - Proxy-State = 0xedac5b4935cf3668
+(0)        proxy-realm1 - proxy-realm1 - Resuming execution
+(0)        proxy-realm1 (ok)
+----
+====
 
-For this exercise, the users will be divided into groups of two. One
-user will be named "realm1" and the other will be named
-"realm2".
+* Proxy server debug output (when proxied packet arrives):
 
-Each user will configure two realms in the `proxy.conf` file. One of the
-user's assigned realms will be authenticated by the local RADIUS
-server. The other realm will be proxied to the RADIUS server
-administered by the other user. Both realms will be configured to
-"strip" the realm name from the incoming request.
+[source,text]
+----
+(0) suffix: Checking for suffix after "@"
+(0) suffix: Looking up realm "realm1.com" for User-Name = "bob@realm1.com"
+(0) suffix: Found realm "default"
+(0) suffix: Adding Stripped-User-Name = "bob"
+(0) suffix: Adding Realm = "default"
+(0) suffix: Authentication realm is LOCAL
+(0)     [suffix] = ok
+----
+[%collapsible]
+====
+----
+(0) files: users: Matched entry bob at line 2
+(0)     [files] = ok
+(0)     [pap] = updated
+(0)   } # authorize = updated
+(0) Found Auth-Type = PAP
+(0) # Executing group from file ../sites-enabled/default
+(0)   Auth-Type PAP {
+(0)     [ok] = ok
+(0)   } # Auth-Type PAP = ok
+----
+====
 
-User 1:
 
-realm1 is local
+=== Proxy to realm2.com
 
-realm2 gets proxied to the server running as "realm2".
+[source,text]
+----
+echo 'User-Name = "bob@realm2.com", User-Password = "hello"' | radclient -x 127.0.0.1 auth testing123
+----
 
-User 2:
+* Radclient output:
 
-realm1 gets proxied to the server running as "realm1".
+[source,text]
+----
+Sent Access-Request Id 130 from 0.0.0.0:43437 to 127.0.0.1:1812 length 72
+  Message-Authenticator = 0x
+        User-Name = "bob@realm2.com"
+        User-Password = "hello"
+Received Access-Accept Id 130 from 127.0.0.1:1812 to 0.0.0.0:43437 via lo length 54
+        Message-Authenticator = 0x591568951632aae69f913f707912e464
+        User-Name = "bob@realm2.com"
+----
 
-realm2 is local
+* Server debug output (main / proxy server – proxied user):
 
-The users should also configure each other's server as a RADIUS
-client, as given in the exercise in xref:new_client.adoc[New Clients].
+[source,text]
+----
+(0)      if (User-Name =~ /@realm2\.com$/)  {
+(0)        | =~
+(0)            | User-Name
+(0)              | %{User-Name}
+(0)              | --> bob@realm2.com
+(0)        | ({bob@realm2.com} =~ (null))
+(0)        | --> true
+----
+[%collapsible]
+====
+----
+(0)        proxy-realm2 - proxy-realm2 - [1] Trunk connection assigned request 1
+(0)        proxy-realm2 - Sending Access-Request ID 0 length 0 over connection proto udp local 10.0.16.96 port 37726 remote 44.222.160.231 port 1812
+(0)          proxy-realm2 - Message-Authenticator = 0xb8c474a818edf42917887303b3181172
+(0)          proxy-realm2 - User-Name = "bob@realm2.com"
+(0)          proxy-realm2 - User-Password = "hello"
+(0)          proxy-realm2 - Packet {
+(0)            proxy-realm2 - Id = 130
+(0)            proxy-realm2 - Authenticator = 0x970cd7fde6e8fefc4d155017d1a0bed1
+(0)          proxy-realm2 - }
+(0)          proxy-realm2 - Packet-Type = ::Access-Request
+(0)          proxy-realm2 - Proxy-State = 0x6836cf35495baced
+(0)        proxy-realm2 - Proxied request.  Relying on NAS to perform more retransmissions
+(0)        proxy-realm2 - Received Access-Accept ID 0 length 48 reply packet on connection proto udp local 10.0.16.96 port 37726 remote 44.222.160.231 port 1812
+(0)          proxy-realm2 - Message-Authenticator = 0xb0438c94e081c9c66b194a770b38bd5f
+(0)          proxy-realm2 - Proxy-State = 0xedac5b4935cf3668
+(0)        proxy-realm2 - proxy-realm2 - Resuming execution
+(0)        proxy-realm2 (ok)
+----
+====
 
-The entry from the exercise in xref:new_user.adoc[New User] for user "bob" in
-the file, will be used in this exercise.
+* Proxy server debug output (when proxied packet arrives):
 
-The example packets `bob.sh`, `bob@realm1.sh`, and `bob@realm2.sh` may
-be used in this exercise.
+[source,text]
+----
+(0) suffix: Checking for suffix after "@"
+(0) suffix: Looking up realm "realm2.com" for User-Name = "bob@realm2.com"
+(0) suffix: Found realm "default"
+(0) suffix: Adding Stripped-User-Name = "bob"
+(0) suffix: Adding Realm = "default"
+(0) suffix: Authentication realm is LOCAL
+(0)     [suffix] = ok
+----
+[%collapsible]
+====
+----
+(0) files: users: Matched entry bob at line 2
+(0)     [files] = ok
+(0)     [pap] = updated
+(0)   } # authorize = updated
+(0) Found Auth-Type = PAP
+(0) # Executing group from file ../sites-enabled/default
+(0)   Auth-Type PAP {
+(0)     [ok] = ok
+(0)   } # Auth-Type PAP = ok
+----
+====
 
-Each user should test that authentication requests from "bob" to
-their RADIUS server should result in authentication accept replies and
-that the request was not forwarded to the other RADIUS server.
 
-Each user should test that authentication requests for their own
-realm (User 1: "bob@realm1", User 2: "bob@realm2") to their
-RADIUS server should result in authentication accept replies and that
-the request was not forwarded to the other RADIUS server.
+=== Proxy failure simulation
 
-Each user in turn should then attempt authentication using the other
-user's realm (User 1: "bob@realm2", User 2: "bob@realm1"),
-to their local RADIUS server.
+Stop the remote server for realm1, then run:
 
-Each in turn should verify that authentication requests for their
-realm sent to the other user's RADIUS server results in an
-authentication reject.
+[source,text]
+----
+echo 'User-Name = "bob@realm1.com", User-Password = "hello"' | radclient -x 127.0.0.1 auth testing123
+----
 
-User 2 should then stop his server. User 1 should then attempt an
-authentication request to his server where the request would normally
-be proxied. Both users should examine the debug logs of User 1's
-RADIUS client and server in order to observe what the server's resulting behaviour
-will be.
+The request should be rejected. Examine the debug logs (of the realm1 user's)
+RADIUS client and server
 
 == Questions