Table of Contents

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

  1. 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
  2. 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
  1. 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
  1. Health Monitoring

    • Implement RADIUS server health checks
    • Automatic failover to secondary servers
    • Load distribution based on response time
    • Regular backup and synchronization
  2. 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"

📖 Additional Resources

Back to UniFi Documentation | Back to Networking Home