Liebe Kollegen,
ich greife den Thread hier nochmal auf, weil wir meiner Meinung nach hier eine gute Lösung gebaut haben.
Voraussetzungen: UNIFI Controller
Vorgehen: Wenn in der Linuxmuster WebUI der Haken bei WIFI entfernt wird, starten wir ein Script, was alle aktiven Sessions mit radclient beendet und damit die Benutzer sofort aus dem WLAN schmeißt. Dazu benötigen wir folgende Schritte:
A) Im Unifi-Controller beim entsprechenden WLAN die Einstellung DAS/DAC (CoA) aktivieren
B) Im Unifi-Controller bei Settings > Profiles > RADIUS > Profil den Accouting Server aktivieren (bei uns auf 10.0.0.1:1813)
C) Accounting traffic in neuer SQL Datenbank speichern, dazu in /etc/freeradius/3.0/sites-enabled/default im Abschnitt „accounting{…}“ die „-sql“ flag setzen
D) SQL Datenbank auf Linuxmusterserver anlegen
Schema des Accouting plugins einspielen:
mysql -u radius -p <PASSWORT> < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql
SQL Plugin von Freeradius aktivieren
ln -s /etc/freeradius/3.0/mods-available/sql /etc/freeradius/3.0/mods-available/sql
Im SQL Plugin von Freeradius Logindaten einstellen und TLS abstellen
nano /etc/freeradius/3.0/mods-available/sql
mysql {
tls {
enable = no
# Connection info:
server = "127.0.0.1"
port = 3306
login = "radius"
password = <PASSWORT>
E) Skript für den eigentlichen Trennvorgang erstellen:
nano /usr/lib/linuxmuster-webui/plugins/lmn_session_new/disconnect_radius.py
#######################################################
# Skript zur Trennung von Radiususern durch #
# Aufruf von radclient disconnect auf dem Accesspoint #
# mit dem der User verbunden ist #
# erstellt Januar 2026 von Simon Brahmst #
#######################################################
def disconnect(username):
import mysql.connector
import subprocess
db = mysql.connector.connect(
host="127.0.0.1",
user="radius",
password="PASSWORT",
database="radius"
)
cursor = db.cursor()
cursor.execute("SELECT username,acctsessionid,calledstationid,nasipaddress,acctstoptime FROM radacct WHERE username = \'" + username + "\' AND acctstoptime IS NULL;")
result = cursor.fetchall()
if(not result):
return
for row in result:
ASI = row[1]
NI = row[2].split(':')[0].replace('-','').lower()
IP = row[3]
p = subprocess.Popen("echo Acct-Session-ID = \'"+ASI+"\',NAS-Identifier = \'"+NI+"\' | radclient -x "+IP+" disconnect \"RADIUSSECRET\"",shell=True)
p.wait()
F) Nun noch die passende Stelle in der WebUI einfügen
nano /usr/lib/linuxmuster-webui/plugins/lmn_session_new/views.py
hinter
from aj.plugins.lmn_common.api import lmn_getSophomorixValue
ergänze
from . import disconnect_radius
und später
def handle_api_management_group(self, http_context):
[…]
if group not in valid_groups:
return
radius = False
if group.startswith("nowi"): radius = True
[…]
if(radius):
for u in users:
disconnect_radius.disconnect(u)
Ist also insgesamt ein weniger komplexer geworden, funktioniert aber zuverlässig. D.h. wir können jetzt zu Beginn des Unterrichts den Schülern einer Klasse oder Gruppe das WIFI freigeben und dann auch einzeln oder für alle instantan wieder wegnehmen und das alles direkt über die WebUI.
Was noch nicht optimal ist, dass ich mich damit in @Arnaud Code einniste und es daher nicht updatefest ist, kann man hier über eine Hook-Schnittstelle nachdenken?
Viele Grüße,
Adrian
P.S. Für die Übersicht hier ein paar Verweise auf Threads die das Thema schon bearbeitet haben