====== FreeRADIUS ====== [[https://freeradius.org|FreeRADIUS]] ist eine weit verbreitete Open-Source-Software, die die Authentifizierung der Nutzenden durchführt. Diese Anleitung nutzt FreeRADIUS 3.0.21 auf Debian 11. Bitte überprüfen Sie also ggf. Inkompatibiltäten zwischen der von Ihnen eingesetzten FreeRADIUS-Version. Die Installation von FreeRADIUS geschieht auf Debian/Ubuntu über ''%%apt install freeradius%%''. Wenn Sie die LDAP-Anbindung von FreeRADIUS nutzen möchten, müssen Sie ggf. noch das Paket ''%%freeradius-ldap%%'' zusätzlich installieren. Die Konfigurationsdateien von FreeRADIUS liegen standardmäßig in ''%%/etc/freeradius/3.0%%'' Diese Anleitung beschränkt sich auf die Konfiguration von FreeRADIUS mit Passwort- und EAP-TLS-basierten Authentifizierungsmethoden (EAP-PEAP/EAP-TTLS). Für EAP-TLS (Authentifizierung mit Client-Zertifikaten) oder EAP-PWD haben wir aktuell noch keine Anleitung. FreeRADIUS ist eine mächtige Software und kann eine Vielzahl von Anwendungsfällen abdecken. Die folgende Anleitung legt den Fokus auf eine absolut minimale funktionsfähige Konfiguration, die alle nicht benötigten Module und Konfigurationen auslässt oder entfernt. Dies dient auch der Sicherheit, da in der Vergangenheit immer wieder Default-Konfigurationen für Schwachstellen gesorgt haben. Es wird daher empfohlen, von dieser minimalen Konfiguration nur abzuweichen, wenn die Auswirkungen verstanden wurden. ===== Sites/Server ===== Im Ordner ''%%sites-available%%'' liegen die Standard-Sites bzw. -Server von FreeRADIUS. Ein Server führt dabei immer Authentifizierung und Autorisierung der anfragenden Nutzenden durch und nutzt dafür verschiedene Module. Die Konfiguration der Server gliedert sich dabei in verschiedene Bereiche: * ''%%listen%%'' In dieser Sektion wird konfiguriert, auf welchen IP-Adressen und Ports der Server auf Verbindungen hört. * ''%%authorize%%'' Diese Sektion konfiguriert die Autorisierung, also die Feststellung ob und wenn ja welche Authentifizierung durchgeführt wird. * ''%%authenticate%%'' In dieser Sektion sind die Authentifizierungsmethoden konfiguriert. * ''%%preacct%%''/''%%accounting%%''/''%%session%%'' Diese Sektionen sind für die Behandlung von Accounting-Anfragen zuständig. Auf Accounting werden wir in diesen Anleitungen nicht eingehen. * ''%%post-auth%%'' In dieser Sektion werden Schritte nach einer erfolgen Authentifizierung konfiguriert. * ''%%pre-proxy%%''/''%%post-proxy%%'' Diese Sektionen sind für die Behandlung von Requests zuständig, die an andere RADIUS-Server weitergeleitet werden. Jede Site/Server hat ein Label, über das er referenziert wird. Dieser Name wird am Anfang konfiguriert. server default { listen { [...] } authorize { [...] } authenticate { [...] } [...] } bzw. für ''%%inner-tunnel%%'' server inner-tunnel { [...] } ==== Der Server default ==== Dieser Server ist für alle Authentifizierungen zuständig (auch für Roaming-Requests). Für eigene Nutzende ist dieser Server dafür zuständig, den TLS-Tunnel aufzubauen, damit dann im Tunnel die Authentifizierung durchgeführt werden kann. === listen-Sektion === Die ''%%listen%%''-Sektion legt fest, auf welchen IP-Adressen und Ports der Server auf Anfragen antworten soll. Hierbei muss für jedes Protokoll (Authentifizierung oder Accounting) und für jede Adressfamilie (IPv4/IPv6) bzw. ggf. sogar jede IP-Adresse ein eigener ''%%listen%%''-Block angelegt werden. Diese Anleitung wird sich nur auf den Authentifizierungs-Teil beschränken und kein Accounting durchführen. In jedem ''%%listen%%''-Block müssen die folgenden Konfigurationen gesetzt werden: * ''%%type%%'': Dies kann entweder ''%%auth%%'' für Authentifizierung oder ''%%acct%%'' für Accounting sein. Da wir uns nur mit Authentifizierung beschäftigen, wird es immer auf ''%%auth%%'' gesetzt sein. * ''%%ipaddr%%'': Die IP-Adresse des Hosts, auf der Verbindungen angenommen werden sollen. Mit ''%%*%%'' werden auf allen IPv4-Adressen des Hosts Verbindungen angenommen. Für verschiedene IP-Adressen muss jeweils ein eigener ''%%listen%%''-Block angelegt werden, wenn nicht auf allen IPv4-Adressen Verbindungen angenommen werden sollen. * Um die IP-Adress-Familie zu spezifizieren kann stattdessen ein anderer Konfigurationsparameter benutt werden: * ''%%ipv4addr%%'': spezielle IPv4-Adresse des Servers, alternativ ''%%*%%'' für alle IPv4-Adressen des Servers * ''%%ipv6addr%%'': spezielle IPv6-Adresse des Servers, alternativ ''%%*%%'' für alle IPv6-Adressen des Servers * **Wichtig:** Sollten mehrere IP-Adress-Konfigurationen im ''%%listen%%''-Block existieren, wird nur die erste verwendet. Für verschiedene Konfigurationen je nach IP-Adresse muss also jeweils ein eigener ''%%listen%%''-Block angelegt werden. * ''%%port%%'': Port, auf dem Verbindungen engegengenommen werden. Standard für RADIUS ist Port ''%%1812%%''. Mit ''%%0%%'' wird der Standardport ausgewählt Beispiel: server default { listen { type = auth ipv4addr = 203.0.113.1 port = 0 } listen { type = auth ipv6addr = 2001:db8:0:203::1 port = 0 } [...] } === authorize-Sektion === In der ''%%authorize%%''-Sektion ist konfiguriert, welche Autorisierungsmechanismen verwendet werden. FreeRADIUS trennt hier Autorisierung (Wer darf was?) von Authentifizierung (Ist das auch wirklich der:die Anfragende?). In der ''%%authorize%%''-Sektion wird also zunächst nur festgelegt, ob und wenn ja auf welche Arten sich das anfragende Gerät authentifizieren darf. Hierfür stellt FreeRADIUS ein paar vordefinierte Filter und Methoden zur Verfügung, um ungültige Kennungen schon früh abzulehnen. Die folgenden Optionen sollten in der ''%%authorize%%''-Sektion vorhanden sein: * ''%%filter_username%%'': Eine Policy, die den Usernamen auf korrektes Format prüft. Die entsprechenden Konfigurationen finden Sie in der Datei ''%%policy.d/filter%%'' * ''%%suffix%%'': Setzt die Realm des Usernamens für die folgende Routing-Entscheidung. Dies setzt voraus, dass der Username das Format ''%%@%%'' hat. * ''%%eap%%'': Dies konfiguriert, dass zur Authentifizierung das EAP-Protokoll genutzt werden soll. Ebenfalls sollte in diesem Teil bereits eine Prüfung stattfinden, ob eine Realm gesetzt wurde, da Nutzerkennungen ohne Realm im eduroam unzulässig sind und zu inkonsistenten Konfigurationen führen, die auf dem lokalen Campus funktionieren, aber nicht an anderen Einrichtungen. **Wichtig:** Diese Konfiguration muss nach ''%%suffix%%'' auftauchen, da hier erst das ''%%Realm%%''-Attribut gesetzt wird.pr if (!&Realm) { reject } Da im Default-Server noch keine Authentifizierung stattfindet, muss hier keine weitere Konfiguration (LDAP/MySQL/…) eingebunden werden. Die finale Konfiguration sollte dann wie folgt aussehen: server default { [...] authorize { filter_username suffix if (!&Realm) { reject } eap { ok = return } } [...] } === authenticate-Sektion === In der ''%%authenticate%%''-Sektion wird die Authentisierung der Geräte vorgenommen. Da im eduroam lediglich EAP genutzt wird, beinhaltet die Konfiguration auch nur den Verweis auf EAP. server default { [...] authenticate { eap } [...] } === Accounting-Sektionen (preacct/accounting/session) === Die Sektionen ''%%preacct%%'', ''%%accounting%%'' und ''%%session%%'' sind für die Behandlung von Accounting-Anfragen zuständig. Da wir kein Accounting konfigurieren, können wir diese Sektionen auslassen bzw. komplett auskommentieren. === post-auth-Sektion === Die ''%%post-auth%%''-Sektion ist für die Behandlung von Requests nach der Authentifizierung zuständig. Hierbei gibt es die Haupt-Sektion, die die laufenden und erfolgreichen Requests abhandelt, sowie eine Sub-Sektion ''%%Post-Auth-Type REJECT%%'', die für die abgelehnten Requests zuständig ist. Zunächst muss mit dem folgenden Block der Zwischenstatus der Anfragen gespeichert werden, die noch nicht abgehandelt sind: if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) { update reply { &User-Name !* ANY } } update { &reply: += &session-state: } Zudem muss eine mögliche Reply-Nachricht entfernt werden, wenn eine EAP-Nachricht gesendet wird: remove_reply_message_if_eap In dieser Sektion kann auch zusätzliches Logging konfiguriert werden, wie z.B. das von uns empfohlene Linelog-Modul. outer_linelog Für Rejects muss die Subsektion ''%%Post-Auth-Type REJECT%%'' genutzt werden. Hierin werden zusätzlich noch Attribute gefiltert, da bei Rejects nur bestimmte RADIUS-Attribute mitgeschickt werden sollen. Post-Auth-Type REJECT { # Logging des Rejects outer_linelog # Filtern von Attributen attr_filter.access_reject # Nutzung von EAP für die Reject-Nachricht eap # Reply-Nachricht entfernen, falls es eine EAP-Nachricht ist remove_reply_message_if_eap } Die gesamte ''%%post-auth%%'' Sektion sieht damit wie folgt aus: server default { [...] post-auth { if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) { update reply { &User-Name !* ANY } } update { &reply: += &session-state: } outer_linelog remove_reply_message_if_eap Post-Auth-Type REJECT { outer_linelog attr_filter.access_reject eap remove_reply_message_if_eap } } [...] } === Proxy-Sektionen (pre-proxy/post-proxy) === Die Sektionen ''%%pre-proxy%%'' und ''%%post-proxy%%'' sind für Konfiguration speziell für Requests gedacht, die an andere Server weitergeleitet werden sollen. Hierbei ist im Normalfall keine weitere Konfiguration nötig, lediglich im ''%%post-proxy%%'' muss ''%%eap%%'' gelistet sein: server default { [...] pre-proxy { } post-proxy { eap } } === Komplette Beispielkonfiguration für sites-available/default === server default { listen { type = auth ipv4addr = 203.0.113.1 port = 0 } authorize { filter_username suffix if (!&Realm) { reject } eap { ok = return } } authenticate { eap } post-auth { if (session-state:User-Name && reply:User-Name && request:User-Name && (reply:User-Name == request:User-Name)) { update reply { &User-Name !* ANY } } update { &reply: += &session-state: } outer_linelog remove_reply_message_if_eap Post-Auth-Type REJECT { outer_linelog attr_filter.access_reject eap remove_reply_message_if_eap } } pre-proxy { } post-proxy { eap } } ==== Der Server inner-tunnel ==== Der Server ''%%inner-tunnel%%'' ist für die Authentifizierung der lokalen Nutzenden zuständig und wird innerhalb des TLS-Tunnels, der durch EAP-TTLS/EAP-PEAP aufgebaut wurde, aufgerufen. In diesem Tunnel wird von den Nutzenden die tatsächliche Kennung und, je nach verwendeter Methode, das Passwort oder der MS-CHAP-v2 Handshake übermittelt. Die Konfigurationsanleitung geht an dieser Stelle davon aus, dass FreeRADIUS über LDAP Zugriff auf den Hash des User-Passworts hat. Weitere Konfigurationsoptionen werden wir in der Zukunft hinzufügen Die Konfiguration des inner Tunnel benötigt im Gegensatz zum default-Server lediglich die Sektionen ''%%authorize%%'' und ''%%authenticate%%''. === authorize-Sektion === In der Authorize-Sektion muss, wie beim default-Server, zunächst die Form des Usernamens überprüft werden. filter_username suffix Zusätzlich muss hier nun allerdings konfiguriert werden, dass, auch wenn die Realm nicht lokal ist, der Request nicht weitergeleitet werden soll. Andernfalls könnte ein Request mit dem äußeren Usernamen ''%%anonymous@my-realm.tld%%'' und innerem Usernamen ''%%something@other-realm.tld%%'' im inneren Tunnel nochmals weitergeleitet werden. update control { &Proxy-To-Realm := LOCAL } Hier wird nun auch die Datenherkunft für die Nutzer-Accounts konfiguriert. In unserem Fall gehen wir von einem LDAP-Backend aus. Alternativ können die User-Accounts auch in einer SQL-Datenbank oder in einer Datei verwaltet werden ldap # Für ein LDAP-Backend sql # Für ein SQL-Backend files # Für ein Datei-Backend Final müssen die Authentifizierungsmethoden vorbereitet werden. Hier ist die Konfiguration nun abhängig davon, in welcher Form das Passswort vorliegt. Soll MS-CHAP-v2 genutzt werden, muss hier ''%%mschap%%'' eingebunden werden. Das Modul ''%%pap%%'' sollte immer eingebunden werden, da es die vorliegenden Passwörter in die benötigte Form bringt. Soll im Tunnel EAP genutzt werden (z.B. bei PEAP), muss hier auch EAP konfiguriert werden. Damit im Inneren Tunnel nicht nochmals TTLS/PEAP gesprochen werden kann, wird hier ein anderer EAP-Kontext genutzt, in dem dann Passwort-basierte Protokolle (PAP/GTC) genutzt werden können. Damit sieht die ''%%authorize%%''-Sektion wie folgt aus (Bsp für LDAP-Backend mit PAP): server inner-tunnel { authorize { filter_username suffix update control { &Proxy-To-Realm := LOCAL } ldap inner_eap { ok = return } pap } [...] } === authenticate-Sektion === Hier werden nun die in der ''%%authorize%%''-Sektion konfigurierten Authentifizierungsmechanismen ausgeführt. Die Konfiguration hierfür ist recht simpel. server inner-tunnel { [...] authenticate { Auth-Type PAP { pap } # Den folgenden Block nur nutzen, wenn das Passwort im Klartext oder als NT-Hash vorliegt. # Sonst wird MS-CHAP nicht funktionieren. Auth-Type MS-CHAP { mschap } Auth-Type inner_eap { inner_eap } } [...] } === post-auth-Sektion === Wie beim default-Server wird auch hier in der ''%%post-auth%%''-Sektion die finale Antwort nochmals abgearbeitet. Zunächst fügen wir hier auch wieder ein Logging hinzu, damit wir auch den inneren Usernamen loggen. Hierfür benutzen wir ebenfalls das Linelog-Modul, allerdings mit einer anderen Konfiguration. inner_tunnel_linelog Die abgelehnten Requests werden ebenfalls behandelt. Zunächst werden auch diese Requests geloggt und, wie im default-Server, werden bestimmte Attribute gefiltert. Post-Auth-Type REJECT { inner_tunnel_linelog attr_filter.access_reject [...] } Um bei der Fehlersuche zu helfen, kann zusätzlich noch die Fehlermeldung des Moduls in die äußere Authentifizierung übertragen werden. Diese Information wird im äußeren Tunnel für das Logging verwendet. update outer.session-state { &Module-Failure-Message := &request:Module-Failure-Message } === Komplette Beispielkonfiguration für sites-available/inner-tunnel === Dieses Beispiel geht von einer LDAP-Konfiguration mit PAP als innerer Authentifizierung aus. Da im inneren Tunnel keine Requests weitergeleitet werden, können die Sektionen ''%%pre-proxy%%''/''%%post-proxy%%'' entfallen. server inner-tunnel { authorize { filter_username suffix update control { &Proxy-To-Realm := LOCAL } ldap eap { ok = return } pap } authenticate { Auth-Type PAP { pap } Auth-Type EAP { eap } } post-auth { inner_tunnel_linelog Post-Auth-Type REJECT { inner_tunnel_linelog attr_filter.access_reject update outer.session-state { &Module-Failure-Message := &request:Module-Failure-Message } } } } ==== Aktivierung der Seiten ==== Die Seiten in ''%%sites-available/%%'' sind nicht automatisch aktiv. Zur Aktivierung muss im Ordner ''%%sites-enabled/%%'' ein Symlink auf die Datei in ''%%sites-available/%%'' gesetzt werden. Für die Seiten ''%%default%%'' und ''%%inner-tunnel%%'' sollten diese Links in der voreingestellten Konfiguration schon existieren. ===== Module ===== Im Ordner ''%%mods-available%%'' bzw. ''%%mods-config%%'' liegen die Konfigurationsdateien der einzelnen FreeRADIUS-Module. In dieser Anleitung werden die Module ''%%eap%%'', ''%%ldap%%'' und ''%%linelog%%'' behandelt. Erweiterte Konfiguration über zusätzliche Module wird ggf. in anderen Anleitungsseiten erklärt. ==== Das eap-Modul ==== Das EAP-Modul ist für die Behandlung des EAP-Traffics zuständig. Hier werden alle genutzten EAP-Methoden konfiguriert. Es gibt die Möglichkeit, mehrere EAP-Instanzen zu konfigurieren, z.B. um das innere EAP vom äußeren EAP zu unterscheiden. === Allgemeine EAP-Konfiguration === Zunächst muss das allgemeine EAP-Modul konfiguriert werden. Hierfür sollte der Default-EAP-Type gesetzt werden. Geschieht dies nicht, wird jede Authentifizierung um einen Roundtrip erweitert, weil Client und Server erst die korrekte EAP-Methode aushandeln müssen. Die Option sollte also auf die in Anleitungen präferierte EAP-Methode (''%%ttls%%'' oder ''%%peap%%'') gesetzt werden. default_eap_type = ttls Um möglichst viele gleichzeitige Authentifizierungen zuzulassen, sollte zudem ''%%max_sessions%%'' auf den Standardwert aus der globalen Konfiguration gesetzt werden. Bei dem Standardwert von 256 kann es bei Lastspitzen sonst zu Engpässen kommen. max_sessions = ${max_requests} === TLS-Konfiguration === Bei der Auswahl des Zertifikats für die Absicherung des EAP-TTLS/EAP-PEAP-Tunnels sind einige Dinge zu beachten. Diese Überlegungen werden in Kürze auf de:eduroam:discuss:zertifikate zusammengetragen. Die TLS-Konfiguration geschieht in einem ''%%tls-config%%''-Block. Zunächst müssen die Zertifikats-Dateien konfiguriert werden. Die Datei mit dem Zertifikat sollte dabei auch die Zertifikatskette (in umgekehrter Reihenfolge, d.h. zuerst das Server-Zertifikat, dann die Zertifikatskette vom letzten zum ersten Intermediate-Zertifikat) ohne das Root-Zertifikat beinhalten. Das Root-Zertifikat ist in den Clients konfiguriert und muss nicht übermittelt werden. Die Zertifikate müssen dabei im Ordner ''%%certs/%%'' liegen und müssen für den User ''%%freerad%%'' lesbar sein. tls-config tls-common { certificate_file = ${certdir}/name-of-certificate-file.pem private_key_file = ${certdir}/name-of-private-key-file.pem [...] } Für den Schlüsselaustausch per Diffie-Hellman müssen Parameter generiert werden. Hierfür empfehlen wir 2048 bit-Schlüssel. Bei Installation generiert FreeRADIUS 1024bit Schlüssel, es müssen also neue Parameter generiert werden: $> openssl dhparam -out certs/dh 2048 Die so erzeugte Datei wird im TLS-Block referenziert: tls-config tls-common { [...] dh_file = ${certdir}/dh [...] } Final können noch Einstellungen zu den unterstützten Cipher Suites und Elliptischen Kurven für den Schlüsselaustausch gesetzt werden. Die empfohlene Cipher-List deaktiviert alle Cipher Suites, die kein Forward Secrecy unterstützen sowie Cipher Suites, die für EAP-TTLS/EAP-PEAP nicht nutzbar sind. Mit dem Setzen der ''%%ecdh_curve%%''-Option werden alle aktuellen ECDHE-Kurven aktiviert, statt ausschließlich die Kurve ''%%prime256v1%%''. tls-config tls-common { [...] cipher_list = "DEFAULT !kRSA !PSK !RSP !SSLv3" ecdh_curve = "" } === Konfiguration der EAP-Methoden === Als EAP-Methoden können EAP-TTLS oder EAP-PEAP zum Einsatz kommen. Die Konfiguration beinhaltet einen Verweis auf die zu nutzende TLS-Konfiguration sowie auf den zu verwendenden Server für den inneren Tunnel. Ebenfalls sollte die Konfiguration eine Default-EAP-Methode für die Nutzung im inneren Tunnel beinhalten. ttls { tls = tls-common default_eap_type = gtc virtual_server = "inner-tunnel" } peap { tls = tls-common default_eap_type = gtc virtual_server = "inner-tunnel" } === Konfiguration der inneren EAP-Methode === Die innere EAP-Methode wird genutzt, wenn im TTLS/PEAP-Tunnel nochmals EAP gesprochen wird. Die Konfiguration hierfür kann minimal sein, da hier lediglich GTC bzw. MS-CHAP-v2 konfiguriert werden müssen. eap inner_eap { default_eap_type = gtc gtc { } # Den folgenden Block wieder nur bei Nutzung von MS-CHAP-v2 mschapv2 { } } === Komplette Beispielkonfiguration für mods-available/eap === eap { default_eap_type = ttls max_sessions = ${max_requests} tls-config tls-common { certificate_file = ${certdir}/name-of-certificate-file.pem private_key_file = ${certdir}/name-of-private-key-file.key dh_file = ${certdir}/dh cipher_list = "DEFAULT !kRSA !PSK !SRP !SSLv3" ecdh_curve = "" } ttls { tls = tls-common default_eap_type = gtc virtual_server = "inner-tunnel" } peap { tls = tls-common default_eap_type = gtc virtual_server = "inner-tunnel" } } eap inner_eap { default_eap_type = gtc gtc { } } ==== Das ldap-Modul ==== Das ''%%ldap%%''-Modul ist für die Nutzerauthentifizierung zuständig. In dieser Anleitung gehen wir davon aus, dass FreeRADIUS über einen Account auf dem LDAP-Server verfügt. === Konfiguration der Serververbindung === Zunächst muss eine Verbindung zum Server konfiguriert werden. Der Server kann dabei entweder per IP-Adresse oder per Hostname angegeben werden. Ebenfalls muss der Base-DN sowie Username und Passwort des FreeRADIUS-Accounts konfiguriert werden. Standardmäßig wird von FreeRADIUS unverschlüsseltes LDAP auf Port 389 gesprochen. Soll ein anderer Port verwendet werden kann dies mit ''%%port = %%'' konfiguriert werden. ldap { server = 'ldap.example.com' base_dn = 'dc=example,dc=com' identity = 'cn=freeradius,dc=example,dc=com' password = '' [...] } Neben der grundsätzlichen Verbindung zum LDAP-Server können noch weitere Parameter der Verbindung eingestellt werden. **TLS-Konfiguration** Soll die LDAP-Verbindung verschlüsselt sein, muss ein TLS-Block hinzugefügt werden, in dem die TLS-Konfiguration hinterlegt ist. Dabei kann konfiguriert werden, wie das Zertifikat des LDAP-Servers überprüft werden soll. Damit die Überprüfung funktioniert, muss der konfigurierte Servername dem Namen im Zertifikat entsprechen. Andernfalls kann die Zertifikatsüberprüfung mit ''%%require_cert='allow'%%'' abgeschaltet werden. Die Zertifikatsüberprüfung sollte nur ausgeschaltet werden, wenn die Sicherheit der LDAP-Verbindung anderweitig sichergestellt ist (z.B. durch IPSec oder ein privates VLAN), da über diese LDAP-Verbindung das Passwort des FreeRADIUS-LDAP-Accounts und ggf. die unverschlüsselten Passwörter der Nutzenden versendet werden ldap { tls { start_tls = yes # Nur notwendig, wenn StartTLS verwendet wird. Wenn LDAP über Port 636 (ldaps) gesprochen wird, ist TLS implizit. ca_file = /path/to/the/ca/file.pem require_cert = 'hard' } } **Connection-Pool** Zur Verarbeitung von vielen gleichzeitigen Anfragen kann es sinnvoll sein, mehrere LDAP-Verbindungen zu öffnen, damit mehrere LDAP-Anfragen zeitgleich durchgeführt werden können. Für den Aufgbau der Verbindungen gibt es 4 wichtige Konfigurationsoptionen: * ''%%start%%'': Wie viele LDAP-Verbindungen werden beim Start des FreeRADIUS-Servers aufgebaut? (Default: 5) * Achtung: Ist eine Zahl > 0 konfiguriert, wird FreeRADIUS nicht starten, falls die Verbindung nicht aufgebaut werden kann. * ''%%min%%'': Wie viele LDAP-Verbindungen sollen mindestens offen sein? (Default: 5) * ''%%max%%'': Wie viele LDAP-Verbindungen dürfen maximal offen sein? (Default: 10) * ''%%spare%%'': Wie viele LDAP-Verbindungen sollen in Reserve gehalten werden? (Default: 3) Für den Abbau Verbindungen können ebenfalls verschiedene Parameter gesetzt werden: * ''%%uses%%'': Anzahl an LDAP-Anfragen, nach denen die Verbindung geschlossen werden soll (''%%0%%'' für unbegrenzt, Default: 0) * ''%%lifetime%%'': Anzahl an Sekunden, nach denen die Verbindung geschlossen werden soll (''%%0%%'' für unbegrenzt, Default: 0) * ''%%idle_timeout%%'': Anzahl an Sekunden nach der nach letzter Nutzung die Verbindung geschlossen werden soll (Default: 60) Sollen die Default-Werte genutzt werden, kann dieser Block auch weggelassen werden. ldap { pool { start = 5 min = 5 max = 10 spare = 3 idle_timeout = 60 } } === Konfiguration der User-Suche === Als nächstes muss konfiguriert werden, in welchem Verzeichnisbaum FreeRADIUS nach den Useraccounts suchen soll. Hierfür muss der ''%%base_dn%%'' entsprechend der vorhandenen LDAP-Struktur konfiguriert werden. Liegen die User-Accounts z.B. unter ''%%ou=People,dc=example,dc=com%%'', dann muss der ''%%base_dn%%'' auf ''%%ou=People,${..base_dn}%%'' gesetzt werden. ''%%${..base_dn}%%'' übernimmt hierbei den konfigurierten ''%%base_dn%%'' aus dem übergeordneten Block. Außerdem muss auch der LDAP-Filter konfiguriert werden. Sind nur Nutzende mit bestimmten Attributen zur eduroam-Nutzung berechtigt, kann dies in diesem LDAP-Filter entsprechend angepasst werden. Als Platzhalter für den Usernamen sollte allerdings immer die Ersetzung ''%%%{%{Stripped-User-Name}:-%{User-Name}}%%'' verwendet werden. ldap { [...] user { base_dn = "ou=People,${..base_dn}" filter = (uid=%{%{Stripped-User-Name}:-%{User-Name}})" } [...] === Konfiguration der verwendeten LDAP-Felder === Um die Authentifizierung korrekt durchführen zu können muss FreeRADIUS nun noch die entsprechenden LDAP-Felder in eigene Variablen übersetzen. Hierfür ist es wichtig zu wissen, in welchem Format das Passwort vorliegt. Ist im Passwort-Feld ein Header enthalten, der das Format mit angibt (z.B. ''%%{ssha}....%%''), kann die Variable ''%%control:Password-With-Header%%'' genutzt werden. Liegt das Passwort ohne Header in einem gesonderten LDAP-Feld, muss es in das entsprechende Feld überführt werden. Die möglichen Felder sind in der Man-Page von ''%%rlm_pap%%'' aufgeführt. In diesem Beispiel gehen wir davon aus, dass das Passwort mit Header im LDAP-Attribut ''%%userPassword%%'' liegt. ldap { update { control:Password-With-Header += 'userPassword' } } === Komplette Beispielkonfiguration für mods-available/ldap === Diese Konfiguration geht von einer unverschlüsselten LDAP-Verbindung aus. ldap { server = 'ldap.example.com' identity = 'cn=freeradius,dc=example,dc=com' password = '' base_dn = 'dc=example,dc=com' user { base_dn = "ou=People,${..base_dn}" filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" } update { control:Password-With-Header += 'userPassword' } } ==== Das linelog-Modul ==== Im Linelog-Modul können eigene Log-Meldungen generiert werden. Dies ist insbesondere Hilfreich, da die Standard-Logmeldungen von FreeRADIUS im inneren Tunnel nicht die MAC-Adresse des anfragenden Geräts loggt, sodass bei hoher Auslastung die Requests im äußeren Tunnel nicht den Requests im inneren Tunnel zugeordnet werden können. In den Servern ''%%default%%'' und ''%%inner-tunnel%%'' rufen wir unterschiedliche Linelog-Module auf, die nun in der Datei ''%%mods-available/linelog%%'' konfiguriert werden müssen: Die unten stehende Konfiguration geht davon aus, dass das Log an Syslog mit der Facility LOCAL3 übergeben wird. Alternativ kann hier auch ein Dateiname angegeben werden. linelog outer_linelog { filename = syslog syslog_facility = local3 reference = "messages.%{%{reply:Packet-Type}:-default}" messages { default = "Unknown packet type %{Packet-Type}" Access-Accept = "Login OK: [%{User-Name}] (cli %{request:Calling-Station-Id})" Access-Reject = "Login incorrect: [%{User-Name}] (%{%{reply:Reply-Message}:-%{request:Module-Failure-Message}}) (cli %{request:Calling-Station-Id})" } } linelog inner_tunnel_linelog { filename = syslog syslog_facility = local3 reference = "messages.%{%{reply:Packet-Type}:-default}" messages { default = "Unknown packet type %{Packet-Type}" Access-Accept = "Login OK: [%{User-Name}] (cli %{outer.request:Calling-Station-Id} via TLS tunnel)" Access-Reject = "Login incorrect: [%{User-Name}] (%{request:Module-Failure-Message}) (cli %{outer.request:Calling-Station-Id} via TLS tunnel)" } } ==== Aktivierung/Deaktivierung der Module ==== Standardmäßig sind in FreeRADIUS eine Vielzahl von Modulen aktiv, die für die hier beschriebene Funktionsweise nicht benötigt werden. Die für diesen FreeRADIUS benötigten Module sind: * ''%%always%%'' * ''%%attr_filter%%'' * ''%%eap%%'' * ''%%ldap%%'' * ''%%linelog%%'' * ''%%pap%%'' * ''%%realm%%'' Die Aktivierung der Module geschieht, wie bei den Servern, über einen Symlink in ''%%mods-enabled/%%'' auf die entsprechenden Konfigurationsdateien in ''%%mods-available/%%''. ===== Konfiguration der Clients ===== Die Anbindung der Access Points geschieht über die Datei ''%%clients.conf%%''. Ebenso muss hier die Verbindung vom Radsecproxy zum FreeRADIUS konfiguriert werden. Jeder Client-Bock besitzt dabei ein Label, das für das Logging genutzt werden kann. Innerhalb des Client-Blocks müssen dann die verschiedenen Parameter gesetzt werden: * IP-Adresse: Hier gibt es verschiedene Möglichkeiten (eine muss ausgewählt werden): * ''%%ipaddr%%'': IPv4, IPv6 oder Hostname (Achtung: Schlägt das DNS-Lookup fehl, startet FreeRADIUS nicht) * ''%%ipv4addr%%'': IPv4-Adresse (ggf. mit Subnetzmaske) * ''%%ipv6addr%%'': IPv6-Adresse (ggf. mit Subnetzmaske) * ''%%secret%%'': Das gemeinsame Geheimnis zwischen dem Client und FreeRADIUS client ap1 { ipv4addr = 198.51.100.1 secret = } client ap2 { ipv4addr = 198.51.100.2 secret = } client andere-aps { ipv4addr = 198.51.100.128/25 secret = } client radsecproxy { ipv4addr = 203.0.113.5 secret = } Für Test-Zwecke ist es ebenfalls sinnvoll eine Konfiguration für localhost hinzuzufügen: client localhost { ipaddr = 127.0.0.1 secret = } ===== Konfiguration der Realms und Proxy-Server ===== Abschließend muss noch das Verhalten von FreeRADIUS in Bezug auf die verschiedenen Realms konfiguriert werden. Dies geschieht in der Datei ''%%proxy.conf%%'' Die Konfiguration gliedert sich in 3 Teile: * Home-Server: Hier werden die Kommunikationspartner (i.d.R. nur der Radsecproxy) konfiguriert * Home-Server-Pool: Ein Pool gruppiert Home-Server zusammen und stellt das Fail-Over sicher. * Realm: Die Realms definieren das Verhalten je nach Realm des Usernamens. Zunächst muss das Proxying der Requests generell aktiviert werden: proxy server { } Dann ist für jeden Server ein eigener ''%%home_server%%''-Block anzulegen. In der Regel ist dies nur der Radsecproxy (bzw. mehrere bei redundantem Setup) home_server radsecproxy { ipaddr = 203.0.113.5 secret = [...] } Um ungewolltes Fail-Over-Verhalten zu verhindern, sollte hierbei dann auch noch StatusServer konfiguriert werden. Diese Konfiguration sorgt dafür, dass die Verbindung an sich getestet wird. Andernfalls kann es sein, dass FreeRADIUS die Verbindung als Zombie markiert, wenn Requests von einer bestimmten Realm nicht beantwortet werden, obwohl die Verbindung für andere Realms funktioniert. home_server radsecproxy { [...] status_check = status-server check_interval = 60 # Anzahl Sekunden zwischen StatusServer-Checks. num_answers_to_be_alive = 3 # Anzahl von StatusServer-Antworten, nach denen bei einem Fail-Over-Event dieser Server wieder aktiv geschaltet wird } Als nächstes muss ein ''%%home_server_pool%%'' konfiguriert werden. In dieser Sektion werden die Fail-Over-Regeln konfiguriert. FreeRADIUS unterstützt verschiedene Fail-Over-Mechanismen, die nicht alle für EAP-basierte Methoden geeignet sind. Geeignet sind: * ''%%client-balance%%'': Entscheidung auf Basis der Source-IP-Adresse des eingegangenen Requests (nicht sinnvoll bei nur einem WLAN-Controller). Ist der so gewählte Server nicht aktiv, wird der nächste genommen. * ''%%client-port-balance%%'': Wie ''%%client-balance%%'', bezieht allerdings den Source-Port mit ein (dementsprechend auch bei nur einem WLAN-Controller nutzbar) * ''%%fail-over%%'': Hot-Standby-Redundanz (der primäre Server wird standardmäßig genommen, es sei denn er ist als nicht aktiv markiert) home_server_pool radsecproxy { type = fail-over home_server = radsecproxy # Hier können dann weitere Home-Server eingetragen werden. # z.B. home_server = radsecproxy2 } Abschließend müssen die Realms konfiguriert werden. Hierfür müssen zunächst die eigenen Realms eingetragen werden. Ein leerer Realm-Block bedeutet hierbei, dass die Requests lokal bearbeitet werden sollen. realm example.com { } realm LOCAL { } realm NULL { } ''%%LOCAL%%'' und ''%%NULL%%'' sind hierbei spezielle Werte, die intern genutzt werden, wenn z.B. keine Realm vorhanden ist oder wenn für den Request manuell gesetzt werden soll, dass er lokal bearbeitet wird. Für alle weiteren Realms können wir das Keyword ''%%DEFAULT%%'' nutzen. Hierbei muss der zuständige ''%%home_server_pool%%'' sowie die Option ''%%nostrip%%'' angegeben werden. Wird die Option ''%%nostrip%%'' weggelassen, bearbeitet FreeRADIUS den weitergeleiteten Request und tauscht den Usernamen durch ''%%Stripped-User-Name%%'' und ''%%Realm%%'' aus, was in der eduroam-Routing-Struktur nicht funktioniert. realm DEFAULT { auth_pool = radsecproxy nostrip } ==== Komplette Beispielkonfiguration proxy.conf ==== proxy server { } home_server radsecproxy { ipaddr = 203.0.113.5 secret = status_check = status-server check_interval = 60 num_answers_to_be_alive = 3 } home_server_pool radsecproxy { type = fail-over home_server = radsecproxy } realm example.com { } realm LOCAL { } realm NULL { } realm DEFAULT { auth_pool = radsecproxy nostrip }