Multiple router in Multi-Location

This is one of the most powerful features of centralized RADIUS authentication.

Key Concept

┌─────────────────────────────────────────────────────────────────┐
│  Different NAS devices (routers) = Different SECRETS            │
│  Same RADCHECK users = Work on ALL routers                      │
└─────────────────────────────────────────────────────────────────┘

Visual Example

                    ┌──────────────────────┐
                    │  RADIUS SERVER       │
                    │  (192.168.0.100)     │
                    │                      │
                    │  User Database:      │
                    │  ┌────────────────┐  │
                    │  │  john / Pass1  │  │
                    │  │  jane / Pass2  │  │
                    │  │  admin / Pass3 │  │
                    │  └────────────────┘  │
                    └──────────────────────┘
                             ▲
                ┌────────────┼────────────┐
                │            │            │
        Secret: "ABC123"     │    Secret: "XYZ789"
                │            │            │
    ┌───────────▼──┐    ┌───▼──────────┐ ┌────▼─────────┐
    │ Router A     │    │ Router B     │ │ Router C     │
    │ 192.168.1.1  │    │ 192.168.2.1  │ │ 192.168.3.1  │
    │ (Branch 1)   │    │ (Branch 2)   │ │ (Branch 3)   │
    └──────────────┘    └──────────────┘ └──────────────┘
         ▲                   ▲                 ▲
         │                   │                 │
    User: john          User: john        User: admin
    Pass: Pass1         Pass: Pass1       Pass: Pass3
         ✓                   ✓                 ✓
    SUCCESS!            SUCCESS!          SUCCESS!

Real-World Example

-- Setup NAS table with different secrets per location
INSERT INTO nas (nasname, shortname, type, secret, description) VALUES
('192.168.1.1', 'bangkok-office', 'mikrotik', 'Bangkok@Secret2025', 'Bangkok Branch'),
('192.168.2.1', 'chiangmai-office', 'mikrotik', 'ChiangMai@Secret2025', 'Chiang Mai Branch'),
('192.168.3.1', 'phuket-office', 'mikrotik', 'Phuket@Secret2025', 'Phuket Branch'),
('192.168.4.1', 'pattaya-office', 'mikrotik', 'Pattaya@Secret2025', 'Pattaya Branch');

-- Create ONE user that works on ALL routers
INSERT INTO radcheck (username, attribute, op, value) VALUES
('john_admin', 'Cleartext-Password', ':=', 'Admin@Pass123');

INSERT INTO radusergroup (username, groupname, priority) VALUES
('john_admin', 'admin_users', 1);

INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES
('admin_users', 'Mikrotik-Rate-Limit', ':=', '50M/50M'),
('admin_users', 'Session-Timeout', ':=', '86400');

Result:

  • User john_admin can login from Bangkok router (secret: Bangkok@Secret2025)
  • User john_admin can login from Chiang Mai router (secret: ChiangMai@Secret2025)
  • User john_admin can login from Phuket router (secret: Phuket@Secret2025)
  • User john_admin can login from Pattaya router (secret: Pattaya@Secret2025)

Same username/password everywhere!

Complete Multi-Location Example

USE radius;

-- ============================================
-- STEP 1: Setup NAS devices (different secrets)
-- ============================================
DELETE FROM nas;

INSERT INTO nas (nasname, shortname, type, secret, description) VALUES
-- Head Office
('10.10.1.1', 'hq-router', 'mikrotik', 'HQ@Secure!2025', 'Head Office Router'),

-- Regional Offices
('10.20.1.1', 'region1-router', 'mikrotik', 'Region1@Secure!2025', 'Region 1 Office'),
('10.30.1.1', 'region2-router', 'mikrotik', 'Region2@Secure!2025', 'Region 2 Office'),

-- Branches
('10.40.1.1', 'branch1-router', 'mikrotik', 'Branch1@Secure!2025', 'Branch 1'),
('10.40.2.1', 'branch2-router', 'mikrotik', 'Branch2@Secure!2025', 'Branch 2'),
('10.40.3.1', 'branch3-router', 'mikrotik', 'Branch3@Secure!2025', 'Branch 3'),

-- Hotels
('172.16.1.1', 'hotel-bangkok', 'mikrotik', 'HotelBKK@2025', 'Hotel Bangkok'),
('172.16.2.1', 'hotel-phuket', 'mikrotik', 'HotelPhuket@2025', 'Hotel Phuket'),

-- Cafes
('172.17.1.1', 'cafe-central', 'mikrotik', 'CafeCentral@2025', 'Cafe Central Plaza'),
('172.17.2.1', 'cafe-airport', 'mikrotik', 'CafeAirport@2025', 'Cafe Airport');

-- ============================================
-- STEP 2: Create user groups
-- ============================================
DELETE FROM radgroupreply WHERE groupname IN ('company_admin', 'company_staff', 'hotel_guest', 'cafe_customer');
DELETE FROM radgroupcheck WHERE groupname IN ('company_admin', 'company_staff', 'hotel_guest', 'cafe_customer');

-- Admin users (work everywhere)
INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES
('company_admin', 'Mikrotik-Rate-Limit', ':=', '100M/100M'),
('company_admin', 'Session-Timeout', ':=', '86400'),
('company_admin', 'Acct-Interim-Interval', ':=', '300');

INSERT INTO radgroupcheck (groupname, attribute, op, value) VALUES
('company_admin', 'Simultaneous-Use', ':=', '10');

-- Staff users (work at all company locations)
INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES
('company_staff', 'Mikrotik-Rate-Limit', ':=', '20M/20M'),
('company_staff', 'Session-Timeout', ':=', '28800'),
('company_staff', 'Idle-Timeout', ':=', '3600');

INSERT INTO radgroupcheck (groupname, attribute, op, value) VALUES
('company_staff', 'Simultaneous-Use', ':=', '3'),
('company_staff', 'Login-Time', ':=', 'Al0700-2000');

-- Hotel guests (work at all hotels)
INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES
('hotel_guest', 'Mikrotik-Rate-Limit', ':=', '5M/5M'),
('hotel_guest', 'Session-Timeout', ':=', '86400'),
('hotel_guest', 'Idle-Timeout', ':=', '1800'),
('hotel_guest', 'Mikrotik-Recv-Limit', ':=', '3221225472'),  -- 3GB
('hotel_guest', 'Mikrotik-Xmit-Limit', ':=', '3221225472');

INSERT INTO radgroupcheck (groupname, attribute, op, value) VALUES
('hotel_guest', 'Simultaneous-Use', ':=', '3');

-- Cafe customers (work at all cafes)
INSERT INTO radgroupreply (groupname, attribute, op, value) VALUES
('cafe_customer', 'Mikrotik-Rate-Limit', ':=', '10M/10M'),
('cafe_customer', 'Session-Timeout', ':=', '14400'),  -- 4 hours
('cafe_customer', 'Idle-Timeout', ':=', '1800'),
('cafe_customer', 'Mikrotik-Recv-Limit', ':=', '2147483648'),  -- 2GB
('cafe_customer', 'Mikrotik-Xmit-Limit', ':=', '2147483648');

INSERT INTO radgroupcheck (groupname, attribute, op, value) VALUES
('cafe_customer', 'Simultaneous-Use', ':=', '2');

-- ============================================
-- STEP 3: Create users (work on ALL locations)
-- ============================================
DELETE FROM radcheck WHERE username IN ('ceo', 'manager_john', 'staff_alice', 'staff_bob', 'room101', 'room201', 'cafe_daily001');
DELETE FROM radusergroup WHERE username IN ('ceo', 'manager_john', 'staff_alice', 'staff_bob', 'room101', 'room201', 'cafe_daily001');

-- Company Admin (can use ANY company router)
INSERT INTO radcheck (username, attribute, op, value) VALUES
('ceo', 'Cleartext-Password', ':=', 'CEO@Secure2025!');

INSERT INTO radusergroup (username, groupname, priority) VALUES
('ceo', 'company_admin', 1);

-- Company Manager (can use ANY company router)
INSERT INTO radcheck (username, attribute, op, value) VALUES
('manager_john', 'Cleartext-Password', ':=', 'Manager@John2025');

INSERT INTO radusergroup (username, groupname, priority) VALUES
('manager_john', 'company_admin', 1);

-- Company Staff (can use ANY company router)
INSERT INTO radcheck (username, attribute, op, value) VALUES
('staff_alice', 'Cleartext-Password', ':=', 'Staff@Alice2025'),
('staff_bob', 'Cleartext-Password', ':=', 'Staff@Bob2025');

INSERT INTO radusergroup (username, groupname, priority) VALUES
('staff_alice', 'company_staff', 1),
('staff_bob', 'company_staff', 1);

-- Hotel Guest (can use ANY hotel router)
INSERT INTO radcheck (username, attribute, op, value) VALUES
('room101', 'Cleartext-Password', ':=', 'Room-101-WiFi'),
('room201', 'Cleartext-Password', ':=', 'Room-201-WiFi');

INSERT INTO radusergroup (username, groupname, priority) VALUES
('room101', 'hotel_guest', 1),
('room201', 'hotel_guest', 1);

-- Cafe Customer (can use ANY cafe router)
INSERT INTO radcheck (username, attribute, op, value) VALUES
('cafe_daily001', 'Cleartext-Password', ':=', 'Cafe@Daily001');

INSERT INTO radusergroup (username, groupname, priority) VALUES
('cafe_daily001', 'cafe_customer', 1);

-- ============================================
-- VERIFICATION
-- ============================================
SELECT '=== NAS DEVICES ===' as info;
SELECT nasname, shortname, LEFT(secret, 10) as secret_preview, description FROM nas;

SELECT '' as '';
SELECT '=== USERS ===' as info;
SELECT c.username, LEFT(c.value, 10) as pass_preview, g.groupname 
FROM radcheck c 
LEFT JOIN radusergroup g ON c.username = g.username 
WHERE c.attribute = 'Cleartext-Password'
ORDER BY g.groupname, c.username;

Testing Script

#!/bin/bash
# test_multi_location.sh

echo "=== Testing Multi-Location RADIUS Setup ==="
echo ""

# Test company admin on different routers
echo "1. Testing CEO on HQ Router:"
radtest ceo 'CEO@Secure2025!' localhost 0 'HQ@Secure!2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "2. Testing CEO on Region 1 Router (different secret):"
radtest ceo 'CEO@Secure2025!' localhost 0 'Region1@Secure!2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "3. Testing Staff on Branch 1:"
radtest staff_alice 'Staff@Alice2025' localhost 0 'Branch1@Secure!2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "4. Testing Staff on Branch 2 (different secret):"
radtest staff_alice 'Staff@Alice2025' localhost 0 'Branch2@Secure!2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "5. Testing Hotel Guest on Bangkok Hotel:"
radtest room101 'Room-101-WiFi' localhost 0 'HotelBKK@2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "6. Testing Hotel Guest on Phuket Hotel (different secret):"
radtest room101 'Room-101-WiFi' localhost 0 'HotelPhuket@2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "7. Testing Cafe Customer on Central Cafe:"
radtest cafe_daily001 'Cafe@Daily001' localhost 0 'CafeCentral@2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "8. Testing Cafe Customer on Airport Cafe (different secret):"
radtest cafe_daily001 'Cafe@Daily001' localhost 0 'CafeAirport@2025' | grep -E "Access-Accept|Access-Reject"

echo ""
echo "=== All Tests Complete ==="

Benefits of This Architecture

Centralized User Management

  • Add user ONCE → Works everywhere
  • Change password ONCE → Updated everywhere
  • Disable user ONCE → Blocked everywhere

Security Per Location

  • Each location has unique secret
  • If one secret is compromised, others are safe
  • Can revoke access per location by removing NAS entry

Flexibility

  • Roaming users (staff travel between branches)
  • Same credentials everywhere
  • Easy to add new locations

Simplified Management

-- Add new location (just add NAS)
INSERT INTO nas (nasname, shortname, type, secret, description) VALUES
('10.50.1.1', 'new-branch', 'mikrotik', 'NewBranch@2025', 'New Branch Office');

-- All existing users automatically work there!

Location-Specific Users (If Needed)

Sometimes you want users that ONLY work at specific locations:

-- Create location-specific user
INSERT INTO radcheck (username, attribute, op, value) VALUES
('guest_bangkok_only', 'Cleartext-Password', ':=', 'Bangkok@Guest'),
('guest_bangkok_only', 'NAS-IP-Address', '==', '172.16.1.1');  -- Only this NAS

-- This user can ONLY login from Bangkok hotel (172.16.1.1)

Query to See Where User Can Login

-- See which routers a user can access
SELECT 
    c.username,
    'ALL LOCATIONS' as access,
    GROUP_CONCAT(n.shortname SEPARATOR ', ') as available_routers
FROM radcheck c
CROSS JOIN nas n
WHERE c.username = 'staff_alice'
  AND c.attribute = 'Cleartext-Password'
GROUP BY c.username;

Summary

ComponentUniquenessShared?
NAS SecretDifferent per router❌ NO (unique)
User CredentialsSame everywhere✅ YES (shared)
User GroupsSame everywhere✅ YES (shared)
Group AttributesSame everywhere✅ YES (shared)

The Power:

10 Routers × 1000 Users = Only 1000 user accounts to manage!
(Not 10,000 separate accounts)

This is centralized authentication at its best! 🎉

Does this clarify the relationship? Any other questions about how the tables work together?

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *