In today’s digital age, the demand for secure and efficient network access control has never been higher. Organizations of all sizes are increasingly relying on wireless networks to provide connectivity to their employees, customers, and guests. However, with this convenience comes the challenge of ensuring that only authorized users can access the network, and that their usage can be monitored and managed effectively.
This comprehensive guide is designed to address these challenges by providing a detailed, step-by-step approach to setting up a RADIUS (Remote Authentication Dial-In User Service) server using FreeRADIUS, integrated with a Mikrotik router, Access Points, and a captive portal. The goal is to create a robust and scalable solution for WiFi client authentication and usage tracking.
Why Use FreeRADIUS and Mikrotik?
FreeRADIUS is one of the most popular and widely deployed RADIUS servers in the world. It is open-source, highly configurable, and supports a wide range of authentication methods. By running FreeRADIUS in a Docker container, you can achieve a high level of flexibility and portability, making it easier to manage and scale your network infrastructure.
Mikrotik routers are known for their powerful features and affordability. They can act as Network Access Servers (NAS), handling authentication and accounting requests, and integrating seamlessly with FreeRADIUS.
What You Will Learn
This guide will walk you through the entire process of setting up and configuring your network, including:
- System Communication Flow: Understanding the interaction between different components such as WiFi clients, access points, the Mikrotik router, FreeRADIUS server, captive portal, and MySQL database.
- FreeRADIUS Server Configuration: Detailed instructions on installing and setting up FreeRADIUS in a Docker container, configuring clients, user authentication, accounting, and integrating with a captive portal.
- Mikrotik Router Configuration: Steps to configure the Mikrotik router to use FreeRADIUS for authentication and accounting, and setting up the Hotspot feature for the captive portal.
- Troubleshooting Tips: Common issues and solutions to help you diagnose and resolve problems during the setup process.
Who Should Use This Guide?
This guide is intended for network administrators, IT professionals, and anyone with a basic understanding of networking concepts who wants to implement a secure and manageable WiFi network. Whether you are setting up a network for a small office, a large enterprise, or a public hotspot, this guide will provide you with the knowledge and tools you need to succeed.
By following this guide, you will be able to create a network that not only provides secure access to authorized users but also tracks and manages their usage effectively. This is crucial for maintaining network performance, ensuring compliance with organizational policies, and providing a positive user experience.
System Communication Flow
The system comprises of the following components and their interactions:
- WiFi Client: A device (e.g., smartphone, tablet, laptop etc) attempting to connect to the WiFi network.
- Access Points (APs): Handle wireless connections and forward traffic to the Mikrotik router.
- Mikrotik Router (NAS): Acts as the Network Access Server (NAS) and RADIUS client, managing authentication and accounting requests.
- FreeRADIUS Server: Runs in a Docker container, handling authentication, authorization, and accounting (AAA).
- Captive Portal: A web interface (likely Mikrotik’s built-in Hotspot portal) where users enter tokens for authentication.
- MySQL Database: Stores user credentials and accounting data for tracking usage.
Communication Flow
- Step 1: Client Connection: The WiFi client connects to the network via an AP (Access Point), which forwards the request to the Mikrotik router.
- Step 2: Captive Portal Redirection: If unauthenticated, the Mikrotik router redirects the client to the captive portal.
- Step 3: Token Submission: The user enters a token (username and password) in the portal, which the router sends to FreeRADIUS as an authentication request (Access-Request) over UDP port 1812.
- Step 4: Authentication: FreeRADIUS verifies the token against the MySQL database. If valid, it sends an Access-Accept message; otherwise, it sends an Access-Reject.
- Step 5: Network Access: Upon receiving Access-Accept, the Mikrotik router grants the client network access.
- Step 6: Accounting: The router sends Accounting-Start, interim updates, and Accounting-Stop packets to FreeRADIUS (port 1813) to track session data (e.g., data volume, time).
- Step 7: Quota Enforcement: FreeRADIUS uses the sqlcounter module to monitor usage against data or time limits, sending attributes like Mikrotik-Total-Limit to enforce quotas.
This flow ensures secure authentication and usage tracking, with the captive portal providing a user-friendly interface.
FreeRADIUS Server Configuration
FreeRADIUS will run in a Docker container alongside a MySQL container for storing user data and accounting records. The setup includes configuring clients, user authentication, accounting, and captive portal integration.
Step 1: Install and Set Up FreeRADIUS in a Container
Use Docker to deploy FreeRADIUS and MySQL, managed via a docker-compose.yml file for simplicity.
i) Create a Project Directory:
mkdir radius-project && cd radius-project
ii) Copy Default Configuration:
Run a temporary container to extract the default FreeRADIUS configuration:
docker run --name temp-radius -d freeradius/freeradius-server
docker cp temp-radius:/etc/raddb ./raddb
docker stop temp-radius && docker rm temp-radius
This creates a ./raddb directory with configuration files.
iii) Create a MySQL Data Directory:
mkdir mysql-data
iv) Create docker-compose.yml:
version: '3'
services:
radius:
image: freeradius/freeradius-server
ports:
- "1812:1812/udp"
- "1813:1813/udp"
volumes:
- ./raddb:/etc/raddb
depends_on:
- db
db:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=radius
- MYSQL_USER=radius
- MYSQL_PASSWORD=radiuspass
volumes:
- ./mysql-data:/var/lib/mysql
- ./raddb/mods-config/sql/main/mysql/schema.sql:/docker-entrypoint-initdb.d/schema.sql
Purpose: Defines two services: radius (FreeRADIUS) and db (MySQL). Maps ports 1812 (authentication) and 1813 (accounting), mounts the raddb directory, and initializes MySQL with the FreeRADIUS schema.
v) Start the Containers:
docker-compose up -d
Step 2: Configuring the Client (Mikrotik Router) in FreeRADIUS
This step defines the Mikrotik router as a RADIUS client in FreeRADIUS.
i) Edit ./raddb/clients.conf:
client mikrotik {
ipaddr = <Mikrotik_IP>
secret = <shared_secret>
}
- Parameters:
- ipaddr: The IP address of the Mikrotik router (e.g., 192.168.1.1).
- secret: A shared secret for secure communication (e.g., mysecret123).
- Purpose: Allows the Mikrotik router to send RADIUS requests to FreeRADIUS.
Step 3: Set Up User Authentication (Using Tokens)
Store user tokens (username and password) in the MySQL database for captive portal authentication.
i) Access MySQL:
docker exec -it radius-project_db_1 mysql -uradius -pradiuspass radius
ii) Add Users:
INSERT INTO radcheck (username, attribute, op, value) VALUES ('testuser', 'Cleartext-Password', ':=', 'testpassword');
- Parameters:
- username: The user’s identifier (e.g., testuser).
- attribute: Cleartext-Password for simple password storage.
- op: := for exact match.
- value: The password or token (e.g., testpassword).
- Purpose: Defines users who can authenticate via the captive portal.
Step 4: Implement Data Volume and Time-Based Accounting
Use the sqlcounter module to track and enforce data volume and time limits.
i) Create Data Volume Counter:
Create ./raddb/mods-available/dailycounter:
sqlcounter dailycounter {
counter_name = Daily-Transfer
check_name = Max-Daily-Transfer
reply_name = Mikrotik-Total-Limit
sql_module_instance = sql
key = User-Name
reset = daily
query = "SELECT SUM(acctinputoctets + acctoutputoctets) FROM radacct WHERE UserName='%{${key}}' AND UNIX_TIMESTAMP(acctstarttime) > UNIX_TIMESTAMP(CURDATE())"
}
- Parameters:
- counter_name: Internal name for the counter.
- check_name: Attribute to check against (set in radcheck).
- reply_name: Attribute sent to Mikrotik to enforce limits.
- reset: Resets the counter daily.
- query: SQL query to sum data usage for the current day.
- Purpose: Tracks daily data usage and sends limits to Mikrotik.
ii) Create Time-Based Counter:
Create ./raddb/mods-available/dailysession:
sqlcounter dailysession {
counter_name = Daily-Session
check_name = Max-Daily-Session
reply_name = Session-Timeout
sql_module_instance = sql
key = User-Name
reset = daily
query = "SELECT SUM(acctsessiontime) FROM radacct WHERE UserName='%{${key}}' AND UNIX_TIMESTAMP(acctstarttime) > UNIX_TIMESTAMP(CURDATE())"
}
- Parameters: Similar to dailycounter, but tracks session time in seconds.
- Purpose: Limits daily session time.
iii) Enable Counters:
ln -s ../mods-available/dailycounter ./raddb/mods-enabled/dailycounter
ln -s ../mods-available/dailysession ./raddb/mods-enabled/dailysession
iv) Update sites-enabled/default:
In ./raddb/sites-enabled/default, add to the authorize section:
dailycounter
dailysession
v) Set User Quotas:
INSERT INTO radcheck (username, attribute, op, value) VALUES ('testuser', 'Max-Daily-Transfer', ':=', '100000000'); # 100 MB
INSERT INTO radcheck (username, attribute, op, value) VALUES ('testuser', 'Max-Daily-Session', ':=', '3600'); # 1 hour
Step 5: Captive Portal Integration
The captive portal (assumed to be Mikrotik’s Hotspot) sends authentication requests using PAP, which FreeRADIUS supports by default. Ensure the sql module is enabled in the authorize section to authenticate users from the database. No additional FreeRADIUS configuration is needed unless a custom portal is used.
Step 6: Restart Containers
docker-compose down && docker-compose up -d
Mikrotik Router Configuration
In this stage, we are going to configure the Mikrotik router to use FreeRADIUS for authentication and accounting, and set up the Hotspot feature for the captive portal.
Step 1: Configure RADIUS Server
i) Access Mikrotik (via WinBox or CLI).
ii) Add RADIUS Server:
/radius
add address=<RADIUS_IP> secret=<shared_secret> service=hotspot
- Parameters:
- address: FreeRADIUS server IP (e.g., 192.168.1.100).
- secret: Must match the secret in clients.conf.
- service: Enables Hotspot authentication.
- Purpose: Allows the router to send RADIUS requests to FreeRADIUS.
Step 2: Configure Wireless Interface with Hotspot
i) Set Up Hotspot:
/ip hotspot
setup
- Follow prompts to select the wireless interface (e.g., wlan1).
- Choose defaults or customize as needed.
ii) Enable RADIUS in Hotspot Profile:
/ip hotspot profile
set [find name="hsprof1"] use-radius=yes radius-accounting=yes radius-interim-update=10m
- Parameters:
- Purpose: Configures the Hotspot to use FreeRADIUS and track usage.
Step 3: Captive Portal Setup
- Mikrotik’s Hotspot provides a built-in captive portal, accessible when users connect.
- Ensure the Hotspot server is active:
/ip hotspot server
set [find] enabled=yes
Purpose: Redirects unauthenticated users to the login page, which sends credentials to FreeRADIUS.
Step 4: Verify Accounting
- Check that accounting packets are sent to FreeRADIUS by monitoring logs or the radacct table in MySQL.
- Use radtest to verify authentication:
docker exec -it radius-project_radius_1 radtest testuser testpassword <RADIUS_IP> 0 <shared_secret>
Troubleshooting Tips
- FreeRADIUS Logs: Run FreeRADIUS in debug mode (docker-compose.yml with command: -X) to diagnose issues.
- Mikrotik Logs: Check /log print for RADIUS or Hotspot errors.
- Network Issues: Ensure firewall rules allow UDP ports 1812 and 1813.
- Database: Verify MySQL schema and user data with SELECT * FROM radcheck;.