Overview

This article provides a detailed walkthrough for setting up a captive portal on pfSense that utilizes FreeRADIUS for authentication and MySQL for user data storage. This setup is ideal for managing guest access to your network with specific limitations.

Prerequisites

Before you begin, ensure you have the following components installed:

  • pfSense: The firewall and router software.
  • FreeRADIUS: For handling authentication requests.
  • MySQL: For storing user credentials.
  • Apache: To serve the captive portal web pages.

Configuration Steps

Step 1: Install Required Packages

First, install FreeRADIUS and MySQL on your pfSense system. You can do this via the package manager:

pkg update
pkg install freeradius mysql56-server php56-mysql

Step 2: Set Up MySQL Database

Next, configure your MySQL database to store user information. Connect to MySQL and create a database named radius:

mysql -u root -p
CREATE DATABASE radius;
CREATE USER 'radius_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON radius.* TO 'radius_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Step 3: Create Required Tables

Import the FreeRADIUS schema into your newly created database. This schema includes tables such as radcheck, radreply, and others necessary for user authentication:

USE radius;
CREATE TABLE radcheck (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(64) NOT NULL,
  attribute VARCHAR(64) NOT NULL,
  op VARCHAR(2) NOT NULL,
  value VARCHAR(253) NOT NULL
);

Step 4: Configure FreeRADIUS

Edit the FreeRADIUS configuration files to connect to your MySQL database. Update the sql.conf file to include your database credentials:

driver = "mysql"
server = "localhost"
database = "radius"
username = "radius_user"
password = "your_password"

Step 5: Create the Captive Portal Pages

In your web server directory (e.g., /var/www/html), create the necessary PHP files for the captive portal:

  • login.php: The registration page where users enter their details.
  • login_success.php: The page users see after successful login.
  • check_login.php: The script that validates user credentials against the MySQL database.

Here’s a snippet for check_login.php:

$host = "localhost";
$username = "radius_user";
$password = "your_password";
db_name = "radius";

// Connect to the database
$conn = new mysqli($host, $username, $password, $db_name);
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

Step 6: Implement Session and Bandwidth Limitations

To enforce session limits (e.g., 3 hours) and bandwidth restrictions (e.g., 512 Kbps), configure these settings in the FreeRADIUS configuration files. You can set session timeouts in the radreply table and bandwidth limits in the radgroupreply table.

Conclusion

By following these steps, you will have a functional captive portal that directs users to a registration page upon connecting to your guest SSID. Users will be authenticated via FreeRADIUS and their data stored in MySQL, allowing for effective management of network access.

Difficulty Level

This setup is considered intermediate due to the requirement of understanding networking concepts and basic database management.