new radius server
This commit is contained in:
22
radius/Dockerfile
Normal file
22
radius/Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM python:3.9-slim
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install runtime dependencies (for mysql-connector and networking tools)
|
||||
RUN apt-get update && \
|
||||
apt-get install -y gcc libmariadb-dev iputils-ping && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy RADIUS service source code
|
||||
COPY . .
|
||||
|
||||
# Expose RADIUS port (UDP)
|
||||
EXPOSE 1812/udp
|
||||
|
||||
# Run the RADIUS service
|
||||
CMD ["python", "main.py"]
|
||||
4
radius/dictionary
Normal file
4
radius/dictionary
Normal file
@@ -0,0 +1,4 @@
|
||||
ATTRIBUTE User-Name 1 string
|
||||
ATTRIBUTE Tunnel-Type 64 integer
|
||||
ATTRIBUTE Tunnel-Medium-Type 65 integer
|
||||
ATTRIBUTE Tunnel-Private-Group-Id 81 string
|
||||
50
radius/main.py
Normal file
50
radius/main.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from pyrad.server import Server, RemoteHost
|
||||
from pyrad.dictionary import Dictionary
|
||||
from pyrad.packet import AccessAccept, AccessReject
|
||||
import mysql.connector
|
||||
import os
|
||||
DEFAULT_VLAN_ID = os.getenv("DEFAULT_VLAN", "999")
|
||||
|
||||
class MacRadiusServer(Server):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.db = mysql.connector.connect(
|
||||
host=os.getenv('DB_HOST'),
|
||||
port=int(os.getenv('DB_PORT', 3306)),
|
||||
user=os.getenv('DB_USER'),
|
||||
password=os.getenv('DB_PASSWORD'),
|
||||
database=os.getenv('DB_NAME'),
|
||||
)
|
||||
|
||||
def HandleAuthPacket(self, pkt):
|
||||
username = pkt['User-Name'][0].upper()
|
||||
cursor = self.db.cursor(dictionary=True)
|
||||
cursor.execute("SELECT vlan_id FROM users WHERE mac_address = %s", (username,))
|
||||
result = cursor.fetchone()
|
||||
cursor.close()
|
||||
|
||||
if result:
|
||||
reply = self.CreateReplyPacket(pkt)
|
||||
reply.code = AccessAccept
|
||||
|
||||
reply.AddAttribute("Tunnel-Type", 13)
|
||||
reply.AddAttribute("Tunnel-Medium-Type", 6)
|
||||
reply.AddAttribute("Tunnel-Private-Group-Id", result['vlan_id'])
|
||||
else:
|
||||
# Fallback to default VLAN
|
||||
reply = self.CreateReplyPacket(pkt)
|
||||
reply.code = AccessAccept
|
||||
reply["Tunnel-Type"] = 13 # VLAN
|
||||
reply["Tunnel-Medium-Type"] = 6 # IEEE-802
|
||||
reply["Tunnel-Private-Group-Id"] = DEFAULT_VLAN_ID
|
||||
self.SendReplyPacket(pkt.fd, reply)
|
||||
print(f"[INFO] MAC {mac} not found — assigned to fallback VLAN {DEFAULT_VLAN_ID}")
|
||||
|
||||
self.SendReplyPacket(pkt.fd, reply)
|
||||
|
||||
if __name__ == '__main__':
|
||||
srv = MacRadiusServer(dict=Dictionary("dictionary"))
|
||||
srv.hosts["0.0.0.0"] = RemoteHost("0.0.0.0", os.getenv("RADIUS_SECRET", "testing123").encode(), "localhost")
|
||||
srv.BindToAddress("0.0.0.0")
|
||||
srv.Run()
|
||||
2
radius/requirements.txt
Normal file
2
radius/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
pyrad
|
||||
mysql-connector-python
|
||||
Reference in New Issue
Block a user