This comprehensive guide covers implementing 802.1x authentication on UniFi Dream Machine and network infrastructure, including MAC-based authentication, user credential authentication, certificate-based authentication, and enterprise security configurations.
🎯 Overview
802.1x (Port-Based Network Access Control) provides enterprise-grade network security by requiring authentication before allowing network access. UniFi supports multiple authentication methods:
- MAC Address Authentication - Device-based authentication using hardware addresses
- User Credential Authentication - Username/password authentication via RADIUS
- Certificate-Based Authentication - PKI certificates for enhanced security
- Hybrid Approaches - Combining multiple authentication methods
Key Benefits
Benefit | Description | Use Cases |
---|---|---|
Network Segmentation | Automatic VLAN assignment based on authentication | Guest networks, IoT devices, employee access |
Enhanced Security | Prevents unauthorized network access | Corporate environments, secure facilities |
Centralized Management | Single point of authentication control | Large deployments, compliance requirements |
Audit Trail | Complete logging of network access attempts | Security monitoring, compliance reporting |
Dynamic VLAN Assignment | Automatic network isolation based on user/device | Role-based access, security zones |
🚀 Initial Setup and Configuration
Global 802.1x Configuration
Enable 802.1x Control
Navigate to Global Settings
- Go to Settings → Networks → Global Switch Settings
- Enable 802.1x Control
- Select RADIUS Profile (Default or custom)
- Configure Fallback VLAN for unauthenticated devices
Advanced Global Settings
802.1x Global Configuration: Authentication Timeout: 30 seconds Quiet Period: 60 seconds Maximum Requests: 2 Reauthentication Period: 3600 seconds (1 hour) Server Timeout: 30 seconds Supplicant Timeout: 30 seconds
RADIUS Server Configuration
Built-in RADIUS Server Setup
### UniFi Built-in RADIUS Configuration
1. **Access RADIUS Settings**
- Navigate to **Settings → Profiles → RADIUS**
- Select **Default** profile or create new profile
2. **RADIUS Profile Configuration**
- Enable **Wired Networks** (for switch ports)
- Enable **Wireless Networks** (for WiFi access points)
- Configure **Authentication Port**: 1812
- Configure **Accounting Port**: 1813
- Set **Shared Secret**: Use strong, unique password
3. **Advanced RADIUS Settings**
- **Interim Accounting Update**: 600 seconds
- **Session Timeout**: 86400 seconds (24 hours)
- **Idle Timeout**: 1800 seconds (30 minutes)
- **Called Station ID Format**: MAC address format
- **Calling Station ID Format**: MAC address format
External RADIUS Server Integration
External_RADIUS_Configuration:
Windows_NPS_Integration:
primary_server:
ip_address: "192.168.1.10"
auth_port: 1812
acct_port: 1813
shared_secret: "YourSecureSharedSecret123!"
timeout: 5
retries: 3
secondary_server:
ip_address: "192.168.1.11"
auth_port: 1812
acct_port: 1813
shared_secret: "YourSecureSharedSecret123!"
timeout: 5
retries: 3
FreeRADIUS_Integration:
configuration_steps:
- "Install FreeRADIUS on Linux server"
- "Configure clients.conf with UniFi equipment"
- "Set up user authentication (SQL/LDAP/files)"
- "Configure VLAN assignment attributes"
- "Test authentication with radtest utility"
🔐 MAC Address Authentication
Complete MAC Authentication Setup
WiFi MAC Authentication
### WiFi Network Configuration
1. **Configure WiFi Network for MAC Authentication**
- Go to **Settings → WiFi**
- Select target WiFi network
- Enable **RADIUS MAC Authentication**
- Select **MAC Address Format**: `aa:bb:cc:dd:ee:ff` (recommended)
- Set **Security Protocol**: `WPA3-Enterprise` or `WPA2-Enterprise`
- Configure **RADIUS Profile**: Select appropriate profile
2. **Advanced WiFi Settings**
- **Fast Roaming**: Enable for seamless handoffs
- **RADIUS Accounting**: Enable for session tracking
- **VLAN Override**: Allow RADIUS-assigned VLANs
- **Bandwidth Limits**: Configure per-user limits if needed
Wired MAC Authentication
### Switch Port Configuration
1. **Configure Switch Ports for 802.1x**
- Go to **Devices → Switches → Select Switch**
- Navigate to **Ports** tab
- Select port(s) to configure
- Enable **802.1x Control**
- Set **Operation**: `MAC-based Authentication`
2. **Port Authentication Settings**
- **Control Direction**: `Both` (recommended)
- **Guest VLAN**: VLAN for unauthenticated devices
- **Auth Fail VLAN**: VLAN for failed authentication
- **Idle Timeout**: 1800 seconds
- **Session Timeout**: 86400 seconds
MAC User Management
Adding MAC-Authenticated Devices
# PowerShell script for bulk MAC address import
function Add-UniFiMACUsers
{
param(
[Parameter(Mandatory)]
[string]$CsvFilePath, # CSV with columns: MACAddress, VLANID, Description
[string]$TunnelType = "13",
[string]$TunnelMediumType = "6"
)
# Read CSV file
$devices = Import-Csv -Path $CsvFilePath
foreach ($device in $devices)
{
$macAddress = $device.MACAddress.ToLower() -replace '[:-]', ''
$formattedMAC = $macAddress -replace '(.{2})(?=.)', '$1:'
Write-Host "Adding MAC user: $formattedMAC (VLAN: $($device.VLANID))" -ForegroundColor Green
# Note: This would require UniFi API integration
# Manual process shown here for reference
$userConfig = @{
Username = $formattedMAC
Password = $formattedMAC
VLANID = $device.VLANID
TunnelType = $TunnelType
TunnelMediumType = $TunnelMediumType
Description = $device.Description
}
Write-Host "User configuration: $($userConfig | ConvertTo-Json)" -ForegroundColor Cyan
}
}
# Example CSV format:
# MACAddress,VLANID,Description
# aa:bb:cc:dd:ee:ff,100,IoT Device - Smart Thermostat
# 11:22:33:44:55:66,200,Security Camera - Lobby
# Create CSV and run: Add-UniFiMACUsers -CsvFilePath "mac_devices.csv"
MAC Address Format Standardization
MAC_Address_Formats:
Colon_Separated: "aa:bb:cc:dd:ee:ff" # Recommended for UniFi
Hyphen_Separated: "aa-bb-cc-dd-ee-ff"
No_Separator: "aabbccddeeff"
Uppercase: "AA:BB:CC:DD:EE:FF"
Format_Conversion_Script: |
# Convert MAC address formats
function Convert-MACFormat {
param([string]$MAC, [string]$OutputFormat = "colon")
$cleanMAC = $MAC -replace '[:-]', ''
switch ($OutputFormat) {
"colon" { $cleanMAC -replace '(.{2})(?=.)', '$1:' }
"hyphen" { $cleanMAC -replace '(.{2})(?=.)', '$1-' }
"clean" { $cleanMAC }
"uppercase" { ($cleanMAC -replace '(.{2})(?=.)', '$1:').ToUpper() }
}
}
Device Categorization and VLAN Assignment
Automated VLAN Assignment Strategy
Device_VLAN_Strategy:
Corporate_Devices:
vlan_id: 10
description: "Employee laptops and workstations"
mac_patterns:
- "Dell_Inc": "VLAN 10"
- "Lenovo": "VLAN 10"
- "Apple": "VLAN 10"
IoT_Devices:
vlan_id: 100
description: "Internet of Things devices"
mac_patterns:
- "Nest_Labs": "VLAN 100"
- "Amazon": "VLAN 100"
- "Philips": "VLAN 100"
Security_Devices:
vlan_id: 200
description: "Security cameras and access control"
mac_patterns:
- "Axis": "VLAN 200"
- "Hikvision": "VLAN 200"
- "Ubiquiti": "VLAN 200"
Guest_Devices:
vlan_id: 500
description: "Guest and temporary devices"
authentication: "Captive portal or guest access"
👥 User-Based Authentication
User Credential Configuration
Standard User Setup
### Creating User Accounts
1. **Add RADIUS Users**
- Go to **Settings → Profiles → RADIUS**
- Select **Default** profile
- Click **Create New RADIUS User**
2. **User Configuration Fields**
- **Username**: User's network login ID
- **Password**: Secure password (8+ characters, mixed case, numbers, symbols)
- **VLAN ID**: `0` for dynamic assignment or specific VLAN
- **Tunnel Type**: Leave as `None` for standard users
- **Tunnel Medium Type**: Leave as `None` for standard users
- **Session Timeout**: 28800 seconds (8 hours)
- **Idle Timeout**: 1800 seconds (30 minutes)
3. **Advanced User Attributes**
- **Filter-Id**: Apply firewall rules
- **Framed-IP-Address**: Assign specific IP (if needed)
- **Calling-Station-Id**: MAC address restriction
- **NAS-Port-Type**: Connection type restriction
Bulk User Import
# PowerShell script for bulk user creation
function Import-UniFiUsers
{
param(
[Parameter(Mandatory)]
[string]$CsvFilePath, # CSV: Username,Password,VLANID,Department,Role
[string]$DefaultVLAN = "0",
[int]$DefaultSessionTimeout = 28800,
[int]$DefaultIdleTimeout = 1800
)
$users = Import-Csv -Path $CsvFilePath
$userConfigs = @()
foreach ($user in $users)
{
# Generate secure password if not provided
if (-not $user.Password)
{
$user.Password = Generate-SecurePassword -Length 12
}
$vlanId = if ($user.VLANID) { $user.VLANID } else { $DefaultVLAN }
$userConfig = [PSCustomObject]@{
Username = $user.Username
Password = $user.Password
VLANID = $vlanId
Department = $user.Department
Role = $user.Role
SessionTimeout = $DefaultSessionTimeout
IdleTimeout = $DefaultIdleTimeout
CreatedDate = Get-Date
}
$userConfigs += $userConfig
Write-Host "Prepared user: $($user.Username) (VLAN: $vlanId)" -ForegroundColor Green
}
# Export for manual import or API integration
$userConfigs | Export-Csv -Path "unifi_users_import.csv" -NoTypeInformation
Write-Host "User configurations exported to: unifi_users_import.csv" -ForegroundColor Cyan
return $userConfigs
}
function Generate-SecurePassword
{
param([int]$Length = 12)
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
$password = ""
for ($i = 0; $i -lt $Length; $i++)
{
$password += $chars[(Get-Random -Minimum 0 -Maximum $chars.Length)]
}
return $password
}
# Example usage:
# Import-UniFiUsers -CsvFilePath "employees.csv"
Dynamic VLAN Assignment
Group-Based VLAN Assignment
Dynamic_VLAN_Configuration:
User_Groups:
Executives:
vlan_id: 50
bandwidth_limit: "unlimited"
access_control: "full_access"
session_timeout: 43200 # 12 hours
Employees:
vlan_id: 10
bandwidth_limit: "50mbps"
access_control: "business_applications"
session_timeout: 28800 # 8 hours
Contractors:
vlan_id: 30
bandwidth_limit: "25mbps"
access_control: "limited_access"
session_timeout: 14400 # 4 hours
Guests:
vlan_id: 500
bandwidth_limit: "10mbps"
access_control: "internet_only"
session_timeout: 7200 # 2 hours
RADIUS_Attributes:
Tunnel-Type: "VLAN (13)"
Tunnel-Medium-Type: "IEEE-802 (6)"
Tunnel-Private-Group-ID: "VLAN_ID"
Session-Timeout: "seconds"
Idle-Timeout: "seconds"
Filter-Id: "firewall_rule_name"
🏆 Certificate-Based Authentication
PKI Infrastructure Setup
Certificate Authority Configuration
### Setting Up Certificate-Based Authentication
1. **Certificate Authority Setup**
- Use Windows Server CA, OpenSSL, or cloud PKI service
- Create root CA certificate
- Generate intermediate CA for device certificates
- Configure certificate templates for devices and users
2. **Device Certificate Generation**
```bash
# OpenSSL example for device certificate
# Generate private key
openssl genrsa -out device.key 2048
# Create certificate request
openssl req -new -key device.key -out device.csr \
-subj "/C=US/ST=State/L=City/O=Company/OU=IT/CN=device.company.com"
# Sign certificate with CA
openssl x509 -req -in device.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out device.crt -days 365 -extensions v3_req
# Create PKCS#12 bundle for device
openssl pkcs12 -export -out device.p12 -inkey device.key \
-in device.crt -certfile ca.crt
- UniFi Certificate Configuration
- Upload CA certificate to UniFi controller
- Configure certificate validation settings
- Set up certificate revocation checking (CRL/OCSP)
#### EAP-TLS Configuration
```yaml
EAP_TLS_Configuration:
WiFi_Network_Settings:
security_protocol: "WPA3-Enterprise"
eap_method: "EAP-TLS"
certificate_validation: "enabled"
ca_certificate: "upload_root_ca.crt"
Client_Configuration:
windows_client:
- "Install client certificate in user store"
- "Configure wireless profile with EAP-TLS"
- "Set server certificate validation"
- "Configure automatic connection"
android_client:
- "Install CA certificate in device"
- "Install client certificate (P12 format)"
- "Configure WiFi with 802.1x EAP-TLS"
- "Set identity and certificate selection"
ios_client:
- "Install certificates via Configuration Profile"
- "Use Apple Configurator or MDM solution"
- "Configure WiFi payload with EAP-TLS"
- "Set trust settings for CA certificate"
Certificate Lifecycle Management
Automated Certificate Deployment
# PowerShell script for certificate management
function Deploy-DeviceCertificates
{
param(
[Parameter(Mandatory)]
[string]$CertificateTemplateName,
[Parameter(Mandatory)]
[string]$DeviceListPath, # CSV with DeviceName, MACAddress, Department
[string]$CAServerName = "CA-SERVER-01",
[string]$OutputPath = ".\Certificates"
)
# Ensure output directory exists
if (-not (Test-Path $OutputPath))
{
New-Item -ItemType Directory -Path $OutputPath -Force
}
$devices = Import-Csv -Path $DeviceListPath
foreach ($device in $devices)
{
Write-Host "Processing device: $($device.DeviceName)" -ForegroundColor Green
try
{
# Request certificate from CA
$certRequest = @"
[NewRequest]
Subject = "CN=$($device.DeviceName),OU=$($device.Department),O=Company"
KeyLength = 2048
KeySpec = 1
KeyUsage = 0xA0
MachineKeySet = TRUE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = PKCS10
[RequestAttributes]
CertificateTemplate = "$CertificateTemplateName"
"@
$requestFile = "$OutputPath\$($device.DeviceName)_request.inf"
$certRequest | Out-File -FilePath $requestFile -Encoding ASCII
# Generate certificate request
& certreq.exe -new $requestFile "$OutputPath\$($device.DeviceName).req"
# Submit to CA and retrieve certificate
& certreq.exe -submit -config "$CAServerName\CA" "$OutputPath\$($device.DeviceName).req" "$OutputPath\$($device.DeviceName).cer"
# Install certificate
& certreq.exe -accept "$OutputPath\$($device.DeviceName).cer"
Write-Host "Certificate deployed for: $($device.DeviceName)" -ForegroundColor Cyan
# Log deployment
$logEntry = [PSCustomObject]@{
DeviceName = $device.DeviceName
MACAddress = $device.MACAddress
Department = $device.Department
CertificateIssued = Get-Date
SerialNumber = (Get-PfxCertificate "$OutputPath\$($device.DeviceName).cer").SerialNumber
}
$logEntry | Export-Csv -Path "$OutputPath\deployment_log.csv" -Append -NoTypeInformation
}
catch
{
Write-Error "Failed to deploy certificate for $($device.DeviceName): $($_.Exception.Message)"
}
}
}
# Certificate renewal monitoring
function Monitor-CertificateExpiration
{
param(
[int]$WarningDays = 30,
[int]$CriticalDays = 7,
[string]$LogPath = ".\certificate_expiration.log"
)
$certificates = Get-ChildItem -Path "Cert:\LocalMachine\My" | Where-Object { $_.EnhancedKeyUsageList -match "Client Authentication" }
$expiringCerts = @()
foreach ($cert in $certificates)
{
$daysUntilExpiry = ($cert.NotAfter - (Get-Date)).Days
if ($daysUntilExpiry -le $CriticalDays)
{
$severity = "CRITICAL"
}
elseif ($daysUntilExpiry -le $WarningDays)
{
$severity = "WARNING"
}
else
{
continue
}
$certInfo = [PSCustomObject]@{
Subject = $cert.Subject
Thumbprint = $cert.Thumbprint
ExpiryDate = $cert.NotAfter
DaysUntilExpiry = $daysUntilExpiry
Severity = $severity
CheckDate = Get-Date
}
$expiringCerts += $certInfo
Write-Host "$severity: Certificate expires in $daysUntilExpiry days - $($cert.Subject)" -ForegroundColor $(if ($severity -eq "CRITICAL") { "Red" } else { "Yellow" })
}
if ($expiringCerts.Count -gt 0)
{
$expiringCerts | Export-Csv -Path $LogPath -NoTypeInformation
return $expiringCerts
}
Write-Host "No certificates require immediate attention" -ForegroundColor Green
return $null
}
🔍 Monitoring and Troubleshooting
Authentication Monitoring
Real-time Authentication Monitoring
### UniFi Controller Monitoring
1. **Authentication Logs**
- Navigate to **System Settings → Logs**
- Filter by **Authentication** events
- Monitor success/failure rates
- Track VLAN assignments
2. **Key Metrics to Monitor**
- Authentication success rate (target: >95%)
- Average authentication time (target: <5 seconds)
- Failed authentication attempts
- RADIUS server response time
- Client device distribution across VLANs
3. **Alert Configuration**
- Set up email alerts for authentication failures
- Configure SNMP monitoring for RADIUS server health
- Monitor network utilization per VLAN
- Track unusual authentication patterns
Log Analysis Scripts
# PowerShell script for authentication log analysis
function Analyze-AuthenticationLogs
{
param(
[Parameter(Mandatory)]
[string]$LogFilePath,
[int]$HoursBack = 24,
[string]$OutputReport = "auth_analysis_$(Get-Date -Format 'yyyyMMdd_HHmm').html"
)
$cutoffTime = (Get-Date).AddHours(-$HoursBack)
# Parse authentication logs (adapt to your log format)
$logEntries = Get-Content $LogFilePath | ForEach-Object {
if ($_ -match "(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}).*Auth (Success|Failure).*User: (\S+).*MAC: ([\da-fA-F:]{17}).*VLAN: (\d+)")
{
[PSCustomObject]@{
Timestamp = [DateTime]$matches[1]
Result = $matches[2]
Username = $matches[3]
MACAddress = $matches[4]
VLAN = $matches[5]
}
}
} | Where-Object { $_.Timestamp -gt $cutoffTime }
# Calculate statistics
$totalAttempts = $logEntries.Count
$successfulAuth = ($logEntries | Where-Object { $_.Result -eq "Success" }).Count
$failedAuth = $totalAttempts - $successfulAuth
$successRate = if ($totalAttempts -gt 0) { [math]::Round(($successfulAuth / $totalAttempts) * 100, 2) } else { 0 }
# Top failed authentication sources
$topFailures = $logEntries | Where-Object { $_.Result -eq "Failure" } |
Group-Object MACAddress |
Sort-Object Count -Descending |
Select-Object -First 10 Name, Count
# VLAN distribution
$vlanDistribution = $logEntries | Where-Object { $_.Result -eq "Success" } |
Group-Object VLAN |
Sort-Object Count -Descending |
Select-Object Name, Count
# Hourly authentication pattern
$hourlyPattern = $logEntries | Group-Object { $_.Timestamp.Hour } |
Sort-Object Name |
Select-Object @{Name="Hour";Expression={$_.Name}}, Count
# Generate HTML report
$htmlReport = @"
<!DOCTYPE html>
<html>
<head>
<title>802.1x Authentication Analysis Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.summary { background: #f0f8ff; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
.metric { display: inline-block; margin: 10px; padding: 15px; border: 1px solid #ddd; border-radius: 5px; text-align: center; }
.success { color: #28a745; }
.failure { color: #dc3545; }
table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>802.1x Authentication Analysis Report</h1>
<p>Report Period: Last $HoursBack hours ($(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'))</p>
<div class="summary">
<div class="metric">
<h3>Total Attempts</h3>
<div style="font-size: 24px; font-weight: bold;">$totalAttempts</div>
</div>
<div class="metric">
<h3>Successful</h3>
<div style="font-size: 24px; font-weight: bold;" class="success">$successfulAuth</div>
</div>
<div class="metric">
<h3>Failed</h3>
<div style="font-size: 24px; font-weight: bold;" class="failure">$failedAuth</div>
</div>
<div class="metric">
<h3>Success Rate</h3>
<div style="font-size: 24px; font-weight: bold;">$successRate%</div>
</div>
</div>
<h2>Top Failed Authentication Sources</h2>
<table>
<tr><th>MAC Address</th><th>Failed Attempts</th></tr>
$(foreach ($failure in $topFailures) { "<tr><td>$($failure.Name)</td><td>$($failure.Count)</td></tr>" })
</table>
<h2>VLAN Distribution (Successful Authentications)</h2>
<table>
<tr><th>VLAN ID</th><th>Authentication Count</th></tr>
$(foreach ($vlan in $vlanDistribution) { "<tr><td>$($vlan.Name)</td><td>$($vlan.Count)</td></tr>" })
</table>
<h2>Hourly Authentication Pattern</h2>
<table>
<tr><th>Hour (24-hour format)</th><th>Authentication Count</th></tr>
$(foreach ($hour in $hourlyPattern) { "<tr><td>$($hour.Hour):00</td><td>$($hour.Count)</td></tr>" })
</table>
</body>
</html>
"@
$htmlReport | Out-File -FilePath $OutputReport -Encoding UTF8
Write-Host "Authentication analysis report generated: $OutputReport" -ForegroundColor Green
# Return summary for further processing
return [PSCustomObject]@{
TotalAttempts = $totalAttempts
SuccessfulAuth = $successfulAuth
FailedAuth = $failedAuth
SuccessRate = $successRate
TopFailures = $topFailures
VLANDistribution = $vlanDistribution
ReportPath = $OutputReport
}
}
Common Issues and Solutions
Troubleshooting Framework
Common_802.1x_Issues:
Authentication_Failures:
symptoms:
- "Devices cannot connect to network"
- "Authentication timeouts"
- "Incorrect VLAN assignment"
causes:
- "Incorrect MAC address format"
- "RADIUS server connectivity issues"
- "Shared secret mismatch"
- "Certificate validation failures"
- "Network switch configuration errors"
solutions:
- "Verify MAC address format consistency"
- "Test RADIUS server connectivity with radtest"
- "Check shared secrets on all devices"
- "Validate certificate chain and CRL"
- "Review switch port 802.1x configuration"
Performance_Issues:
symptoms:
- "Slow authentication times"
- "Random disconnections"
- "High CPU usage on RADIUS server"
causes:
- "RADIUS server overload"
- "Network latency issues"
- "Insufficient switch resources"
- "Frequent reauthentication"
solutions:
- "Load balance RADIUS servers"
- "Optimize network paths to RADIUS"
- "Upgrade switch firmware"
- "Increase reauthentication timers"
VLAN_Assignment_Problems:
symptoms:
- "Devices in wrong VLAN"
- "No network access after authentication"
- "Inconsistent VLAN assignments"
causes:
- "Incorrect RADIUS attributes"
- "VLAN not configured on switches"
- "Trunk port configuration issues"
- "RADIUS profile misconfiguration"
solutions:
- "Verify Tunnel-Private-Group-ID attribute"
- "Ensure VLAN exists on all switches"
- "Check trunk port VLAN membership"
- "Review RADIUS profile VLAN settings"
Diagnostic Tools and Scripts
#!/bin/bash
# 802.1x Network Diagnostic Script
echo "=== UniFi 802.1x Network Diagnostics ==="
echo "========================================"
# Function to test RADIUS connectivity
test_radius_connectivity() {
local radius_server=$1
local shared_secret=$2
local username=$3
local password=$4
echo "Testing RADIUS connectivity to $radius_server..."
if command -v radtest &> /dev/null; then
radtest "$username" "$password" "$radius_server" 1812 "$shared_secret"
else
echo "radtest not available. Install freeradius-utils for testing."
echo "Manual test: telnet $radius_server 1812"
fi
}
# Function to check MAC address format
check_mac_format() {
local mac_address=$1
echo "Checking MAC address format: $mac_address"
# Check for standard formats
if [[ $mac_address =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
echo "✓ Valid colon-separated format"
elif [[ $mac_address =~ ^([0-9A-Fa-f]{2}-){5}[0-9A-Fa-f]{2}$ ]]; then
echo "✓ Valid hyphen-separated format"
elif [[ $mac_address =~ ^[0-9A-Fa-f]{12}$ ]]; then
echo "✓ Valid no-separator format"
else
echo "✗ Invalid MAC address format"
echo "Expected formats: aa:bb:cc:dd:ee:ff, aa-bb-cc-dd-ee-ff, or aabbccddeeff"
fi
}
# Function to test network connectivity
test_network_connectivity() {
local target_ip=$1
local vlan_id=$2
echo "Testing network connectivity to $target_ip (VLAN $vlan_id)..."
# Ping test
if ping -c 3 "$target_ip" &> /dev/null; then
echo "✓ Ping successful to $target_ip"
else
echo "✗ Ping failed to $target_ip"
fi
# DNS resolution test
if nslookup google.com &> /dev/null; then
echo "✓ DNS resolution working"
else
echo "✗ DNS resolution failed"
fi
}
# Function to check certificate validity
check_certificate_validity() {
local cert_file=$1
if [[ -f "$cert_file" ]]; then
echo "Checking certificate: $cert_file"
# Check expiration
expiry_date=$(openssl x509 -in "$cert_file" -noout -enddate | cut -d= -f2)
echo "Certificate expires: $expiry_date"
# Check if certificate is still valid
if openssl x509 -in "$cert_file" -noout -checkend 86400; then
echo "✓ Certificate is valid for at least 24 hours"
else
echo "✗ Certificate expires within 24 hours"
fi
# Display certificate details
echo "Certificate details:"
openssl x509 -in "$cert_file" -noout -subject -issuer
else
echo "Certificate file not found: $cert_file"
fi
}
# Main diagnostic routine
main() {
echo "Starting 802.1x diagnostics..."
echo ""
# Example usage - customize for your environment
RADIUS_SERVER="192.168.1.10"
SHARED_SECRET="YourSharedSecret"
TEST_USERNAME="testuser"
TEST_PASSWORD="testpass"
TEST_MAC="aa:bb:cc:dd:ee:ff"
GATEWAY_IP="192.168.1.1"
VLAN_ID="100"
CERT_FILE="/path/to/client.crt"
echo "--- RADIUS Connectivity Test ---"
test_radius_connectivity "$RADIUS_SERVER" "$SHARED_SECRET" "$TEST_USERNAME" "$TEST_PASSWORD"
echo ""
echo "--- MAC Address Format Check ---"
check_mac_format "$TEST_MAC"
echo ""
echo "--- Network Connectivity Test ---"
test_network_connectivity "$GATEWAY_IP" "$VLAN_ID"
echo ""
echo "--- Certificate Validity Check ---"
check_certificate_validity "$CERT_FILE"
echo ""
echo "--- System Information ---"
echo "Current IP: $(hostname -I | awk '{print $1}')"
echo "Current user: $(whoami)"
echo "Network interfaces:"
ip addr show | grep -E "inet " | awk '{print $2, $NF}'
echo ""
echo "Diagnostics completed!"
}
# Run main function
main "$@"
📊 Performance Optimization
Scalability Best Practices
Large Deployment Optimization
Scalability_Configuration:
RADIUS_Server_Optimization:
hardware_requirements:
cpu_cores: "4+ cores for 1000+ concurrent users"
memory: "8GB+ RAM for user database"
storage: "SSD storage for optimal performance"
network: "Gigabit network interface"
software_tuning:
max_requests: 16384
cleanup_delay: 5
lifetime: 30
max_request_time: 30
hostname_lookups: "no"
allow_core_dumps: "no"
database_optimization:
connection_pooling: "enabled"
query_cache: "enabled"
index_optimization: "user lookups, MAC addresses"
regular_maintenance: "weekly REINDEX"
Network_Switch_Optimization:
port_configuration:
authentication_timeout: 30
quiet_period: 60
server_timeout: 30
supplicant_timeout: 30
max_req: 2
performance_tuning:
enable_fast_start: true
optimize_cpu_usage: true
reduce_logging_verbosity: true
implement_rate_limiting: true
Load Balancing Strategies
### RADIUS Load Balancing
1. **Multiple RADIUS Servers**
```yaml
Primary_RADIUS_Configuration:
server_1:
ip: "192.168.1.10"
priority: 1
weight: 100
server_2:
ip: "192.168.1.11"
priority: 2
weight: 100
server_3:
ip: "192.168.1.12"
priority: 3
weight: 50
Health Monitoring
- Implement RADIUS server health checks
- Automatic failover to secondary servers
- Load distribution based on response time
- Regular backup and synchronization
Geographic Distribution
- Deploy RADIUS servers in multiple locations
- Configure site-local authentication
- Implement WAN link failover
- Optimize authentication paths
## 🛡️ **Security Best Practices**
### Advanced Security Configuration
#### Comprehensive Security Framework
```yaml
Security_Best_Practices:
Authentication_Security:
password_policies:
minimum_length: 12
complexity_requirements: "uppercase, lowercase, numbers, symbols"
password_history: 12
lockout_threshold: 5
lockout_duration: 30 # minutes
certificate_security:
key_length: 2048 # minimum
certificate_lifetime: 365 # days
crl_checking: "enabled"
ocsp_validation: "enabled"
certificate_pinning: "recommended"
network_security:
shared_secret_length: 32 # characters
encryption_protocols: ["AES-256", "TLS 1.3"]
disable_weak_ciphers: true
implement_perfect_forward_secrecy: true
Access_Control:
vlan_segmentation:
isolate_device_types: true
implement_micro_segmentation: true
restrict_inter_vlan_routing: true
apply_firewall_rules: true
time_based_restrictions:
business_hours_only: "optional"
location_based_access: "GPS/IP geofencing"
device_compliance_checking: true
regular_access_reviews: "quarterly"
Monitoring_and_Logging:
comprehensive_logging:
authentication_attempts: "all"
authorization_decisions: "all"
administrative_actions: "all"
system_events: "security-relevant"
security_monitoring:
anomaly_detection: "enabled"
brute_force_detection: "enabled"
unusual_location_alerts: "enabled"
compliance_reporting: "monthly"
Threat Detection and Response
# Advanced security monitoring script
function Monitor-AuthenticationThreats
{
param(
[int]$BruteForceThreshold = 10,
[int]$TimeWindowMinutes = 15,
[string]$AlertEmail = "security@company.com",
[string]$LogPath = ".\security_alerts.log"
)
$endTime = Get-Date
$startTime = $endTime.AddMinutes(-$TimeWindowMinutes)
# Simulated log analysis (adapt to your log source)
$recentFailures = @(
# This would come from actual authentication logs
# Get-EventLog or Import-Csv depending on log format
)
# Detect brute force attacks
$bruteForceAttacks = $recentFailures |
Group-Object SourceIP |
Where-Object { $_.Count -ge $BruteForceThreshold } |
ForEach-Object {
[PSCustomObject]@{
SourceIP = $_.Name
AttemptCount = $_.Count
FirstAttempt = ($_.Group | Sort-Object Timestamp | Select-Object -First 1).Timestamp
LastAttempt = ($_.Group | Sort-Object Timestamp | Select-Object -Last 1).Timestamp
ThreatType = "Brute Force Attack"
Severity = "High"
}
}
# Detect unusual authentication patterns
$unusualPatterns = $recentFailures |
Group-Object { $_.Username } |
Where-Object {
$userFailures = $_.Group
$uniqueIPs = ($userFailures | Select-Object -Unique SourceIP).Count
$uniqueIPs -gt 3 # Same user from multiple IPs
} |
ForEach-Object {
[PSCustomObject]@{
Username = $_.Name
UniqueIPs = ($_.Group | Select-Object -Unique SourceIP).Count
AttemptCount = $_.Count
ThreatType = "Distributed Authentication Attempt"
Severity = "Medium"
}
}
# Combine all threats
$allThreats = $bruteForceAttacks + $unusualPatterns
if ($allThreats.Count -gt 0)
{
Write-Host "SECURITY ALERT: $($allThreats.Count) threat(s) detected!" -ForegroundColor Red
foreach ($threat in $allThreats)
{
$alertMessage = "THREAT DETECTED: $($threat.ThreatType) - Severity: $($threat.Severity)"
Write-Host $alertMessage -ForegroundColor Red
# Log the threat
$logEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - $alertMessage"
$logEntry | Add-Content -Path $LogPath
# Send email alert (implement email sending)
# Send-MailMessage -To $AlertEmail -Subject "802.1x Security Alert" -Body $alertMessage
}
return $allThreats
}
else
{
Write-Host "No security threats detected in the last $TimeWindowMinutes minutes" -ForegroundColor Green
return $null
}
}
# Automated threat response
function Invoke-ThreatResponse
{
param(
[Parameter(Mandatory)]
[object[]]$Threats,
[switch]$AutoBlock,
[int]$BlockDurationHours = 24
)
foreach ($threat in $Threats)
{
Write-Host "Responding to threat: $($threat.ThreatType)" -ForegroundColor Yellow
switch ($threat.ThreatType)
{
"Brute Force Attack"
{
if ($AutoBlock)
{
# Block source IP (implement firewall rule addition)
Write-Host "AUTO-BLOCKING IP: $($threat.SourceIP) for $BlockDurationHours hours" -ForegroundColor Red
# Add-FirewallRule -Action Block -RemoteAddress $threat.SourceIP -Duration $BlockDurationHours
}
# Increase authentication delay for this IP
# Set-AuthenticationDelay -SourceIP $threat.SourceIP -DelaySeconds 30
}
"Distributed Authentication Attempt"
{
# Temporarily disable user account
Write-Host "DISABLING USER ACCOUNT: $($threat.Username)" -ForegroundColor Yellow
# Disable-ADAccount -Identity $threat.Username
# Send notification to user and admin
# Send-SecurityNotification -Username $threat.Username -ThreatType $threat.ThreatType
}
}
}
}
# Example usage:
# $threats = Monitor-AuthenticationThreats -BruteForceThreshold 5 -TimeWindowMinutes 10
# if ($threats) { Invoke-ThreatResponse -Threats $threats -AutoBlock }
📚 Documentation and Compliance
Configuration Documentation
Network Architecture Documentation
Network_Architecture_Documentation:
Physical_Infrastructure:
unifi_devices:
dream_machine: "UDM-Pro (192.168.1.1)"
switches:
- "USW-24-POE (192.168.1.10)"
- "USW-48-POE (192.168.1.11)"
access_points:
- "UAP-AC-HD (192.168.1.20-30)"
- "UAP-AC-Lite (192.168.1.31-40)"
radius_infrastructure:
primary_server: "RADIUS-01 (192.168.1.50)"
secondary_server: "RADIUS-02 (192.168.1.51)"
certificate_authority: "CA-01 (192.168.1.60)"
Logical_Network_Design:
vlans:
management_vlan: 1
corporate_vlan: 10
guest_vlan: 500
iot_vlan: 100
security_vlan: 200
dmz_vlan: 300
authentication_flows:
wired_devices: "MAC authentication → VLAN assignment"
wifi_users: "Username/password → dynamic VLAN"
certificates: "EAP-TLS → high-security VLAN"
guests: "Captive portal → guest VLAN"
Security_Policies:
access_control:
inter_vlan_routing: "Controlled by firewall rules"
internet_access: "Filtered by content policy"
admin_access: "Certificate-based only"
guest_access: "Isolated with bandwidth limits"
compliance_requirements:
data_retention: "Authentication logs kept for 1 year"
audit_frequency: "Quarterly security reviews"
certificate_renewal: "Annual certificate refresh"
password_rotation: "90-day password policy"
Compliance Reporting
Automated Compliance Reports
# Comprehensive compliance reporting script
function Generate-ComplianceReport
{
param(
[Parameter(Mandatory)]
[string]$ReportPeriod, # "Monthly", "Quarterly", "Annual"
[string]$OutputPath = ".\Compliance_Reports",
[string[]]$RequiredCompliance = @("SOX", "HIPAA", "PCI-DSS", "ISO27001")
)
$reportDate = Get-Date
$reportName = "802.1x_Compliance_Report_$($ReportPeriod)_$(Get-Date -Format 'yyyyMMdd').html"
Write-Host "Generating $ReportPeriod compliance report..." -ForegroundColor Cyan
# Collect compliance data
$complianceData = @{
AuthenticationMetrics = Get-AuthenticationMetrics -Period $ReportPeriod
SecurityIncidents = Get-SecurityIncidents -Period $ReportPeriod
CertificateStatus = Get-CertificateStatus
UserAccessReview = Get-UserAccessReview -Period $ReportPeriod
SystemConfiguration = Get-SystemConfiguration
AuditTrail = Get-AuditTrail -Period $ReportPeriod
}
# Generate HTML report
$htmlReport = @"
<!DOCTYPE html>
<html>
<head>
<title>802.1x Network Authentication Compliance Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background: #2c3e50; color: white; padding: 20px; text-align: center; }
.section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
.compliant { color: #27ae60; font-weight: bold; }
.non-compliant { color: #e74c3c; font-weight: bold; }
.warning { color: #f39c12; font-weight: bold; }
table { width: 100%; border-collapse: collapse; margin: 10px 0; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f8f9fa; }
.metric { display: inline-block; margin: 10px; padding: 15px; border: 1px solid #ddd; border-radius: 5px; text-align: center; min-width: 120px; }
</style>
</head>
<body>
<div class="header">
<h1>802.1x Network Authentication Compliance Report</h1>
<p>$ReportPeriod Report - Generated: $($reportDate.ToString('yyyy-MM-dd HH:mm:ss'))</p>
</div>
<div class="section">
<h2>Executive Summary</h2>
<div class="metric">
<h4>Overall Compliance Score</h4>
<div style="font-size: 24px;" class="compliant">92%</div>
</div>
<div class="metric">
<h4>Security Incidents</h4>
<div style="font-size: 24px;">$($complianceData.SecurityIncidents.Count)</div>
</div>
<div class="metric">
<h4>Authentication Success Rate</h4>
<div style="font-size: 24px;" class="compliant">$($complianceData.AuthenticationMetrics.SuccessRate)%</div>
</div>
<div class="metric">
<h4>Certificate Compliance</h4>
<div style="font-size: 24px;" class="compliant">98%</div>
</div>
</div>
<div class="section">
<h2>Authentication Metrics</h2>
<table>
<tr><th>Metric</th><th>Value</th><th>Target</th><th>Status</th></tr>
<tr><td>Total Authentication Attempts</td><td>$($complianceData.AuthenticationMetrics.TotalAttempts)</td><td>-</td><td>-</td></tr>
<tr><td>Success Rate</td><td>$($complianceData.AuthenticationMetrics.SuccessRate)%</td><td>>95%</td><td class="compliant">COMPLIANT</td></tr>
<tr><td>Average Response Time</td><td>$($complianceData.AuthenticationMetrics.AvgResponseTime)ms</td><td><5000ms</td><td class="compliant">COMPLIANT</td></tr>
<tr><td>Failed Attempts</td><td>$($complianceData.AuthenticationMetrics.FailedAttempts)</td><td><5%</td><td class="compliant">COMPLIANT</td></tr>
</table>
</div>
<div class="section">
<h2>Security Incidents</h2>
$(if ($complianceData.SecurityIncidents.Count -eq 0) {
"<p class='compliant'>No security incidents reported during this period.</p>"
} else {
"<table><tr><th>Date</th><th>Type</th><th>Severity</th><th>Status</th><th>Resolution</th></tr>"
foreach ($incident in $complianceData.SecurityIncidents) {
"<tr><td>$($incident.Date)</td><td>$($incident.Type)</td><td>$($incident.Severity)</td><td>$($incident.Status)</td><td>$($incident.Resolution)</td></tr>"
}
"</table>"
})
</div>
<div class="section">
<h2>Certificate Management</h2>
<table>
<tr><th>Certificate Type</th><th>Total Count</th><th>Valid</th><th>Expiring Soon</th><th>Expired</th></tr>
<tr><td>Root CA</td><td>1</td><td class="compliant">1</td><td>0</td><td>0</td></tr>
<tr><td>Device Certificates</td><td>$($complianceData.CertificateStatus.DeviceCerts.Total)</td><td class="compliant">$($complianceData.CertificateStatus.DeviceCerts.Valid)</td><td class="warning">$($complianceData.CertificateStatus.DeviceCerts.ExpiringSoon)</td><td class="non-compliant">$($complianceData.CertificateStatus.DeviceCerts.Expired)</td></tr>
<tr><td>User Certificates</td><td>$($complianceData.CertificateStatus.UserCerts.Total)</td><td class="compliant">$($complianceData.CertificateStatus.UserCerts.Valid)</td><td class="warning">$($complianceData.CertificateStatus.UserCerts.ExpiringSoon)</td><td class="non-compliant">$($complianceData.CertificateStatus.UserCerts.Expired)</td></tr>
</table>
</div>
<div class="section">
<h2>Compliance Framework Status</h2>
<table>
<tr><th>Framework</th><th>Requirements Met</th><th>Status</th><th>Action Required</th></tr>
$(foreach ($framework in $RequiredCompliance) {
$status = Get-ComplianceFrameworkStatus -Framework $framework
"<tr><td>$framework</td><td>$($status.RequirementsMet)/$($status.TotalRequirements)</td><td class='$($status.StatusClass)'>$($status.Status)</td><td>$($status.ActionRequired)</td></tr>"
})
</table>
</div>
<div class="section">
<h2>Recommendations</h2>
<ul>
<li>Continue monitoring authentication success rates to maintain >95% target</li>
<li>Schedule certificate renewal for certificates expiring within 30 days</li>
<li>Review and update user access permissions quarterly</li>
<li>Implement additional monitoring for anomalous authentication patterns</li>
<li>Conduct annual penetration testing of 802.1x infrastructure</li>
</ul>
</div>
<div class="section">
<h2>Report Generation Details</h2>
<p><strong>Generated by:</strong> 802.1x Compliance Monitoring System</p>
<p><strong>Report Period:</strong> $ReportPeriod</p>
<p><strong>Data Sources:</strong> UniFi Controller, RADIUS Server Logs, Certificate Store</p>
<p><strong>Next Report Due:</strong> $(Get-NextReportDate -Current $reportDate -Period $ReportPeriod)</p>
</div>
</body>
</html>
"@
# Ensure output directory exists
if (-not (Test-Path $OutputPath))
{
New-Item -ItemType Directory -Path $OutputPath -Force
}
$reportFilePath = Join-Path $OutputPath $reportName
$htmlReport | Out-File -FilePath $reportFilePath -Encoding UTF8
Write-Host "Compliance report generated: $reportFilePath" -ForegroundColor Green
return @{
ReportPath = $reportFilePath
ComplianceScore = 92 # Calculate actual score
SecurityIncidents = $complianceData.SecurityIncidents.Count
CertificateIssues = $complianceData.CertificateStatus.DeviceCerts.Expired + $complianceData.CertificateStatus.UserCerts.Expired
}
}
# Helper functions for compliance data collection
function Get-AuthenticationMetrics
{
param([string]$Period)
# Implement actual metrics collection
return @{
TotalAttempts = 15420
SuccessRate = 96.8
AvgResponseTime = 1250
FailedAttempts = 494
}
}
function Get-SecurityIncidents
{
param([string]$Period)
# Implement actual incident collection
return @() # No incidents
}
function Get-CertificateStatus
{
# Implement actual certificate status check
return @{
DeviceCerts = @{ Total = 125; Valid = 122; ExpiringSoon = 3; Expired = 0 }
UserCerts = @{ Total = 450; Valid = 448; ExpiringSoon = 2; Expired = 0 }
}
}
function Get-ComplianceFrameworkStatus
{
param([string]$Framework)
# Implement framework-specific compliance checks
return @{
RequirementsMet = 28
TotalRequirements = 30
Status = "COMPLIANT"
StatusClass = "compliant"
ActionRequired = "Monitor certificate renewals"
}
}
# Generate compliance report
# Generate-ComplianceReport -ReportPeriod "Monthly"