Die folgende Anleitung beschreibt den Aufbau eines Netzwerks mit 802.1x-Authentifizierung (z.B. für „WPA2 Enterprise“) mittels OpenLDAP und FreeRADIUS.
SSL-Zertifikate / CA
Grundlage für eine vertrauenswürdige Kommunikation ist eine anständige Publik-Key-Infrastruktur (PKI, siehe Wikipedia). Hierfür legen wir uns eine eigene Zertifizierungsstelle (CA – Certificate Authority) an, mit der wir später alle benötigten SSL/TLS-Zertifikate ausstellen.
Zuerst aber installieren wir die benötigten Werkzeuge:
apt-get install openssl ssl-cert
Anschließend erzeugen wir ein eigenes CA-Zertifikat. Der private Schlüssel für dieses Zertifikat sollte an einem sicheren Ort aufbewahrt werden und mit einem sicheren und möglichst langem Passwort versehen sein! (Tipp: das Programm „apg“ generiert zufällige Passwörter)
Das CA-Zertifikat ist in diesem Beispiel 10 Jahre lang gültig, damit man nicht alle paar Jahre seine gesamte IT-Infrastruktur neu konfigurieren muss 🙂
openssl req -x509 -new -extensions v3_ca -newkey rsa:4096 \ -keyout ca.key -days 3652 -out ca.pem -sha512
Beispieldaten für eine CA:
Country Name: DE
State or Province Name: Bayern
Locality Name: Muenchen
Organization Name: Familie Mustermann
Organizational Unit Name: (leer)
Common Name: Familie Mustermann CA 2016
Email Address: (leer)
Mit diesem CA-Zertifikat erstellen wir nun ein erstes Zertifikat für den Server selbst, welches später u.a. für LDAP und RADIUS verwendet wird. So lange diese Dienste auf dem selben Server laufen empfehle ich, ein gemeinsames Zertifikat anzulegen, das vereinfacht dann den Austausch wenn es abläuft:
openssl req -new -newkey rsa:2048 -keyout server.key \ -out server.csr -nodes -sha512
Bei den Zertifikatsdaten kann man die selben Informationen angeben wie beim CA-Zertifikat, oder auch beliebig andere. Wichtig ist aber, beim Common Name den Namen des Servers anzugeben:
Common Name (e.g. server FQDN or YOUR name) []: server.example.org
Außerdem benötigen wir noch eine kleine Textdatei mit den X509v3-Extensions, welche in das Zertifikat aufgenommen werden sollen. Ich nenne die mal ca-sign.cfg:
[ usr_cert ] basicConstraints=CA:FALSE subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer:always extendedKeyUsage = 1.3.6.1.5.5.7.3.1 # identisch: extendedKeyUsage = serverAuth
Besonders wichtig ist die „extendedKeyUsage“-Einschränkung – ohne diese akzeptiert Windows das Serverzertifikat nicht (KB#814394)
Diesen Certificate Signing Request unterschreiben wir mit dem CA-Zertifikat. Die Gültigkeit wird auf 2 Jahre festgelegt (dann muss das Zertifikat ersetzt werden!):
openssl x509 -req -in server.csr -out server.pem \ -CA ca.pem -CAkey ca.key -CAcreateserial -days 730 -sha512 \ -extfile ca-sign.cfg -extensions usr_cert
Die Dateien werden anschließend in die richtigen Zielverzeichnisse kopiert sowie die Dateiberechtigungen angepasst:
cp ca.pem /etc/ssl/certs/ca.pem cp server.pem /etc/ssl/certs/server.pem cp server.key /etc/ssl/private/server.key chown root:ssl-cert /etc/ssl/private/server.key chmod 640 /etc/ssl/private/server.key
Das war’s vorerst was SSL-Zertifikate betrifft.
LDAP
Erst mal das OpenLDAP-Paket installieren:
apt-get install slapd ldap-utils
Falls die Konfiguration des LDAP-Server (slapd) übersprungen wurde oder was geändert werden muss, einfach den Befehl dpkg-reconfigure slapd ausführen.
Die relevanten Einstellungen für den LDAP-Server sind:
DNS domain name: server.example.org
Organization name: Familie Mustermann
Administrator password: (gut merken!)
Database backend: MDB
Allow LDAPv2 protocol? no
Mit dem Befehl slapcat kann man sich die Konfigurationsdaten anzeigen lassen.
Nun müssen wir das LDAP-Schema erweitert, um Benutzer (users) und Gruppen (groups) anlegen zu können. Dazu legen wir eine Datei namens „base.ldif“ mit folgendem Inhalt an:
dn: ou=people,dc=example,dc=org objectClass: organizationalUnit ou: people dn: ou=groups,dc=example,dc=org objectClass: organizationalUnit ou: groups
Mit folgendem Befehl werden die neuen Einträge angelegt:
ldapadd -x -D cn=admin,dc=example,dc=org -W -f base.ldif
TLS für LDAP einrichten
Damit der OpenLDAP-Server Zugriff auf den privaten Schlüssel des Serverzertifikats erhält, müssen wir ihn in die Gruppe ssl-cert aufnehmen. Außerdem müssen wir den Dienst neu starten, damit die neue Gruppenmitgliedschaft wirksam wird (sonst gibt es später beim ocTLS.ldif einen Fehler):
usermod -a -G ssl-cert openldap service slapd restart
Anschließend legen wir eine Datei namens olcTLS.ldif an:
dn: cn=config changetype: modify add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ssl/certs/ca.pem - replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/ssl/certs/server.pem - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ssl/private/server.key
Diese wird importiert mit:
ldapmodify -Y EXTERNAL -H ldapi:/// -f olcTLS.ldif
Zuletzt wird in /etc/default/slapd in die Variable SLAPD_SERVICES noch „ldaps:///“ mit aufgenommen:
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
Dann (noch mal) slapd neu starten:
service slapd restart
Fertig.
RADIUS
Wie immer installieren wir zuerst die benötigten Pakete:
apt-get install freeradius freeradius-ldap freeradius-utils
Während der Installation werden individuelle 1024-Bit Diffie-Hellman-Parameter erzeugt. Streng genommen gelten 1024 Bit nicht mehr als (langfristig) sicher – ich empfehle, 2048-Bit DH-Parameter zu erzeugen und diese entsprechend in der Datei /etc/freeradius/certs/dh zu ersetzen. Zur Erzeugung den Befehl „openssl gendh 2048“ ausführen – auf einem Raspberry kann das aber eine mittlere Ewigkeit dauern…
Zudem ersetzen wir die symbolischen Links auf die „Snakeoil“-Zertifikate durch unsere eigenen Dateien. So bleibt alles da wo es hingehört und wir müssen weniger an der Konfiguration ändern.
cd /etc/freeradius/certs ln -sf /etc/ssl/certs/ca.pem ca.pem ln -sf /etc/ssl/certs/server.pem server.pem ln -sf /etc/ssl/private/server.key server.key
In der Datei /etc/freeradius/clients.conf legen wir dann jeweils einen Eintrag für den Switch sowie für den WLAN-Accesspoint an. Die IP-Adressen sind die jeweiligen Geräte-IPs aus dem Management-VLAN. Die Passwörter sind selbstverständlich zu ersetzen! 😉
# Switch: client 192.168.10.3 { secret = PaSsWoRtNuRfUeRsWiTcH shortname = switch } # WLAN Access Point: client 192.168.10.4 { secret = AcCeSsPoInTpAsSwOrT shortname = wlan }
Anschließend wird die Authentifzierung konfiguriert. In der Datei /etc/freeradius/eap.conf muss der Eintrag default_eap_type (im Abschnitt eap {…} ) auf ttls gestellt werden:
default_eap_type = ttls
In /etc/freeradius/modules/ldap müssen wir den LDAP-Server definieren:
ldap { server = "server.example.org" port = 636 basedn = "dc=example,dc=org" filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})" base_filter = "(objectclass=radiusprofile)" ldap_connections_number=5 dictionary_mapping = ${confdir}/ldap.attrmap }
Dann in /etc/freeradius/sites-enabled/default sowie in /etc/freeradius/sites-enabled/inner-tunnel LDAP aktivieren:
authorized { [...] ldap [...] } [...] authenticate { [...] Auth-Type LDAP { ldap } [...] }
Zum Schluss starten wir freeradius neu:
service freeradius restart
RADIUS-Schema in LDAP importieren
Das für RADIUS benötigte LDAP-Schema liegt in /usr/share/doc/freeradius/examples/openldap.schema. Lästig und unverständlich ist die Tatsache, dass dieses Schema nicht als „.ldif“-Datei vorliegt und man sich das relativ kompliziert selbst erzeugen muss. Ein schneller Workaround ist dabei das Script schema2ldif.sh. Damit ist die Konvertierung schnell erledigt:
wget "http://technik.blogs.nde.ag/files/2012/08/schema2ldif.sh" sh schema2ldif.sh /usr/share/doc/freeradius/examples/openldap.schema
Mit ldapadd importieren wir das erzeugte openldap.ldif:
ldapadd -Y EXTERNAL -H ldapi:/// -f openldap.ldif
#
Test
Nun wird es Zeit, die Dienste mal zu testen. Zuerst legen wir eine Datei „test123.ldif“ an, welche die Daten für einen Test-Account enthält:
dn: uid=test123,ou=people,dc=example,dc=org objectClass: top objectClass: radiusprofile objectClass: inetOrgPerson cn: test123 sn: test123 uid: test123 description: Test User radiusTunnelType: VLAN radiusTunnelMediumType: 6 radiusTunnelPrivateGroupId: 10 # Passwort: PaSs123 (erzeugt mit "slappasswd") userPasswort: {SSHA}Kznn1PyjcYJEkn96avu74r8qqBjm8Mou
Dieser wird mit ldapadd angelegt:
ldapadd -x -D cn=admin,dc=example,dc=org -W -f test123.ldif
Mit dem Befehl radtest testen wir dann eine Anmeldung:
radtest "test123" "PaSs123" localhost 18120 testing123
Wenn alles geklappt hat, sollte die Ausgabe etwa so aussehen:
Sending Access-Request of id 199 to 127.0.0.1 port 1812 User-Name = "test123" User-Password = "PaSs123" NAS-IP-Address = 127.0.1.1 NAS-Port = 18120 Message-Authenticator = 0x00000000000000000000000000000000 rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=199, length=36 Tunnel-Private-Group-Id:0 = "10" Tunnel-Medium-Type:0 = IEEE-802 Tunnel-Type:0 = VLAN
Falls der Test nicht erfolgreich war, dann sollte man freeradius beenden (service freeradius stop) und im Debug-Modus starten (freeradius -XXX). Von einer zweiten SSH-Verbindung/Konsole aus dann den radtest-Befehl ausführen und prüfen, was freeradius so meldet.
EAP testen (optional)
Die Authentifizierung für 802.1x läuft via EAP (Extensible Authentication Protocol). Um das zu testen, installieren wir das Tool eapol_test (muss leider aus dem Source compiliert werden):
apt-get install libssl-dev libnl-dev cd /tmp wget "http://w1.fi/releases/wpa_supplicant-2.5.tar.gz" tar xvf wpa_supplicant-2.5.tar.gz cd wpa_supplicant-2.5/wpa_supplicant cp defconfig .config echo "CONFIG_EAPOL_TEST=y" >>.config make eapol_test
eapol_test benötigt eine Konfigurationsdatei (wie auch wpa_supplicant unter Linux). Diese einfach als „eapol_test.conf“ anlegen:
network={ eap=TTLS eapol_flags=0 key_mgmt=IEEE8021X identity="test123" password="PaSs123" ca_cert="/etc/ssl/certs/ca.pem" phase2="auth=PAP" }
Und dann der spannende Moment:
./eapol_test -c ./eapol_test.conf -a 127.0.0.1 -p 1812 -s testing123
Wenn alles passt, sollte (nach vielen, vielen Bildschirmseiten voller Debug-Meldungen) als letzte Zeile ein SUCCESS ausgegeben werden. 🙂
Absicherung / Aufräumen
## „testing123“-Account entfernen
# (Fotsetzung folgt)