Installing FortiOS on FortiGate hardware is typically done using the TFTP (Trivial File Transfer Protocol) method via a console cable for a clean installation.
Welcome to my personal blog! Generally, I'll discuss networking and system related problems and their solutions here. I also plan to include many networking and system related multiple choice questions (MCQs) and their answers. I hope this content will be helpful to everyone.
Friday, April 24, 2026
FortiGate | Installing FortiOS on FortiGate Appliance
Install and Configure FreeRADIUS and daloRADIUS on Debian 13/Debian 12
Install and Configure FreeRADIUS and daloRADIUS on Debian 13/Debian 12
Managing network authentication becomes unscalable when using static configuration files for multiple users and NAS devices. This guide provides a modern solution by combining FreeRADIUS with the daloRADIUS web interface.
Key Technical Highlights:
- Centralized AAA: Provides a robust framework for Authentication, Authorization, and Accounting (AAA), moving beyond limited local config files.
- Database Backend: Uses MariaDB for structured data storage, ensuring scalability and easy auditing for compliance.
- Streamlined Management: daloRADIUS offers a powerful GUI to manage users, NAS clients, and accounting data, eliminating the need for direct SQL manipulation.
- Optimized for Debian: Specifically designed for Debian 13 and 12, focusing on a clean SQL integration rather than patching default configurations that are prone to breaking.
- Dependency Clarity: Explicitly covers the often-undocumented PHP and PEAR dependencies required to get the daloRADIUS stack fully operational.
Prerequisites:
- OS: Debian 13 (Trixie) or Debian 12 (Bookworm) with a minimal installation.
- Hardware: Minimalist-friendly; runs on 1 CPU and 1 GB RAM for small-to-medium deployments.
- Software Stack: * FreeRADIUS: v3.2.7 (Debian 13) or v3.2.1 (Debian 12).
- Database: MariaDB v11.8.6 or v10.11.6.
- PHP: v8.4 (Debian 13) or v8.2 (Debian 12).
Update your package index before starting:
sudo apt update && sudo apt upgrade -y
Step 1: Install MariaDB and Create the Database
FreeRADIUS stores user credentials, accounting records, and NAS client definitions in MariaDB. Install the server and client packages:
sudo apt install -y mariadb-server mariadb-client
Start and enable MariaDB so it survives reboots:
sudo systemctl enable --now mariadb
Verify the service is active:
sudo systemctl status mariadb --no-pager
Secure the installation by setting a root password and removing test databases:
sudo mariadb-secure-installation
Accept the defaults: set a root password, remove anonymous users, disallow remote root login, remove the test database, and reload privileges.
Now create the radius database and a dedicated user. Log into MariaDB:
sudo mariadb -u root -p
Run these SQL statements to create the database and grant privileges:
CREATE DATABASE radius;
GRANT ALL ON radius.* TO 'radius'@'localhost' IDENTIFIED BY 'YourStr0ngP@ss!';
FLUSH PRIVILEGES;
EXIT;
YourStr0ngP@ss! with a strong password of your own. Keep it handy because you will need it for both the FreeRADIUS and daloRADIUS configuration files.Step 2. Install FreeRADIUS with MySQL Module
Debian ships FreeRADIUS in the default repositories. Install the server along with the MySQL/MariaDB module:
sudo apt install -y freeradius freeradius-mysql freeradius-utils
This pulls in FreeRADIUS 3.2.7 on Debian 13 (3.2.1 on Debian 12). The freeradius-mysql package provides the rlm_sql_mysql driver, and freeradius-utils includes radtest for authentication testing.
Confirm the installed version:
freeradius -v | head -2
Now import the FreeRADIUS schema into MariaDB. This creates the core tables (radcheck, radreply, radacct, nas, and others):
sudo mariadb -u root -p radius < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql
The schema file path is the same on both Debian 13 and Debian 12.
Step 3. Configure FreeRADIUS SQL Backend
The default SQL module config ships with comments and placeholders that cause problems when you try to patch them with sed. A cleaner approach: write the config from scratch with only what you need.
Back up the original, then create the new config:
sudo cp /etc/freeradius/3.0/mods-available/sql /etc/freeradius/3.0/mods-available/sql.bak
Open the SQL module configuration file:
sudo vi /etc/freeradius/3.0/mods-available/sql
Replace the entire contents with the following tested configuration:
sql {
driver = "rlm_sql_mysql"
dialect = "mysql"
server = "localhost"
port = 3306
login = "radius"
password = "YourStr0ngP@ss!"
radius_db = "radius"
acct_table1 = "radacct"
acct_table2 = "radacct"
postauth_table = "radpostauth"
authcheck_table = "radcheck"
groupcheck_table = "radgroupcheck"
authreply_table = "radreply"
groupreply_table = "radgroupreply"
usergroup_table = "radusergroup"
read_clients = yes
client_table = "nas"
group_attribute = "SQL-Group"
$INCLUDE ${modconfdir}/${.:name}/main/${dialect}/queries.conf
pool {
start = 5
min = 4
max = 10
spare = 3
uses = 0
lifetime = 0
idle_timeout = 60
}
}
password field to match the MariaDB password you created earlier.Enable the SQL module by creating a symlink in mods-enabled:
sudo ln -sf /etc/freeradius/3.0/mods-available/sql /etc/freeradius/3.0/mods-enabled/sql
The symlink and the SQL config file must be owned by the freerad user, otherwise FreeRADIUS refuses to load the module:
sudo chown -h freerad:freerad /etc/freeradius/3.0/mods-enabled/sql
sudo chown freerad:freerad /etc/freeradius/3.0/mods-available/sql
Restart FreeRADIUS and check for errors:
sudo systemctl restart freeradius
sudo systemctl status freeradius --no-pager
active (running). If it fails, run sudo freeradius -X in debug mode to see the exact error.Step 4. Test FreeRADIUS Authentication
radcheck table:sudo mariadb -u root -p -e "INSERT INTO radcheck (username, attribute, op, value) VALUES ('testuser', 'Cleartext-Password', ':=', 'testing123');" radius
Now test with radtest. The shared secret for localhost is testing123 by default (defined in /etc/freeradius/3.0/clients.conf):
radtest testuser testing123 127.0.0.1 0 testing123
You should see Access-Accept in the response, confirming the SQL backend is working:
Sent Access-Request Id 146 from 0.0.0.0:41999 to 127.0.0.1:1812 length 78
User-Name = "testuser"
User-Password = "testing123"
Received Access-Accept Id 146 from 127.0.0.1:1812 to 127.0.0.1:41999 length 38
If you get Access-Reject instead, check the SQL module configuration and verify the database credentials are correct. Running sudo freeradius -X in a second terminal, while sending the test request shows exactly where the failure occurs.
Step5. Install Apache, PHP, and daloRADIUS
daloRADIUS is a PHP application that needs Apache, several PHP extensions, and one PEAR package that Debian does not install by default.
Install Apache and the required PHP modules:
sudo apt install -y apache2 libapache2-mod-php php php-mysql php-gd php-curl php-mail php-mail-mime php-xml php-mbstring php-pear
The php-db PEAR package provides the DB.php abstraction class that daloRADIUS relies on. Without it, you get a fatal error on every page load. Install it via PEAR:
sudo pear install DB
Clone the daloRADIUS repository from GitHub into the web root:
sudo apt install -y git
sudo git clone https://github.com/lirantal/daloradius.git /var/www/daloradius
This pulls daloRADIUS 2.2 beta from the master branch.
daloRADIUS requires its own database tables (operators, config, billing, and others) on top of the standard FreeRADIUS schema. Two separate imports are needed. First, the FreeRADIUS tables (if you haven’t imported them already during the FreeRADIUS setup, do it now):
sudo mariadb -u root -p radius < /var/www/daloradius/contrib/db/fr3-mariadb-freeradius.sql
Then import the daloRADIUS-specific tables:
sudo mariadb -u root -p radius < /var/www/daloradius/contrib/db/mariadb-daloradius.sql
Both imports are mandatory. Skipping the second one causes “table not found” errors when daloRADIUS tries to load its operator settings or billing configuration.
Set the correct ownership so Apache can read the files:
sudo chown -R www-data:www-data /var/www/daloradius
Step 6. Configure daloRADIUS
daloRADIUS ships a sample configuration file that you copy and edit with your database credentials.
Create the configuration file from the sample:
sudo cp /var/www/daloradius/app/common/includes/daloradius.conf.php.sample /var/www/daloradius/app/common/includes/daloradius.conf.php
Open it for editing:
sudo vi /var/www/daloradius/app/common/includes/daloradius.conf.php
Find and set these three values to match your MariaDB radius database credentials:
$configValues['CONFIG_DB_USER'] = 'radius';
$configValues['CONFIG_DB_PASS'] = 'YourStr0ngP@ss!';
$configValues['CONFIG_DB_NAME'] = 'radius';
The database host (CONFIG_DB_HOST) defaults to localhost, which is correct for this setup. Save and close the file.
Step 7. Configure Apache Virtual Host
daloRADIUS has two portals: operators (admin) and users. The operators portal is the primary interface for managing RADIUS. Point Apache’s DocumentRoot at it.
Create a new virtual host configuration:
sudo vi /etc/apache2/sites-available/daloradius.conf
Add the following configuration:
<VirtualHost *:80>
ServerAdmin admin@example.com
ServerName your-server-ip
DocumentRoot /var/www/daloradius/app/operators
<Directory /var/www/daloradius/app/operators>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/daloradius-error.log
CustomLog ${APACHE_LOG_DIR}/daloradius-access.log combined
</VirtualHost>
Replace your-server-ip with your server’s actual IP address or domain name.
Disable the default site and enable the daloRADIUS virtual host:
sudo a2dissite 000-default.conf
sudo a2ensite daloradius.conf
sudo a2enmod rewrite
Test the Apache configuration for syntax errors, then restart:
sudo apachectl configtest
sudo systemctl restart apache2
Apache should report Syntax OK. If you have a firewall running, open port 80:
sudo ufw allow 80/tcp
Step 8. Access the daloRADIUS Web UI
http://your-server-ip/. The daloRADIUS login page should appear.The default credentials are:
- Username: administrator
- Password: radius
Change the default password immediately after your first login.
After logging in, the dashboard shows a summary of online users, RADIUS server status, and quick links to common tasks. The navigation menu on the left gives you access to user management, NAS configuration, accounting reports, and server settings.
The user management section lists all RADIUS users stored in the database. From here you can add new users, edit authentication attributes, assign groups, and view accounting data per user.
Step 9. Debian 13 vs Debian 12 Differences
While the configuration logic and file paths remain identical between the two releases, the primary difference lies in the software versions provided by the official repositories as of March 2026:
| Component | Debian 13 (Trixie) | Debian 12 (Bookworm) |
| FreeRADIUS | 3.2.7 (Includes latest security patches) | 3.2.1 |
| MariaDB | 11.8.6 (Modern performance optimizations) | 10.11.6 |
| PHP | 8.4 (Fully compatible with daloRADIUS 2.2) | 8.2 |
| Apache | 2.4.66 | 2.4.62 |
| daloRADIUS | 2.2 beta (Latest GitHub clone) | 2.2 beta |
Key Takeaways:
- Compatibility: Despite the major version jumps in MariaDB (10.11 to 11.8) and PHP (8.2 to 8.4), the RADIUS SQL schema and daloRADIUS codebase are fully compatible with both.
- Security: Debian 13 (Trixie), having been released as the new "Stable" in August 2025, offers a more modern security posture and longer support lifecycle for new production deployments.
- Stability: The configuration format is unchanged, meaning scripts and documentation for Debian 12 will work perfectly on Debian 13.
Fatal error: Class ‘DB’ not found in daloRADIUS
This means the php-db PEAR package is missing. daloRADIUS uses the PEAR DB abstraction layer, which is not installed by default on Debian 13 even when you install php-pear. Fix it with:
sudo pear install DB
Restart Apache after installing:
sudo systemctl restart apache2
Table ‘radius.operators’ doesn’t exist
This happens when you only import the FreeRADIUS schema but skip the daloRADIUS schema. Two separate SQL files must be imported. The daloRADIUS tables (operators, billing, config) live in a different file:
sudo mariadb -u root -p radius < /var/www/daloradius/contrib/db/mariadb-daloradius.sql
FreeRADIUS fails to start with “rlm_sql_mysql: Cannot load library”
freeradius-mysql package is not installed. This package provides the rlm_sql_mysql.so shared library. Install it and restart:sudo apt install -y freeradius-mysql
sudo systemctl restart freeradius
Also check file ownership. The SQL module config and symlink must be owned by freerad:freerad, not root. FreeRADIUS drops privileges to the freerad user on startup and cannot read files owned by root:
sudo chown -h freerad:freerad /etc/freeradius/3.0/mods-enabled/sql
sudo chown freerad:freerad /etc/freeradius/3.0/mods-available/sql
Run FreeRADIUS in debug mode to see exactly where the failure occurs:
sudo freeradius -X
Debug mode prints every module load, config parse, and SQL connection attempt. The error message will point to the specific problem.
Cisco | Cisco 2960 Switch Configuration (PID: WS-C2960-24TC-L)
Cisco 2960 Switch Configuration (PID: WS-C2960-24TC-L):
Changing Switch Hostname:
Switch(config)#hostname DST-SW
Configuring Passwords:
DST-SW(config)#enable secret sysadminDST-SW(config)#enable secret sysadmin
DST-SW(config)#line con 0DST-SW(config-line)#password sysadminDST-SW(config-line)#login
DST-SW(config)#line vty 0 4DST-SW(config-line)#password sysadminDST-SW(config-line)#login
DST-SW(config)#service password-encryption
DST-SW(config)#banner motd$ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- UNAUTHORIZED ACCESS IS PROHIBITED -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- $
DST-SW(config)#interface vlan 1DST-SW(config-if)#ip address 192.168.101.2 255.255.255.0DST-SW(config-if)#shutdown
DST-SW(config)#ip default-gateway 192.168.101.1
DST-SW#copy running-config startup-configDestination filename [startup-config]?Building configuration… [OK]
OrDST-SW#wrBuilding configuration… [OK]
DST-SW(config)#no ip domain-lookupDST-SW(config)#line vty 0 4DST-SW(config-line)#history size 15DST-SW(config-line)# exec-timeout 10 30DST-SW(config-line)#logging synchronous
DST-SW(config)#ip domain-name example.com
DST-SW(config)#username admin secrat cisco
DST-SW(config)#crypto key generate rsa How many bits in the modulus [512]: 1024
DST-SW(config)#ip ssh version 2
DST-SW(config)#line vty 0 4DST-SW(config-line)#login localDST-SW(config-line)#transport input telnet ssh
DST-SW(config)#interface fastEthernet 0/1DST-SW(config-if)#description ***To-Core RTR***DST-SW(config-if)#speed 100 (options: 10, 100, auto)DST-SW(config)#interface range fastEthernet 0/5 – 10DST-SW(config-if-range)#duplex full (options: half, full, auto)
DST-SW#show version
DST-SW#show running-config
DST-SW#show startup-config
DST-SW#show history
DST-SW#show ip interface brief
DST-SW#show interface vlan 1
DST-SW#show interfaces description
DST-SW#show interfaces status
DST-SW#show crypto key mypubkey rsa
DST-SW#show dhcp lease
DST-SW(config-if)#switchport mode access
DST-SW(config-if)#switchport port-security
DST-SW(config-if)#switchport port-security maximum 1
DST-SW(config-if)#switchport port-security violation shutdown (options: shutdown, protect, restrict)
DST-SW(config-if)#switchport port-security mac-address 68b5.9965.1195 (options: H.H.H, sticky)
DST-SW#show mac-address-table
DST-SW#show port-security
DST-SW#show port-security interface fa0/5
DST-SW(config)#vlan 10DST-SW(config-vlan)#name ***To-IT-Users***
DST-SW(config)#interface fastEthernet 0/5DST-SW(config-if)#switchport mode accessDST-SW(config-if)#switchport access vlan 10
DST-SW(config)#interface fastEthernet 0/5DST-SW(config-if)#switchport access vlan 10DST-SW(config-if)#switchport voice vlan 12
DST-SW(config)#interface fastEthernet 0/1DST-SW(config-if)#switchport mode trunk (options: access, trunk, dynamic auto, dynamic desirable) DST-SW(config-if)#switchport trunk allowed
DST-SW(config-if)#shutdown
DST-SW(config-if)#nonegotiate (or hardcode the port as an access port)DST-SW(config-if)#switchport mode access
DST-SW(config-if)#switchport access vlan 222
DST-SW(config)#spanning-tree vlan 1 root primaryDST-SW(config)#spanning-tree vlan 1 root secondaryDST-SW(config)#spanning-tree [vlan 1] priority 8192
DST-SW(config)#spanning-tree mode rapid-pvst (options: mst, pvst, rapid-pvst)
DST-SW(config-if)#spanning-tree portfastDST-SW(config-if)#spanning-tree bpduguard enable
DST-SW(config-if)#spanning-tree [vlan 1] cost 25
DST-SW(config-if)#channel-group 1 mode on (options: auto, desirable, on)
DST-SW#show spanning-tree
DST-SW#show spanning-tree interface fa0/2
DST-SW#show spanning-tree vlan 1
DST-SW#show spanning-tree [vlan1] root
DST-SW#show spanning-tree [vlan1] bridge
DST-SW#show etherchannel 1
DST-SW#debug spanning-tree events
DST-SW(config)#cdp run
DST-SW(config-if)#no cdp enable
DST-SWSW1#show cdp
DST-SW#show cdp interface fa0/2
DST-SW#show cdp neighbors
DST-SW#show cdp neighbors detail
DST-SW#show cdp entry *
DST-SW#show cdp entry DST-SW2