Linux Tutorials

Install FreeRADIUS and daloRADIUS on Ubuntu 26.04|24.04|22.04

FreeRADIUS is an open-source, high-performance RADIUS server that handles authentication, authorization, and accounting (AAA) for network access. It supports request proxying with failover and load balancing, and connects to many backend databases including MySQL, PostgreSQL, and LDAP.

Original content from computingforgeeks.com - post 3022

This guide covers installing FreeRADIUS with the daloRADIUS web management interface on Ubuntu 26.04, 24.04, and 22.04 LTS. The install steps are identical across all three releases; only the package versions differ, which the table below lists. daloRADIUS provides a PHP-based web dashboard for managing RADIUS users, NAS devices, billing plans, and accounting reports, mainly used for hotspot and ISP deployments. If you need a newer FreeRADIUS than the Ubuntu repositories ship, you can build FreeRADIUS from source instead. Every command and screenshot below comes from runs on Ubuntu 26.04, 24.04, and 22.04 with daloRADIUS 2.3 in June 2026, and the 2.3 pin still matches the current upstream release as of August 2026.

ComponentUbuntu 26.04Ubuntu 24.04Ubuntu 22.04
FreeRADIUS3.2.83.2.53.0.26
PHP8.58.38.1
daloRADIUS2.32.32.3
Config directory/etc/freeradius/3.0/ on all three

What is daloRADIUS?

daloRADIUS is a web front end for FreeRADIUS, not a RADIUS server itself. It is a PHP application that reads and writes the same MySQL or MariaDB tables FreeRADIUS authenticates against, which is why it has to sit alongside a working FreeRADIUS instance with a SQL backend rather than run on its own. Point it at an empty database and there is nothing for it to manage.

The project is GPL-2.0 licensed and lives at github.com/lirantal/daloradius. Release 2.3, published in May 2026, is the current tagged version and the one this guide installs. It ships two separate interfaces: an operators dashboard for administrators and a lighter users portal for self service, which is why the steps below configure two Apache vhosts on different ports.

Prerequisites

  • A server running Ubuntu 26.04, 24.04, or 22.04 LTS with at least 1GB RAM
  • Root or sudo access
  • Ports to open: 1812/UDP (RADIUS auth), 1813/UDP (RADIUS accounting), 80/TCP (daloRADIUS users portal), 8000/TCP (daloRADIUS operators portal)

Step 1: Update Ubuntu System

Start by updating all system packages to the latest available versions:

sudo apt update && sudo apt -y upgrade

Reboot if the kernel was updated:

[ -f /var/run/reboot-required ] && sudo reboot -f

Step 2: Install Apache and PHP

daloRADIUS needs Apache and PHP with several extensions. Install the web server first:

sudo apt -y install apache2

Then install PHP and all required extensions:

sudo apt -y install php libapache2-mod-php php-{gd,common,mail,mail-mime,mysql,pear,db,mbstring,xml,curl,zip}

Confirm PHP is installed and working:

php -v

You should see the active PHP version. The output below is from Ubuntu 24.04; on 26.04 you get PHP 8.5 and on 22.04 PHP 8.1:

PHP 8.3.6 (cli) (built: Jan 27 2026 03:09:47) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.6, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.6, Copyright (c), by Zend Technologies

Step 3: Install MariaDB and Create Database

FreeRADIUS stores user credentials, NAS information, and accounting data in a database. Install MariaDB server:

sudo apt -y install mariadb-server

Create the RADIUS database and a dedicated user. Log into MariaDB and run these SQL statements:

sudo mariadb

At the MariaDB prompt, create the database and grant permissions:

CREATE DATABASE radius;
GRANT ALL ON radius.* TO radius@localhost IDENTIFIED BY "Str0ngR@diusPass";
FLUSH PRIVILEGES;
QUIT;

Replace Str0ngR@diusPass with your own strong password. If you have a dedicated database server, replace localhost with the IP address of the FreeRADIUS server. Keep a percent sign out of that password: daloRADIUS builds a URL style connection string and passes it through rawurldecode(), so Pa%41ss reaches MariaDB as PaAss and the login fails with nothing in the page to explain it. An @ is safe, because the parser splits on the last one.

Step 4: Install and Configure FreeRADIUS

Ubuntu ships FreeRADIUS in its default repositories: 3.2.8 on 26.04, 3.2.5 on 24.04, and 3.0.26 on 22.04. Check what is available on your system:

sudo apt policy freeradius

The output shows the candidate version from the Ubuntu repositories:

freeradius:
  Installed: (none)
  Candidate: 3.2.5+dfsg-3~ubuntu24.04.3
  Version table:
     3.2.5+dfsg-3~ubuntu24.04.3 500
        500 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages

Install FreeRADIUS along with the MySQL module and utility tools:

sudo apt -y install freeradius freeradius-mysql freeradius-utils

Import the FreeRADIUS MySQL Schema

FreeRADIUS includes a SQL schema that creates the tables it needs for storing users, groups, and accounting records. The schema file is readable only by root and the freerad user, so the import must run inside a root shell. A plain sudo mysql with a shell redirect fails with Permission denied because your unprivileged shell opens the file, not sudo:

sudo bash -c "mysql -u root radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql"

Verify the tables were created:

sudo mysql -u root -e "USE radius; SHOW TABLES;"

You should see the core FreeRADIUS tables including radcheck, radacct, and nas:

+------------------+
| Tables_in_radius |
+------------------+
| nas              |
| nasreload        |
| radacct          |
| radcheck         |
| radgroupcheck    |
| radgroupreply    |
| radpostauth      |
| radreply         |
| radusergroup     |
+------------------+

Enable and Configure the SQL Module

Create a symbolic link to enable the SQL module:

sudo ln -s /etc/freeradius/3.0/mods-available/sql /etc/freeradius/3.0/mods-enabled/

Open the SQL module configuration file:

sudo vi /etc/freeradius/3.0/mods-enabled/sql

Update the connection parameters in the sql block to match your database credentials:

sql {
    driver = "rlm_sql_mysql"
    dialect = "mysql"

    # Connection info:
    server = "localhost"
    port = 3306
    login = "radius"
    password = "Str0ngR@diusPass"

    # Database table configuration for everything except Oracle
    radius_db = "radius"

    # Set to 'yes' to read radius clients from the database ('nas' table)
    # Clients will ONLY be read on server startup.
    read_clients = yes

    # Table to keep radius client info
    client_table = "nas"
}

The default values for driver and dialect are set to rlm_sql_null and sqlite. Change them to rlm_sql_mysql and mysql. The server, port, login, password, and radius_db lines are commented out by default, so uncomment and set them.

In the same file, find the mysql block and comment out the entire tls section inside it. FreeRADIUS will fail to start if the TLS certificate files do not exist:

        mysql {
                # If any of the files below are set, TLS encryption is enabled
#               tls {
#                       ca_file = "/etc/ssl/certs/my_ca.crt"
#                       ca_path = "/etc/ssl/certs/"
#                       certificate_file = "/etc/ssl/certs/private/client.crt"
#                       private_key_file = "/etc/ssl/certs/private/client.key"
#                       cipher = "DHE-RSA-AES256-SHA:AES128-SHA"
#
#                       tls_required = yes
#                       tls_check_cert = no
#                       tls_check_cert_cn = no
#               }

                # If yes, (or auto and libmysqlclient reports warnings are
                # available), will retrieve and log additional warnings from
                # the server if an error has occured. Defaults to 'auto'
                warnings = auto
        }

Set the correct ownership on the SQL module files so the freerad user can read them:

sudo chgrp -h freerad /etc/freeradius/3.0/mods-available/sql
sudo chown -R freerad:freerad /etc/freeradius/3.0/mods-enabled/sql

Restart FreeRADIUS to load the SQL module:

sudo systemctl restart freeradius.service

Verify the service is running:

systemctl status freeradius.service

The output should show active (running) with "Processing requests" as the status:

● freeradius.service - FreeRADIUS multi-protocol policy server
     Loaded: loaded (/usr/lib/systemd/system/freeradius.service; enabled; preset: enabled)
     Active: active (running) since Sat 2026-03-21 20:43:48 UTC; 9ms ago
       Docs: man:radiusd(8)
             man:radiusd.conf(5)
             http://wiki.freeradius.org/
             http://networkradius.com/doc/
    Process: 15105 ExecStartPre=/usr/sbin/freeradius $FREERADIUS_OPTIONS -Cx -lstdout (code=exited, status=0/SUCCESS)
   Main PID: 15107 (freeradius)
     Status: "Processing requests"
      Tasks: 6 (limit: 2315)
     Memory: 42.9M (max: 2.0G)
        CPU: 261ms
     CGroup: /system.slice/freeradius.service
             └─15107 /usr/sbin/freeradius -f

If the restart fails with Job for freeradius.service failed because the control process exited with error code, check the log with journalctl -u freeradius -n 30. The most common cause is ERROR 1146 (Table 'radius.nas' doesn't exist), which means the schema import above never actually ran; with read_clients = yes FreeRADIUS reads the nas table at startup and refuses to start without it. Re-run the import with the sudo bash -c form, confirm SHOW TABLES lists the nine tables, then restart again. The second cause is a typo in the SQL credentials, and the third is a missed tls block comment-out; sudo freeradius -XC pinpoints either one.

Step 5: Install and Configure daloRADIUS

daloRADIUS provides a web-based management interface for FreeRADIUS with user management, billing, graphical reporting, and NAS configuration. Clone the latest stable release from GitHub:

sudo apt -y install git
git clone --branch 2.3 https://github.com/lirantal/daloradius.git #https://github.com/lirantal/daloradius/tags

Import daloRADIUS Database Tables

The clone is pinned to the tested 2.3 release on purpose, so the commands and screenshots below match what you actually get. Master moves on its own schedule. Older master checkouts aborted the schema import with ERROR 1136 (21S01): Column count doesn't match value count at row 1, which is why guides tell you to pin, but that is fixed upstream: a master clone taken on 2026-08-08 imported cleanly against MariaDB 11.8.6.

daloRADIUS ships two SQL schema files. One extends the FreeRADIUS tables and the other creates daloRADIUS-specific tables for operators, billing, and hotspot management:

sudo mysql -u root radius < daloradius/contrib/db/fr3-mariadb-freeradius.sql
sudo mysql -u root radius < daloradius/contrib/db/mariadb-daloradius.sql

Configure daloRADIUS Database Connection

Move the daloRADIUS directory to the web server root:

sudo mv daloradius /var/www/

Create the configuration file from the sample and set the correct ownership:

cd /var/www/daloradius/app/common/includes/
sudo cp daloradius.conf.php.sample daloradius.conf.php
sudo chown www-data:www-data daloradius.conf.php

Open the configuration file:

sudo vi daloradius.conf.php

Update the database connection variables to match what you configured in Step 3. The defaults use raduser, radpass, and raddb, so change them to your actual values:

$configValues['CONFIG_DB_HOST'] = 'localhost';
$configValues['CONFIG_DB_PORT'] = '3306';
$configValues['CONFIG_DB_USER'] = 'radius';
$configValues['CONFIG_DB_PASS'] = 'Str0ngR@diusPass';
$configValues['CONFIG_DB_NAME'] = 'radius';

Create the log and backup directories that daloRADIUS needs:

cd /var/www/daloradius/
sudo mkdir -p var/{log,backup}
sudo chown -R www-data:www-data var

Step 6: Configure Apache Virtual Hosts for daloRADIUS

daloRADIUS 2.x has two separate portals: an operators portal for administration (port 8000) and a users self-service portal (port 80). Each needs its own Apache virtual host.

First, add port 8000 to Apache's listening ports. Open the ports configuration file:

sudo vi /etc/apache2/ports.conf

Add the Listen 8000 directive so Apache accepts connections on both ports:

Listen 80
Listen 8000

<IfModule ssl_module>
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
</IfModule>

Create the operators virtual host on port 8000. Create a new file:

sudo vi /etc/apache2/sites-available/operators.conf

Add the following virtual host configuration:

<VirtualHost *:8000>
    ServerAdmin operators@localhost
    DocumentRoot /var/www/daloradius/app/operators

    <Directory /var/www/daloradius/app/operators>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    <Directory /var/www/daloradius>
        Require all denied
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/daloradius/operators/error.log
    CustomLog ${APACHE_LOG_DIR}/daloradius/operators/access.log combined
</VirtualHost>

Create the users virtual host on port 80:

sudo vi /etc/apache2/sites-available/users.conf

Add this configuration:

<VirtualHost *:80>
    ServerAdmin users@localhost
    DocumentRoot /var/www/daloradius/app/users

    <Directory /var/www/daloradius/app/users>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
    </Directory>

    <Directory /var/www/daloradius>
        Require all denied
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/daloradius/users/error.log
    CustomLog ${APACHE_LOG_DIR}/daloradius/users/access.log combined
</VirtualHost>

Enable the new virtual hosts, create the log directories, and disable the default site:

sudo a2ensite users.conf operators.conf
sudo mkdir -p /var/log/apache2/daloradius/{operators,users}
sudo a2dissite 000-default.conf

Restart both Apache and FreeRADIUS to apply all changes:

sudo systemctl restart apache2 freeradius

Step 7: Open Firewall Ports

If UFW firewall is active, allow the required ports for RADIUS and daloRADIUS:

sudo ufw allow 1812/udp
sudo ufw allow 1813/udp
sudo ufw allow 80/tcp
sudo ufw allow 8000/tcp
sudo ufw reload

Step 8: Verify the Installation

Confirm both services are running:

systemctl status apache2 freeradius

Both services should show active (running):

● apache2.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled)
     Active: active (running) since Sat 2026-03-21 20:44:47 UTC; 3s ago
...
● freeradius.service - FreeRADIUS multi-protocol policy server
     Loaded: loaded (/usr/lib/systemd/system/freeradius.service; enabled; preset: enabled)
     Active: active (running) since Sat 2026-03-21 20:44:47 UTC; 3s ago

Test RADIUS authentication by adding a test user and running radtest:

sudo mysql -u root -e "INSERT INTO radcheck (username, attribute, op, value) VALUES ('testuser', 'Cleartext-Password', ':=', 'testpass123');" radius
radtest testuser testpass123 127.0.0.1 0 testing123

A successful authentication returns Access-Accept:

Sent Access-Request Id 190 from 0.0.0.0:40859 to 127.0.0.1:1812 length 78
	User-Name = "testuser"
	User-Password = "testpass123"
	NAS-IP-Address = 127.0.1.1
	NAS-Port = 0
	Message-Authenticator = 0x00
	Cleartext-Password = "testpass123"
Received Access-Accept Id 190 from 127.0.0.1:1812 to 127.0.0.1:40859 length 38

Step 9: Access daloRADIUS Web Interface

Open a browser and navigate to the daloRADIUS portals using your server's IP address:

  • Operators portal (administration): http://10.0.1.50:8000/
  • Users portal (self-service): http://10.0.1.50/

The operators portal on port 8000 opens to a login screen:

daloRADIUS 2.3 operators login page on Ubuntu

The default login credentials for the operators portal are:

Username: administrator
Password: radius

Change this password immediately after first login from the operators portal under Config > Operators.

After signing in, the dashboard summarizes server status, the latest connection attempts, and the count of registered users and NAS devices:

daloRADIUS 2.3 dashboard on Ubuntu 26.04 showing a RADIUS Access-Accept

Register your network access servers (routers, switches, or access points) under Management > Nas before they authenticate against FreeRADIUS:

daloRADIUS NAS clients listing on Ubuntu

With a NAS registered and a user in place, daloRADIUS becomes the single console for managing users, tracking accounting, and running reports against FreeRADIUS.

Troubleshooting: Database connection error at login

Submitting the operators login and landing on a page that reads Database connection error means the web stack is fine and PHP could not reach MariaDB. The message is printed by app/common/includes/db_open.php, which assembles a connection string from the CONFIG_DB_* values and repeats whatever the database layer hands back. The second line is the part that identifies the fault.

Error MessageCause
DB Error: connect failedMariaDB refused the connection. The user, password, or database name in daloradius.conf.php does not match what you granted, or the host is not reachable
DB Error: extension not foundCONFIG_DB_ENGINE is set to mysql. It has to stay mysqli, which is the sample file's default; the older extension was dropped from PHP long ago
DB Error: not foundApache cannot read daloradius.conf.php, so every setting is empty. Check that the file is owned by www-data
Blank page, HTTP 500The same credential problem as the first row, on PHP 8.1 or newer, where mysqli raises an exception instead of returning an error and the script dies before printing anything. The reason is in the error log

Three commands settle it. The first tests the credentials on their own, the second shows the real PHP error the browser hides, and the third shows what daloRADIUS is actually configured with:

mysql -u radius -p'Str0ngR@diusPass' -h localhost radius -e "SELECT COUNT(*) FROM operators;"
sudo tail -20 /var/log/apache2/daloradius/operators/error.log
sudo grep CONFIG_DB_ /var/www/daloradius/app/common/includes/daloradius.conf.php

If the first command fails, the GRANT from Step 3 never ran or the password differs from the one in the config file; re-run the GRANT and set the identical string in both places. If it succeeds, the error log names the cause outright, for example Access denied for user 'radius'@'localhost' (using password: YES) for a password mismatch, or Access denied for user 'radius'@'localhost' to database 'raddb' when CONFIG_DB_NAME is still the sample value.

One more trap: MariaDB on Ubuntu listens on 127.0.0.1 only. Pointing CONFIG_DB_HOST at the server's LAN address therefore fails even on the same machine, until you change bind-address in the MariaDB config and grant the user from that host as well.

Next steps

FreeRADIUS and daloRADIUS are now running on your Ubuntu server with MariaDB as the backend database. The RADIUS server handles authentication on ports 1812/1813 UDP while daloRADIUS provides web management on ports 80 and 8000.

For production deployments, secure the daloRADIUS web interface with HTTPS using Let's Encrypt, restrict access to the operators portal by IP, and set up regular database backups. You can find the installation guide for other Linux distributions below:

Keep reading

Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Ubuntu Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) UFW Firewall Commands with Examples on Ubuntu 24.04 / 22.04 Security UFW Firewall Commands with Examples on Ubuntu 24.04 / 22.04 Configure Samba File Share on Debian 13 / 12 Debian Configure Samba File Share on Debian 13 / 12 Configure Telegraf Input Plugins for Docker, Nginx and PostgreSQL Monitoring Configure Telegraf Input Plugins for Docker, Nginx and PostgreSQL Migrate InfluxDB 2 to InfluxDB 3 on Ubuntu 26.04 / 24.04 Databases Migrate InfluxDB 2 to InfluxDB 3 on Ubuntu 26.04 / 24.04 Ubuntu 22.04 vs Fedora 36 – Comparison Table Fedora Ubuntu 22.04 vs Fedora 36 – Comparison Table

12 thoughts on “Install FreeRADIUS and daloRADIUS on Ubuntu 26.04|24.04|22.04”

  1. You should not run this command sudo mysql -u root -p radius < contrib/db/fr2-mysql-daloradius-and-freeradius.sql. It will drop all of your tables in the previous steps.

    Reply
  2. When I run this command

    root@svr-radius01:~# sudo mysql -u root radius < daloradius/contrib/db/mariadb-daloradius.sql

    I get
    ————–
    INSERT INTO `operators` VALUES (1,'administrator','radius','','','','','','','','','','','','',NULL,CURRENT_TIMESTAMP,'admin',NULL,NULL)
    ————–

    ERROR 1136 (21S01) at line 10299: Column count doesn't match value count at row 1

    can someone help please
    thanks

    Reply
    • This is an upstream daloRADIUS bug, not your setup. The development branch you cloned added five TOTP columns to the operators table but never updated its seed row, so the INSERT has 20 values against 25 columns and the import aborts at that line. The guide now clones the tagged 2.3 release, which imports cleanly.

      Since the failed import left the database half-built, switch to the release and rebuild it:

      cd daloradius
      git checkout 2.3
      sudo mysql -e “DROP DATABASE radius; CREATE DATABASE radius;”
      sudo mysql -u root radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql sudo mysql -u root radius < daloradius/contrib/db/fr3-mariadb-freeradius.sql sudo mysql -u root radius < daloradius/contrib/db/mariadb-daloradius.sql The operators portal then logs in with administrator / radius.

      Reply
  3. When I execute the following command

    sudo systemctl restart freeradius.service

    Job for freeradius.service failed because the control process exited with error code.
    See “systemctl status freeradius.service” and “journalctl -xeu freeradius.service” for details.

    Any help is apreciated

    Reply
    • That failure is almost always an empty radius database. The schema import command in the earlier revision of this guide failed silently with Permission denied when run from a sudo user, and with read_clients = yes FreeRADIUS will not start because the nas table is missing. Check journalctl -u freeradius -n 30; if you see ERROR 1146 (Table radius.nas does not exist), re-run the import as
      sudo bash -c “mysql -u root radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql" then restart the service. The guide now carries the corrected command. If the tables already exist, run sudo freeradius -XC and it will point at the actual failing line, usually a credentials typo or a tls block in mods-enabled/sql that was not commented out.

      Reply
  4. Good afternoon, I installed everything according to your article, but after entering the account, an error appears.

    Database connection error
    Error Message: DB Error: connect failed

    Reply
    • I rebuilt this guide from scratch on a clean Ubuntu 24.04 host today, start to finish, and the operators login lands on the dashboard with no database error, so the difference is in your setup rather than in the steps.

      That message is printed by app/common/includes/db_open.php, and the second line is the part that identifies the fault:

      DB Error: connect failed means MariaDB refused the connection, so the user, password or database name in daloradius.conf.php does not match what you granted, or the host is not reachable.
      DB Error: extension not found means CONFIG_DB_ENGINE was changed to mysql. It has to stay mysqli.
      DB Error: not found means Apache cannot read daloradius.conf.php, so every value is empty.

      Three commands will tell you which one it is:

      mysql -u radius -p’YourPassword’ -h localhost radius -e “SELECT COUNT(*) FROM operators;”
      sudo tail -20 /var/log/apache2/daloradius/operators/error.log
      sudo grep CONFIG_DB_ /var/www/daloradius/app/common/includes/daloradius.conf.php

      If the first one fails, the GRANT never ran or the password differs between MariaDB and the config file. If it succeeds, the error log names the cause outright, for example Access denied for user 'radius'@'localhost' (using password: YES).

      Two traps that catch people here. A percent sign in the password is silently decoded away, because daloRADIUS builds a URL style connection string and runs it through rawurldecode(), so Pa%41ss reaches MariaDB as PaAss; an @ is safe. And MariaDB on Ubuntu listens on 127.0.0.1 only, so pointing CONFIG_DB_HOST at the server’s LAN address fails even on the same machine until you change bind-address and grant the user from that host too.

      One thing that would help me help you: seeing “DB Error: connect failed” at all tells me your PHP is 8.0 or older. On 8.1 and newer mysqli throws instead of returning an error, and the same misconfiguration gives a blank HTTP 500 page rather than this one. Which distribution and PHP version are you on? If it is not Ubuntu 22.04, 24.04 or 26.04, the Rocky Linux and Debian guides linked at the end of the article will match your host more closely.

      I have added a troubleshooting section covering all of the above to the article.

      Reply
      • Thank you very much, there really was an error in the account. One more request: you write the instructions very clearly; perhaps you could write a basic description of how to set up and use FreeRadius? What are the nuances?

        Reply

Leave a Comment

Press ESC to close