
### **FreeRADIUS Setup for Student Network Access (IPv4-Only)**  
**Context:**  
- **FreeRADIUS Server IP:** `172.16.2.5`  
- **AD Server IP:** `172.16.2.10`  
- **Student VLAN:** `10.10.135.254/22` (ensure this VLAN is isolated and routed to the RADIUS server).  
- **Goal:**  
  - Students authenticate via AD.  
  - Prevent multiple devices per user (same credentials) from connecting.  
  - Track connected devices per user.  

---

### **1. FreeRADIUS Configuration (Key Sections)**  
#### **A. LDAP Authentication to AD**  
Edit `/etc/freeradius/3.0/sites-enabled/inner-tunnel` (or `default`):  
```ini
ldap {
    server = "172.16.2.10"  # AD Server IP  
    base_dn = "DC=example,DC=com"  # Replace with your domain  
    bind_dn = "CN=radius,OU=ServiceAccounts,DC=example,DC=com"  # AD service account  
    bind_password = "your_ad_password"  # AD service account password  
    ldap_filter = "(sAMAccountName=%{User-Name})"  # Query for user  
    timeout = 5  
    retry = 3  
    start_tls = no  
}
```
- **Note:** Ensure the AD service account has read access to user attributes (e.g., `sAMAccountName`, `userPrincipalName`).  

---

#### **B. Prevent Multiple Devices per User**  
Use the `Limit` directive to enforce **1 session per user**:  
```ini
authorize {
    ...
    Limit-User-Name {
        max = 1  # Max 1 session per user  
        reject  # Reject if limit is exceeded  
    }
}
```
- **How it works:**  
  - The `Limit` directive checks the `User-Name` attribute.  
  - If a user is already logged in, the second request is rejected.  
- **Limitations:**  
  - Requires **persistent session tracking** (e.g., a database or file).  
  - FreeRADIUS itself does not natively track active sessions.  

#### **C. Track Connected Devices (Optional)**  
If you need to **track devices per user**, use a **database** (e.g., MySQL, PostgreSQL) or a **file** to store active sessions. Example:  
```ini
authorize {
    ...
    if (User-Name == "student1") {
        update {
            User-Name := "student1"
            Framed-IP-Address := "%{Framed-IP-Address}"
            Calling-Station-Id := "%{Calling-Station-Id}"
        }
    }
}
```
- **Store this data in a database** to check for duplicates.  
- Use `radacct` for accounting records (requires `accounting` section).  

---

### **2. VLAN Configuration (Network Layer)**  
Ensure the **student VLAN** (`10.10.135.254/22`) is properly routed to the RADIUS server:  
- **NAS (Network Access Server):**  
  - Configure the NAS to send the **`Framed-Interface-Id`** (VLAN ID) in the RADIUS request.  
  - Example:  
    ```ini
    [nas]
    type = other
    shortname = NAS-Name
    secret = shared_secret
    framed-interface-id = 135  # VLAN ID
    ```
- **Firewall Rules:**  
  - Allow traffic between the student VLAN and the RADIUS server (`172.16.2.5`).  
  - Block unauthorized access to the VLAN.  

---

### **3. NAS Configuration (Example: Cisco IOS)**  
If using a router as the NAS:  
```bash
aaa authentication login default group radius local  
aaa authentication login default group radius  
aaa authorization network default group radius  
aaa accounting network default start-stop group radius  

radius-server host 172.16.2.5 key your_shared_secret  
radius-server vsa send-template  
```
- Ensure the NAS sends the **`Calling-Station-Id`** (MAC address) and **`Framed-IP-Address`** in the RADIUS request.  

---

### **4. Testing and Debugging**  
1. **Test LDAP Authentication:**  
   - Use `radtest` to simulate a login:  
     ```bash
     radtest student1 password 172.16.2.5 1812 testing123
     ```
2. **Check Logs:**  
   - `/var/log/freeradius/radius.log` for authentication errors.  
3. **Monitor Active Sessions:**  
   - Use `radwho` or a database query to list active users.  

---

### **5. Advanced: Session Tracking with a Database**  
If you need precise tracking, set up a database (e.g., MySQL) with a table like:  
```sql
CREATE TABLE active_sessions (
    username VARCHAR(255) PRIMARY KEY,
    ip_address VARCHAR(45),
    mac_address VARCHAR(45),
    session_id VARCHAR(255),
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
- Update the RADIUS config to insert session data into the table.  
- Use a script to clean up old sessions (e.g., every 5 minutes).  

---

### **Final Notes**  
- **Security:** Ensure the RADIUS secret and AD credentials are encrypted.  
- **Scalability:** For large deployments, use a **database** to track sessions.  
- **Fallback:** If the `Limit` directive is insufficient, use a **script** to check the database for active sessions and reject new ones.  

This configuration ensures students authenticate via AD, prevents multiple devices per user, and isolates their VLAN for secure access.