FreeRADIUS
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
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 entwederauth
für Authentifizierung oderacct
für Accounting sein. Da wir uns nur mit Authentifizierung beschäftigen, wird es immer aufauth
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 eigenerlisten
-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 Serversipv6addr
: 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 eigenerlisten
-Block angelegt werden.
port
: Port, auf dem Verbindungen engegengenommen werden. Standard für RADIUS ist Port1812
. Mit0
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 Dateipolicy.d/filter
suffix
: Setzt die Realm des Usernamens für die folgende Routing-Entscheidung. Dies setzt voraus, dass der Username das Format<username>@<realm>
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 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
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 = <portnummer>
konfiguriert werden.
ldap { server = 'ldap.example.com' base_dn = 'dc=example,dc=com' identity = 'cn=freeradius,dc=example,dc=com' password = '<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.
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 = '<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 = <shared secret> } client ap2 { ipv4addr = 198.51.100.2 secret = <shared secret> } client andere-aps { ipv4addr = 198.51.100.128/25 secret = <shared secret> } client radsecproxy { ipv4addr = 203.0.113.5 secret = <shared secret> }
Für Test-Zwecke ist es ebenfalls sinnvoll eine Konfiguration für localhost hinzuzufügen:
client localhost { ipaddr = 127.0.0.1 secret = <shared 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 = <shared 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
: Wieclient-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 = <shared 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 }