This project provides a complete, containerized FreeRADIUS environment backed by a MariaDB database. It includes automatic schema initialization and a web interface (phpMyAdmin) for database management.
- FreeRADIUS 3.x: Pre-configured with the SQL module enabled.
- MariaDB Backend: Stores users, groups, accounting data, and NAS clients.
- Automatic Initialization: The container automatically checks for and imports the default FreeRADIUS SQL schema on first start.
- No Extra Init Container: Initialization logic is embedded in the main container via
start.sh. - phpMyAdmin: Easy web-based management for the database.
- Cross-Platform: Configured with
platform: linux/amd64to ensure compatibility on both AMD64 and ARM64 (Apple Silicon) hosts (via emulation).
- Docker
- Docker Compose
- Clone/Download this repository.
- Start the stack:
docker-compose up -d --build
- Access phpMyAdmin at http://localhost:8888 (User:
root, Pass:root).
By default, this stack starts a local MariaDB container (COMPOSE_PROFILES=local in .env).
To use an external database:
- Open
.env. - Comment out or remove
COMPOSE_PROFILES=local. - Set
MYSQL_HOSTto your external database IP/Hostname. - Update User/Password/Port as needed.
- Restart the stack. Docker will now ONLY start the FreeRADIUS container.
- 1812/udp: Authentication
- 1813/udp: Accounting
- 8888/tcp: phpMyAdmin (maps to 80)
- Dockerfile: Builds the custom FreeRADIUS image, installs
mysql-client, and sets the entrypoint tostart.sh. - docker-compose.yml: Defines the services (radius, db, phpmyadmin).
- start.sh: The startup script that waits for the DB, imports the schema if missing, and starts FreeRADIUS.
- raddb/: Contains the extracted and modified configuration files.
mods-available/sql: Configured for MySQL, TLS disabled,read_clients = no(Pure Dynamic).sites-available/default: SQL module enabled in all sections.sites-available/dynamic-clients: Virtual server configuration for fully dynamic, SQL-based client lookups.
- Host:
db(internal) - Database:
radius - User:
radius - Password:
radius - Root Password:
root
Execute the following SQL (e.g., via phpMyAdmin) to add a user with a cleartext password:
INSERT INTO radcheck (username, attribute, op, value)
VALUES ('testuser', 'Cleartext-Password', ':=', 'testpass');Thanks to the dynamic_clients virtual server, managing NAS clients is completely dynamic. There is no need to reload or restart FreeRADIUS when helping new clients.
-
Insert Client into Database:
INSERT INTO nas (nasname, shortname, type, secret, description) VALUES ('172.16.0.254', 'office-ap', 'other', 'secureSecret', 'Main Office Access Point');
nasname: The IP address of the client.secret: The shared secret.
-
Connect: The client can authenticate immediately.
How it works:
- The server accepts packets from any IP (
0.0.0.0/0) due to thedynamic-clientsconfiguration. - It performs a SQL lookup for the source IP.
- If found in the
nastable, the client parameters (secret, shortname, type) are loaded on-the-fly. - If not found, adding the entry to the DB makes it work instantly.
If you see this error, it means port 1812 is already in use on your host (often by a local instance of freeradius or a zombie docker process). Stop the blocking service on the host or map to a different port (e.g., 11812:1812).
You can test the server locally from within the container:
# Get container ID or name
docker ps
# Run radtest
docker exec -it freeradius-stack-radius-1 radtest testuser testpass localhost 0 testing123Note: The internal shared secret for localhost is testing123 (defined in clients.conf, not the DB).
To start FreeRADIUS in debug mode (foreground, highly verbose output):
- Open
.env. - Set
RADIUS_DEBUG=true. - Recreate the container:
docker-compose up -d --build. - View logs:
docker logs -f freeradius-stack-radius-1.