DFNRoaming/eduroam sichern mit Client-Zertifikaten und LDAP 55. DFN-Betriebstagung 18. Oktober 2011 Kerstin Ordnung kerstin.ordnung@fiz-karlsruhe.de
1. Zielsetzung Zugriff über WLAN auf interne Ressourcen von FIZ und ddas Internet t für FIZ-Mitarbeiter unter Gewährleistung von: Authentizität der Daten und des Benutzers Integrität der Daten und des Benutzers Vertraulichkeit der Daten Teilnahme am DFNRoaming/eduroam für FIZ-Mitarbeiter unter Gewährleistung von: Authentizität des Benutzers Integrität des Benutzers Vertraulichkeit der Daten Bereitstellung des DFNRoaming/eduroam Dienstes für externe Gäste des FIZ Seite 2
2. Werkzeuge Til Teilnahme am DFNRoaming-Dienst Di Verschlüsselung nach IEEE 802.11i (WPA2) Authentifizierung nach IEEE 802.1X EAP-TLS Client- und Server-Zertifikate aus der DFN-PKI 802.1X (EAP-TLS)-fähige Supplikanten 2 x radsecproxy 1.4.2 (FreeBSD 8.2) in DMZ 2 x freeradius 2.1.10 (Debian GNU/Linux) 2 x Cisco 2100 Series Controller Cisco AIR-LAP1142N Access Points (Thin AP) LDAP-Verzeichnis (MS Active Directory) Sonstiges: DHCP-Server, DNS, Proxy, etc. Seite 3
3. Architektur Seite 4
4. Stolpersteine /1 1. Microsoft NPS in Verbindung mit 3rd-Party-Zertifikaten tifik t (= nicht aus einer Microsoft CA) kann zum heutigen Zeitpunkt nicht sinnvoll eingesetzt werden 2. Korrekte Schlüsselnutzung: Profil beim Zertifikatsantrag ändern User nach 802.1X User (Microsoft Supplicant stört t EKU Smartcard Login) X509v3 Extended Key Usage: TLS Web Client Authentication, E-Mail Protection, Microsoft Smartcardlogin Seite 5
4. Stolpersteine /2 3. Gewünschten Benutzernamen ins Zertifikat schleusen (der, den freeradius als User-Name nehmen soll): Im Zertifikatsantrag den Microsoft UPN hinzufügen (sonst wird CN als äußere Identität angenommen) Seite 6
4.1 Das richtige Zertifikat Seite 7
5. Herausforderungen /1 freeradius nimmt nicht nur für das REALM-Routing sondern auch für die Autorisierung die äußere Identität. So wird z. B. eine LDAP- Abfrage mit einem willkürlich gewählten Benutzernamen ggf. erfolgreich sein, obwohl der Inhaber des Zertifikates, t mit dem die Authentifizierung durchgeführt wird, nicht in der entsprechenden LDAP- Gruppe ist. Seite 8
5. Herausforderungen /2 1. Autorisierung i und Authentifizierung tifi i ausschließlich h mit Daten, die nicht manipuliert werden können. 2. Die einzigen Daten, die nicht manipuliert werden können, befinden sich im Zertifikat. Diese Daten stehen erst zur Verfügung, wenn das EAP-Modul geladen wird (Authentifizierungsphase). 3. Extensive und vollständige Zertifikatsprüfung freeradius macht nur Teilprüfungen Seite 9
6. Lösung 1. Authentifizierung tifi i erfolgt ausschließlich h über EAP-TLS gegen das vom Client und Server präsentierte Zertifikat. 2. Minimal-Autorisierung über das file file Modul (users-datei) Realm und Called-Station-ID 3. Vollständige Zertifikatsprüfung und LDAP-Abfrage Abfrage über den Aufruf eines Skriptes in der eap.conf: Schnittstelle für den Aufruf eines externen Kommandos beliebige Befehle ausführbar Daten aus dem präsentierten Zertifikat stehen zur Verfügung Alle anderen Benutzerinformationen sind frei manipulierbar und damit für die Autorisierung und Authentifizierung irrelevant. Seite 10
7. Konfiguration Relevante Konfigurationsdateien t i in /etc/freeradius: /f 1. sites-available/default 2. eap.conf 3. bin/check_client_cert.shclient cert.sh 4. Client-Konfig Weitere: bin/run_fetch-crl.sh, certs/, users, clients.conf, proxy.conf, radiusd.conf Seite 11
7.1 Konfiguration freeradius sites-available/default authorize { preprocess suffix host ntdomain ## ldap # nicht in dieser Phase. Hier wird nur die # äußere Identität geprüft. files expiration } authenticate { } [ ] eap Seite 12
7.2 Konfiguration freeradius eap.conf eap { [ ] tls { [ ] # check_crl = yes # siehe Skript # check_ cert_ issuer = /C=DE/O=DFN-Verein/ \ OU=DFN-PKI/CN=DFN-CA Global # siehe Skript # check_cert_cn = %{User-Name} # siehe Skript [ ] } verify { client = /etc/freeradius/bin/check_client_cert.sh client cert \ %{TLS-Client-Cert-Filename} [ ] Seite 13
7.3 Konfiguration freeradius bin/check_client_cert.sh CRL-Update Inhalt des Client-Zertifikates wird als temporäre Arbeitsdatei gespeichert Prüfung auf Gültigkeit des Zertifikats: Abgelaufen? Korrupt? CRL ok? Ist der Verwendungszweck SSL Client? Prüfung auf den korrekten Aussteller Prüfung auf das korrekte Subject Prüfung auf einen korrekten Subject Alternative Name: FQDN (für Computer-Zertifikate) oder gültige Email-Adresse (für Benutzer- Zertifikate) Je nach Fund wird der SAN gefiltert und gegen den entsprechenden Attributswert zusammen mit der jeweiligen Objektklasse ( computer oder user ) im LDAP (Active Directory) geprüft Seite 14
7.4 Client-Konfiguration Seite 15
7.4 Client-Konfiguration Seite 16
Danke! Fragen?
55. DFN-Betriebstagung 18. Oktober 2011 Anhang zum Vortrag DFNRoaming/eduroam sichern mit Client- Zertifikaten und LDAP Kerstin Ordnung FIZ Karlsuhe Leibniz-Institut für Informationsinfrastruktur kerstin.ordnung@fiz-karlsruhe.de Relevante Konfigurationsverzeichnisse und -dateien
1. Inhalt des Verzeichnisses /etc/freeradius/certs # Sym-Links auf Hash-Dateien als Ergebnis des Befehls c_rehash./certs # Es werden nur Dateien verarbeitet, die mit.pem oder.crt enden. 400e3430.0 -> DFN-chain.pem 400e3430.r0 -> crl_dfn-verein_dfn-ca_global_pem.pem 46e67768.0 -> server.pem 513c4d4e.0 -> DFN-chain.pem 6107e209.r0 -> crl_dfn-verein_pca_global-g01_pem.pem 812e17de.r0 -> crl_deutsche_telekom_rootca_pem.pem f138a2ae.0 -> server.pem # Die konvertierte CRL-Datei von http://www.telesec.de/pki/roots.html crl_deutsche_telekom_rootca_pem.pem # Die CRL-Datei von https://pki.pca.dfn.de/dfn-ca-global/pub/crl/cacrl.txt crl_dfn-verein_dfn-ca_global_pem.pem # Die CRL-Datei von http://cdp.pca.dfn.de/global-root-ca/pub/crl/cacrl.txt crl_dfn-verein_pca_global-g01_pem.pem # Die Bundle-Datei von https://pki.pca.dfn.de/dfn-ca-global/pub/cacert/chain.txt DFN-chain.pem # Default vom freeradius angelegt (Diffie-Hellmann) dh # Der freeradius-schlüssel server.key # Das freeradius-serverzertifikat server.pem /etc/freeradius# c_rehash./certs 2
2. /etc/freeradius/users # Verbiete Benutzer anonymous ohne Realm (aeussere Identitaet): DEFAULT User-Name == "^[Aa][Nn][Oo][Nn][Yy][Mm][Oo][Uu][Ss]$", Auth-Type := Reject # Erlaube Benutzer anonymous mit Realm (aeussere Identitaet), starte Authentifizierungsphase: DEFAULT User-Name == "^[Aa][Nn][Oo][Nn][Yy][Mm][Oo][Uu][Ss]@.*$", Auth-Type := EAP # Verbiete FIZ-internen Benutzern, sich ueber das interne WLAN an eduroam anzumelden: DEFAULT Called-Station-Id =~ ".*.eduroam", NAS-Identifier =~ "WLANCTL0*", \ User-Name =~ ".*.fiz-karlsruhe.de", Auth-Type := Reject # Ansonsten wird die Authentifizierungsphase eingeleitet: ## DEFAULT Ldap-Group!= "WLANUsers", Auth-Type := Reject # Nicht in dieser Phase. ## Fall-Through = 1 # Der folgende Eintrag betrifft nur Anfragen von FIZ-Benutzern,die von einer fremden Einrichtung # ueber den DFN RADIUS eintreffen. DEFAULT Called-Station-Id =~ ".*eduroam", Auth-Type := EAP # Ansonsten duerfen die Benutzer oder Computer versuchen, sich an FIZINTERN anzumelden: DEFAULT Called-Station-Id =~ ".*FIZINTERN", User-Name =~ ".*\..*@fiz-karlsruhe\.de$", \ Auth-Type := EAP DEFAULT Called-Station-Id =~ ".*FIZINTERN", User-Name =~ ".*\.fiz-karlsruhe\.de$", \ Auth-Type := EAP # Alle anderen fliegen raus: DEFAULT Auth-Type := Reject 3
3. /etc/freeradius/eap.conf eap { default_eap_type = tls timer_expire = 60 ignore_unknown_eap_types = no cisco_accounting_username_bug = no max_sessions = 4096 tls { certdir = ${confdir}/certs cadir = ${confdir}/certs private_key_password = "" private_key_file = ${certdir}/server.key certificate_file = ${certdir}/server.pem CA_file = ${cadir}/dfn-chain.pem dh_file = ${certdir}/dh random_file = /dev/urandom fragment_size = 1024 # check_crl = yes # siehe Skript CA_path = ${cadir} # check_cert_issuer = \ # "/C=DE/O=DFN-Verein/OU=DFN-PKI/CN=DFN-CA Global" # siehe Skript # check_cert_cn = %{User-Name} # siehe Skript copy_request_to_tunnel = yes use_tunneled_reply = yes cipher_list = "DEFAULT" cache { enable = no lifetime = 24 # hours max_entries = 255 } verify { tmpdir = /var/tmp/radiusd client = "/etc/freeradius/bin/check_client_cert.sh %{TLS-Client-Cert-Filename}" } } } 4
4. /etc/freeradius/bin/check_client_cert.sh #!/bin/bash /etc/freeradius/bin/run_fetch-crl.sh client_cert_pem_file="$1" trusted_ca_certs='/etc/freeradius/trusted-cas' # create a tmp file for our cert so that we are safe when running concurrently client_cert_pem_file_safe=`mktemp /var/tmp/radius/client-cert-safe-xxxxxxx.pem` # make sure the file is removed when we exit this script trap "rm -f $client_cert_pem_file_safe" EXIT SIGKILL SIGTERM if [! -r "$client_cert_pem_file" ]; then # if we don't have a readable file to work on, bail out exit 10 fi # make sure we have exactly one certificate in PEM format that openssl can parse # process the input file trough openssl to see if it good enough for openssl # this ensures that only the first cert in the input file will be processed # in subsequent processing openssl x509 -in "$client_cert_pem_file" -out "$client_cert_pem_file_safe" -text 1>/dev/null 2>&1 if [! -r "$client_cert_pem_file_safe" ]; then # if we don't have a readable file to work on, bail out exit 11 fi # is the cert valid afterall? Check validity & revocation status of all(!) certs of the chain. # about the chain: freeradius has given us a single(!) client cert and our directory with # trusted CA certs contains only those CA certs we really trust and want to build chains with openssl verify -crl_check_all -purpose sslclient -CApath "$trusted_ca_certs" "$client_cert_pem_file_safe" egrep -i '(error not valid invalid)' 1>/dev/null 2>&1 if [ "$?" -eq 0 ]; then exit 12 fi # check issuerdn - in case freeradius gives us some other cert egrep '^ *Issuer: C=DE, O=DFN-Verein, OU=DFN-PKI, CN=DFN-CA Global$' "$client_cert_pem_file_safe" >/dev/null 2>&1 if [ "$?" -ne 0 ]; then exit 13; fi # check subjectdn - cause we want only our own staff egrep '^ *Subject: C=DE, O=FIZ Karlsruhe - Leibniz-Institut fuer Informationsinfrastruktur, CN=.+$' "$client_cert_pem_file_safe" >/dev/null 2>&1 if [ "$?" -ne 0 ]; then exit 14; fi 5
# the client cert must contain in its subject alternative name either an fqdn or # an email address from fiz subject_alt_name=`grep -A1 'X509v3 Subject Alternative Name' "$client_cert_pem_file_safe" tail -1` # the following is optimized for machine client authentication: If there is an acceptable # SaN of type DNS recognized, then the test for the mail address is skipped. The test # for the mail address is only run if there was no acceptable SaN of Type DNS detected before # get first FIZ FQDN from SaN if present fqdn=`echo -n "$subject_alt_name" perl -n -e 'if (s/^.*?dns:([^:, ]+?\.fiz-karlsruhe\.de)(,.*)?$/$1/) { print $_ }'` if [ "$fqdn" ]; then # echo "### found FQDN - seems to be a computer: $fqdn" queryattribute='dnshostname' queryvalue="$fqdn" queryvalueobjectclass='computer' else # get first mail address from SaN if present email=`echo -n "$subject_alt_name" perl -n -e 'if (s/^.*?email:([^:, ]+?\@fizkarlsruhe\.de)(,.*)?$/$1/) { print $_ }'` if [ "$email" ]; then # echo "### found mailaddress - seems to be a user: $email" queryattribute='mail' queryvalue="$email" queryvalueobjectclass='user' else # echo "No acceptable FQDN nor email address in certificate's SaN present" exit 15 fi fi if ( [ "$queryattribute" ] && [ "$queryvalue" ] && [ "$queryvalueobjectclass" ] ) then # Now query the directory server (ldap or AD) and check for authorisation ldapsearch -h server.fiz-karlsruhe.de -b "DC=fiz-karlsruhe,DC=de" -D "CN=user,CN=Users,DC=fiz-karlsruhe,DC=de" -w geheim "(&(objectclass=${queryvalueobjectclass})(${queryattribute}=${queryvalue}))" grep WLANUsers if [ "$?" -ne 0 ]; then exit 16; fi exit 0 fi exit 17 6