]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
docs-v4: update sql_user tutorial for v4. Added steps and outputs for debugging.
authornolade <nola.aunger@inkbridge.io>
Tue, 2 Jun 2026 22:10:08 +0000 (18:10 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 9 Jun 2026 06:13:53 +0000 (09:13 +0300)
doc/antora/modules/tutorials/pages/sql_user.adoc

index 28611a4299778f1d13283fbdff7422a20c326f43..1c28a64e047607e6ef74121f4434fd22558eb8cc 100644 (file)
@@ -1,7 +1,12 @@
-= Configuring a user in an SQL database
+= SQL Users
 
-*Goal:* To configure the server to have a new user in an SQL database,
-to send test packets as that user, and to receive a reply.
+*Goal:* To add a new user in the SQL database schema, similar to the
+xref:new_user.adoc[New User] tutorial. Next, you'll send test packets
+as that user, and to receive a reply.
+
+The RADIUS server can retrieve authentication and authorization
+information directly from the database. It can either replace or work
+with the `authorize` or `users` file.
 
 *Time:* 25-40 minutes.
 
@@ -9,83 +14,171 @@ to send test packets as that user, and to receive a reply.
 
 - `mods-available/sql`
 - `mods-config/sql/main/*`
+- `mods-config/sql/main/<dialect>/schema.sql`
+- `mods-config/sql/main/<dialect>/queries.conf`
+
+*Documentation pages:*
+
+- xref:reference:raddb/mods-available/sql.adoc[SQL]
+
+Having completed the previous xref:sql.adoc[SQL] tutorial, which
+confirmed the server's ability to communicate with the SQL database,
+our next step is to add user entries to the SQL database.
+
+== Step 1: Add a User into the SQL Database
+
+Add a test user directly into the database. We're using MySQL in this
+example, so you will connect to the database server using the `mysql`
+command-line client.
+
+Connect to your MySQL server with the credentials stored in the
+`mods-available/sql` file:
 
-Now that we have verified in the previous exercise,
-xref:sql.adoc[SQL] that the server can communicate with
-an SQL server, we proceed to adding user configuration entries into the
-SQL database.
-
-Before adding any user configuration to an SQL database, we first need
-to create the schema used to store that information. In the source
-archive, the file `RADIUS-SQL.schema` in the documentatin directory,
-describes where the schemas are located, and how to install them. In
-general, you will need to be familiar with the tools for the SQL
-database your are using, as they are too complicated and variable to
-describe here.
-
-Once the schema has been created, use an SQL client utility to execute
-the following SQL commands:
-
-[source, sql]
----------------------------------------------------------
-INSERT INTO radcheck (UserName, Attribute, op, Value)
-  values("bob", "Password.Cleartext", ":=", "hello");
-INSERT INTO radreply (UserName, Attribute, op, Value)
-  values("bob", "Reply-Message", ":=", "Hello from SQL");
----------------------------------------------------------
-
-These commands may need to be modified slightly, depending on the syntax
-required by your SQL database.
-
-These commands mirror the "check" and "reply" entries listed in the
-file for the user "bob". Use the SQL client to verify that the entries
-are now in the database.
-
-As the previous exercise in xref:sql.adoc[SQL]
-did not tell the server to query the database, but only to connect to it,
-we must now configure FreeRADIUS to query the database. This may be done
-by editing `sites-available/default`, and listing the `sql`
-module in the "authorize" section.
-
-There should already be a commented-out entry for `sql` in the
-"authorize" section or there will be `-sql` entry.
-If the entry is commented it should be un-commented, to make it live.
-If the entry has a '-' prefix, it may be left as is, the '-' prefix is used
-to mark modules as optional, so that the server can start even if they
-are not enabled.
-
-The file should now be edited to delete the existing entry or entries
-for user "bob". This may be done by commenting out the entries, rather
-than deleting them. Add a `#` character to the start of every line
-for the relevant entries, and save the updated file.
-
-The server should now be started. Send a test packet for user "bob",
-and verify that an authentication accept packet is received. Observe the
-debugging output of the server, and verify that the `sql` module is
-called, and that it successfully returns data for user "bob".
+- server    = "localhost"
+- port      = 3306
+- login     = "radius"
+- password  = "password"
+- radius_db = "radius"
+
+[source,bash]
+----
+$ mysql -h 127.0.0.1 -u radius -p
+----
+
+Enter the password when prompted.
+
+*Add the test user with the following commands:*
+
+[source,bash]
+----
+USE radius;
+
+INSERT INTO radcheck (username, attribute, op, value)
+VALUES ('alice', 'Cleartext-Password', ':=', 'testing123');
+
+INSERT INTO radreply (username, attribute, op, value)
+VALUES ('alice', 'Reply-Message', '+', 'Hello! You authenticated via the SQL database.');
+----
+These commands may need to be modified slightly, depending on the
+syntax required by your SQL database. These commands mirror the
+"check" and "reply" entries listed in the file for the user "alice".
+
+*Confirm the rows were inserted using:*
+
+Use the SQL client to verify that the entries are now in the database.
+
+----
+SELECT * FROM radcheck WHERE username = 'alice';
+SELECT * FROM radreply WHERE username = 'alice';
+----
+
+The two `INSERT` statements are the direct SQL equivalent of the
+following classic `authorize` file entry:
+
+[source,text]
+----
+mysql> SELECT * FROM radcheck WHERE username = 'alice';
++----+----------+--------------------+----+------------+
+| id | username | attribute          | op | value      |
++----+----------+--------------------+----+------------+
+|  1 | alice    | Cleartext-Password | := | hello      |
++----+----------+--------------------+----+------------+
+1 row in set (0.00 sec)
+
+mysql> SELECT * FROM radreply WHERE username = 'alice';
++----+----------+---------------+----+------------------------------------------------+
+| id | username | attribute     | op | value                                          |
++----+----------+---------------+----+------------------------------------------------+
+|  1 | alice    | Reply-Message | := | Hello! You authenticated via the SQL database. |
++----+----------+---------------+----+------------------------------------------------+
+1 row in set (0.00 sec)
+----
+
+If you see the rows appear in the `SELECT` output, the test user is
+correctly stored in the database.
+
+== Step 2: Test Authentication with `radclient`
+
+Keep the server running in debug mode (`radiusd -X`).
+
+Open a second terminal and send a PAP authentication request:
+
+[source,bash]
+----
+$ echo 'User-Name = "alice", User-Password = "hello"' | radclient -x 127.0.0.1 auth testing123
+----
+
+You should see `Access-Accept` and the `Reply-Message` coming back
+from the server. A successful response should look similar to this:
+
+[source,text]
+----
+Sent Access-Request Id 60 from 0.0.0.0:48774 to 127.0.0.1:1812 length 63
+       Message-Authenticator = 0x
+        User-Name = "alice"
+        User-Password = "hello"
+Received Access-Accept Id 60 from 127.0.0.1:1812 to 0.0.0.0:48774 via lo length 93
+        Message-Authenticator = 0x27b9670734452d218b977f5518b5e1f2
+        Reply-Message = "Hello! You authenticated via the SQL database."
+        User-Name = "alice"
+----
+
+Return to the terminal where the server is running in debug mode.
+
+After the `radclient` command completes, review the debug output. Look
+for the section that corresponds to the relevant request.
+
+*Debug output*
+
+[source,text]
+----
+(0)      sql - SQL-User-Name set to 'alice'
+(0)        sql - | %{SQL-User-Name}
+(0)        sql - | --> alice
+(0)        sql - | ||
+(0)        sql - | %logical_or()
+(0)          sql - | User-Password
+(0)            sql - | %{User-Password}
+(0)            sql - | --> hello
+(0)          sql - | %logical_or(...)
+(0)          sql - | --> hello
+(0)        sql - | %{reply.Packet-Type}
+(0)        sql - | --> Access-Accept
+(0)        sql - | %S
+(0)        sql - | --> 2026-02-11 11:06:52
+(0)        sql - | %M
+(0)        sql - | --> 374075
+(0)        sql - | %{reply.Class}
+(0)        sql - (null)
+(0)      -sql (ok)
+----
+
+== Step 3: Diagnose Failures
 
 If the server rejects the access request, then there are a number of
-steps to take, to correct the problem. Verify that FreeRADIUS is
-connecting to the SQL server, and that FreeRADIUS is "Ready to process
-requests." Verify that the file entry for "bob" has not matched the
-request. Verify that the SQL module returns "ok", rather than
-"notfound".
-
-If necessary, edit the `mods-enabled/sql` file, and enable
-additional debugging of SQL statements via the `sqltrace` and `sqltracefile`
-configuration options. If the SQL queries are performed by the server and
-logged to the file, but the request for user "bob" is still rejected, then
-perform those queries by hand, using an SQL test client. Once you have
-verified that the SQL test client returns the correct information for
-the queries, then send the access request again.
+steps to take, to correct the problem:
+
+* Verify that FreeRADIUS is connecting to the SQL server.
+* Check that FreeRADIUS has printed `Ready to process requests.`
+* Verify that the SQL module returns `ok`, rather than `notfound` for
+  the "alice" user.
+
+If necessary, edit the `mods-enabled/sql` file, and enable additional
+debugging of SQL statements via the `sqltrace` and `sqltracefile`
+configuration options. If the SQL queries are performed by the server
+and logged to the file, but the request for user "bob" is still
+rejected, then perform those queries by hand, using an SQL test
+client. Once you have verified that the SQL test client returns the
+correct information for the queries, then send the access request
+again.
 
 == Questions
 
 1.  Why do we not use an SQL database to "authenticate" users?
 2.  How do we have a DEFAULT entry in an SQL database?
 3.  Why is there no "Fall-Through" entry in an SQL database?
-4.  Does that DEFAULT entry differ from its use in the file? If so, why,
-and how? If not, why not?
+4.  Does that DEFAULT entry differ from its use in the file? If so,
+    why, and how? If not, why not?
 5.  What other configuration entries in `sites-available/default`
     exist for the `sql` module, and why?