Absicherung des OpenLDAP-Servers - LDAPS-Konfiguration
Damit unser OpenLDAP-Server auch via ldaps erreichbar ist, werden wir in diesem Kapitel die Erstellung und Integration eines Server-Zertifikates sowie die nötigen Konfigurationsschritte näher betrachten.
Zertifikatserstellung
Für unseren OpenLDAP-Server werden wir ein Zertifikat von der freien Community-Zertifizierungsstelle CAcert. Selbstverständlich kann man sich auch selbst eine CA erstellen und ein selfsigned Zertifikat generieren. Die grundlegende Herangehensweise ist dabei die gleiche; wir werden uns bei der weiteren Betrachtung daher auf die CAcert-Variante beziehen.
privaten Schlüssel generieren
Als erstes generieren wir uns einen privaten Schlüssel.
# openssl genrsa -out /etc/pki/tls/private/private.key 2048
Generating RSA private key, 2048 bit long modulus ................................................................................+++ ..+++ e is 65537 (0x10001)
Über die Dateiberechtigung schützen wir die Datei vor fremden Blicken.
# chmod 400 /etc/pki/tls/private/private.key
Bei Bedarf kann man mit openssl rsa -in <keyfile> -noout -text die Schlüsseldatei öffnen und ausgeben lassen.
# openssl rsa -in /etc/pki/tls/private/private.key -noout -text
Zertifikatsregistrierungsanforderung
Damit von CAcert unser digitales Zertifikat erstellt werden kann, benötigen wir ein CSR1), eine Textzeichenfolge, die wir mit Hilfe der SSL-Software openssl auf unserem zu zertifizierenden Servers erzeugen. Mit Eingabe eines Punktes . erzeugen wir dabei ein leeres Feld.
# openssl req -new -key /etc/pki/tls/private/private.key -out /etc/pki/tls/misc/ldap.dmz.nausch.org.csr
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:DE State or Province Name (full name) []:Bayern Locality Name (eg, city) [Default City]:Pliening Organization Name (eg, company) [Default Company Ltd]:Nausch Organizational Unit Name (eg, section) []:. Common Name (eg, your name or your server's hostname) []:ldap.dmz.nausch.org Email Address []:michael@nausch.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Auch hier passen wir die Dateiberechtigung des gerade erstellten CSR2) an.
# chmod 400 /etc/pki/tls/misc/ldap.dmz.nausch.org.csr
Den Inhalt unseres CSR, der gerade erstellten Datei, geben wir dann auf der Seite von CAcert im im Browserfenster bei der Bestellung ein.
Bei Bedarf können wir uns den Inhalt unseres CSR in lesbarer Form ausgeben lassen.
# openssl req -noout -text -in /etc/pki/tls/misc/ldap.dmz.nausch.org.csr
CAcert Server-Zertifikat
Von CAcert erhalten wir dann unser Zertifikat, welches wir in einer einfachen Textdatei auf unserem Server ablegen.
# vim /etc/pki/tls/certs/ldap.dmz.nausch.org.crt
Anschließend passen wir auch hier die Dateiberechtigungen an.
# chmod 400 /etc/pki/tls/certs/ldap.dmz.nausch.org.crt
Den Inhalt unseres CAcert-Zertifikates können wir mit folgenden Befehlsaufrufes lesbar ausgeben lassen.
# openssl req -noout -text -in /etc/pki/tls/misc/ldap.dmz.nausch.org.csr
CAcert Root-Zertifikat
Von CAcert laden wir uns das Class 1 Root-Zertifikat auf unseren Server.
# wget http://www.cacert.org/certs/root.crt
Anschließend überprüfen wir den Fingerprint des heruntergeladenen Root-Zertifikates.
# openssl x509 -noout -fingerprint -in /etc/pki/tls/certs/root.crt
SHA1 Fingerprint=13:5C:EC:36:F4:9C:B8:E9:3B:1A:B2:70:CD:80:88:46:76:CE:8F:33
Diesen vergleichen wir mit den Angaben auf der Webseite von CAcert.
Konfiguration
Schlüsseldateien ablegen
Für unsere OpenLDAP-Installation legen wir uns am besten einen eigenen Unterordner unter /etc/pki an.
# mkdir -p /etc/pki/ldap/certs
# mkdir -p /etc/pki/ldap/private
Anschließend legen wir dort die drei benötigten Dateien ab:
- unseren Serverzertifikat : servercert.pem
# cp /etc/pki/tls/certs/ldap.dmz.nausch.org.crt /etc/pki/ldap/certs/servercert.pem
- unseren Serverschlüssel : serverkey.pem und
# cp /etc/pki/tls/private/private.key /etc/pki/ldap/PRIVATE/serverkey.pem
- das CA-Zertifikat : cacert.pem
# cp /etc/pki/tls/certs/root.crt /etc/pki/ldap/certs/cacert.pem
Abschließend passen wir noch die Datei- und Nutzerberechtigungen an.
# chown root:ldap /etc/pki/openldap/certs/*
# chmod 640 /etc/pki/openldap/certs*
# chown root:ldap /etc/pki/openldap/private/*
# chmod 640 /etc/pki/openldap/private*
Anpassen der /etc/sysconfig/ldap (Server)
Damit unser OpenLDAP-Server zukünftig LDAPS auf Port 636 unter IPv4 zur verfügung stellen kann, bearbeiten wir nun die systemweite Konfigurationsdatei.
# vim /etc/sysconfig/ldap
- /etc/sysconfig/ldap
# Options of slapd (see man slapd) #SLAPD_OPTIONS= # Django : 2011-11-11 LDAPs - Konfiguration # default : SLAPD_OPTIONS= # Nur IPv4 Unterstützung aktiviert SLAPD_OPTIONS="-4" # options of slurpd (see man slurpd) # #SLURPD_OPTIONS= # At least one of SLAPD_LDAP, SLAPD_LDAPI and SLAPD_LDAPS must be set to 'yes'! # # Run slapd with -h "... ldap:/// ..." # yes/no, default: yes #SLAPD_LDAP=yes # Run slapd with -h "... ldapi:/// ..." # yes/no, default: no #SLAPD_LDAPI=no # Run slapd with -h "... ldaps:/// ..." # yes/no, default: no #SLAPD_LDAPS=no # Django : 2011-11-11 LDAPs - Konfiguration # default : SLAPD_LDAPS=no SLAPD_LDAPS=yes # Run slapd with -h "... $SLAPD_URLS ..." # This option could be used instead of previous three ones, but: # - it doesn't overwrite settings of $SLAPD_LDAP, $SLAPD_LDAPS and $SLAPD_LDAPI options # - it isn't overwritten by settings of $SLAPD_LDAP, $SLAPD_LDAPS and $SLAPD_LDAPI options # example: SLAPD_URLS="ldapi:///var/lib/ldap_root/ldapi ldapi:/// ldaps:///" # default: empty #SLAPD_URLS="" # Maximum allowed time to wait for slapd shutdown on 'service ldap stop' (in seconds) #SLAPD_SHUTDOWN_TIMEOUT=3 # Parameters to ulimit called right before starting slapd # - use this to change system limits for slapd #SLAPD_ULIMIT_SETTINGS=""
Nähere Informationen zu den möglichen Parametern entnehmen wir der zugehörigen Manpage.
# man slapd
LDAPS Konfiguration .LDIF
Da wir unsere Konfiguration des OpenLDAP-Servers mit Hilfe von .LDIF-Datreien realisiert haben, werden wir nun eine passende .LDIF-Datei erstellen und diese anschließend in das System importieren.
# vim /etc/openldap/ldif/TLS.ldif
- /etc/openldap/ldif/TLS.ldif
dn: cn=config changetype: modify add: olcTLSCipherSuite olcTLSCipherSuite: HIGH - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/pki/openldap/certs/servercert.pem - add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/pki/openldap/private/serverkey.pem - add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/pki/openldap/certs/cacert.pem
Anschließend importieren wir unsere LDIF-Konfigurationsdatei in den laufenden OpenLDAP-Server
# ldapmodify -W -x -D cn=config -f /etc/openldap/ldif/TLS.ldif
Enter LDAP Password: modifying entry "cn=config"
Mit einer LDAP-Suche im OpenLDAP-Server mit dem CommonNAme config können wir uns davon überzeugen, dass der Import entsprechend geklappt hat.
# ldapsearch -W -x -D cn=config -b cn=config "(objectclass=olcGlobal)"
Enter LDAP Password: # extended LDIF # # LDAPv3 # base <cn=config> with scope subtree # filter: (objectclass=olcGlobal) # requesting: ALL # # config dn: cn=config objectClass: olcGlobal cn: config olcConfigFile: /etc/openldap/slapd.conf olcConfigDir: /etc/openldap/slapd.d olcAllows: bind_v2 olcArgsFile: /var/run/openldap/slapd.args olcAttributeOptions: lang- olcAuthzPolicy: none olcConcurrency: 0 olcConnMaxPending: 100 olcConnMaxPendingAuth: 1000 olcDisallows: bind_anon olcGentleHUP: FALSE olcIdleTimeout: 15 olcIndexSubstrIfMaxLen: 4 olcIndexSubstrIfMinLen: 2 olcIndexSubstrAnyLen: 4 olcIndexSubstrAnyStep: 2 olcIndexIntLen: 4 olcLocalSSF: 71 olcLogLevel: Stats olcPidFile: /var/run/openldap/slapd.pid olcReadOnly: FALSE olcReferral: ldap://ldap.dmz.nausch.org olcRequires: authc olcReverseLookup: FALSE olcSaslSecProps: noplain,noanonymous olcSockbufMaxIncoming: 262143 olcSockbufMaxIncomingAuth: 16777215 olcThreads: 16 olcTLSCRLCheck: none olcTLSVerifyClient: never olcToolThreads: 1 olcWriteTimeout: 0 olcTLSCipherSuite: HIGH olcTLSCertificateFile: /etc/pki/openldap/certs/servercert.pem olcTLSCertificateKeyFile: /etc/pki/openldap/private/serverkey.pem olcTLSCACertificateFile: /etc/pki/openldap/certs/cacert.pem # search result search: 2 result: 0 Success # numResponses: 2 # numEntries: 1
Aktivierung der OpenLDAP-Konfiguration
Damit nun unser OpenLDAP-server auch wirklich LDAPS sprechen kann müssen wir diesen nun einmal durchstarten.
# service slapd restart
Stopping slapd: [ OK ] Starting slapd: [ OK ]
Ob nun der OpenLDAP-Server auch auf den beiden Ports 389 und 636 lauscht überprüfen wir mit Hilfe des Programmes netstat.
# netstat -tulpen | grep slapd
tcp 0 0 0.0.0.0:636 0.0.0.0:* LISTEN 0 65657 27311/slapd tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN 0 65655 27311/slapd
Unser verwendetes CAcert Serverzertifikat können wir mit Hilfe von openssl überprüfen.
# openssl s_client -connect ldap.dmz.nausch.org:636 -showcerts -state -CAfile /etc/pki/openldap/certs/cacert.pem -cert /etc/pki/openldap/certs/servercert.pem -key /etc/pki/openldap/private/serverkey.pem
CONNECTED(00000003) SSL_connect:before/connect initialization SSL_connect:SSLv2/v3 write client hello A SSL_connect:SSLv3 read server hello A depth=1 O = Root CA, OU = http://www.cacert.org, CN = CA Cert Signing Authority, emailAddress = support@cacert.org verify return:1 depth=0 CN = ldap.dmz.nausch.org verify return:1 SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read server session ticket A SSL_connect:SSLv3 read finished A --- Certificate chain 0 s:/CN=ldap.dmz.nausch.org i:/O=Root CA/OU=http://www.cacert.org/CN=CA Cert Signing Authority/emailAddress=support@cacert.org -----BEGIN CERTIFICATE----- MIIE4TCCAsmgAwIBAgIDCvFhMA0GCSqGSIb3DQEBBQUAMHkxEDAOBgNVBAoTB1Jv b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y dEBjYWNlcnQub3JnMB4XDTExMTExMDIxMTMyMFoXDTEzMTEwOTIxMTMyMFowHjEc MBoGA1UEAxMTbGRhcC5kbXoubmF1c2NoLm9yZzCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAMm8BoT246isZpY6mz+VU6WQS75NHJBSuYQcrh1O8JuheAq3 2XpVRqO4uIEhAcyrqMjR2Sjg4XqOlx39mAtbnvN1Era7Cb2geTNRQsagmINA2LOu 7zt4CsKE92KdQhgohnS/Tm6K4I5ssXMFK1UhtCD9uu2eBFNYNgWHf0B7AVRVh3yX o+bUbTL0Lt2CSpA0dnNauT+rPpC3gOjaEXEtOFOIMOtIz+UkCxLsXh1baG3Hjgio hq8EfN9yrlg7wpNo2b1IUWaqIYEkcl0l+f9+eCPIkMgw2PhR4e4Xlw8h2ffd/Cfw TFeNYH37bJ8JvSd2PWzpcZsosMCqblOdjkz1XE8CAwEAAaOBzDCByTAMBgNVHRMB Af8EAjAAMDQGA1UdJQQtMCsGCCsGAQUFBwMCBggrBgEFBQcDAQYJYIZIAYb4QgQB BgorBgEEAYI3CgMDMAsGA1UdDwQEAwIFoDAzBggrBgEFBQcBAQQnMCUwIwYIKwYB BQUHMAGGF2h0dHA6Ly9vY3NwLmNhY2VydC5vcmcvMEEGA1UdEQQ6MDiCE2xkYXAu ZG16Lm5hdXNjaC5vcmegIQYIKwYBBQUHCAWgFQwTbGRhcC5kbXoubmF1c2NoLm9y ZzANBgkqhkiG9w0BAQUFAAOCAgEAk4eKyTcz/uoK4cXvG6GaZzfBp+iohwE/KeLs mLI1LN0XUfouIOhfV6vNnRoH+Odus+wy25FRbnYAYKJNPCyIY9iH5iKH988rx2oQ +XtVUHuD0dOOuDi4fIhXyXjfPGYJ3hI5TYTH7eU2bv+2egNr0dnrgOZPgN9ql1yP H7moM+8I7zMYrISUzjGdvJNpXIXQlvu/jLRCtJRUoDfa5CYK5XjxGrCdWFupMUYu jcKNvnhOPLtcy5C7L0HfYfjNvYMDGFhBgho74mX5Z7qkQw6chQwdSoDENsHxdQOa AkGjubQ6wEaI36BN4IG7zu4nSI1sn0r76JBOeeAglLJnGT7+y0CPnExuo/Pa8hzd N4S6BlSKHU0vvfk3FxEQZ3osV0aIzr+8qPTK7CmsDLplZfvvUiWJ8XduutiBvmSe AWX0dufY8AtlyoGTZRSGo3dvLK1rxvElxRQrFP2y7HN7NhMl2MjyHRW92nJoet4H RnL+mEZW0FmLYPD/FzD1axYf5bwcgz8fQuJSD3dXPpSWhsqVODFfGhQPQwPLaKTl Pj32C6BqHcWBpUWddyF3hAzLolNmgWYZnCXru0GDJ/qrm/z7NFQWTSLpeU4SW4au T1CdPEwqXapAvRxcerm6xUHomoBrm5Rp+yTnbOoL4CPhuT8bNJimazTFTaNZRfP4 g5lnaak= -----END CERTIFICATE----- 1 s:/O=Root CA/OU=http://www.cacert.org/CN=CA Cert Signing Authority/emailAddress=support@cacert.org i:/O=Root CA/OU=http://www.cacert.org/CN=CA Cert Signing Authority/emailAddress=support@cacert.org -----BEGIN CERTIFICATE----- MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ 8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6 zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7 w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826 YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0 IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0 dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg 18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD -----END CERTIFICATE----- --- Server certificate subject=/CN=ldap.dmz.nausch.org issuer=/O=Root CA/OU=http://www.cacert.org/CN=CA Cert Signing Authority/emailAddress=support@cacert.org --- No client certificate CA names sent --- SSL handshake has read 3445 bytes and written 439 bytes --- New, TLSv1/SSLv3, Cipher is AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported Compression: zlib compression Expansion: zlib compression SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: 9501557C4CDF9E555B52430A74226B9E2C8F28C4DCC81786E8BC092BB4694CD7 Session-ID-ctx: Master-Key: C17E92622EF087873AB9D3D13AAE9DB96D41491C2D97CBA0B95F0FF16A219FE51AF3A559E7AE1666FAD5B54602EE4778 Key-Arg : None Krb5 Principal: None PSK identity: None PSK identity hint: None TLS session ticket: 0000 - 89 36 bc f1 45 7d 8b de-23 88 7b 01 2e ba e6 8b .6..E}..#.{..... 0010 - 38 72 be ca c8 37 cf e0-56 16 eb 8f be 54 f3 91 8r...7..V....T.. 0020 - 7e c6 f6 eb 1a 82 b8 87-8b 5c 10 ef 2c 4a 8b ef ~........\..,J.. 0030 - cc 55 03 dd 6b 25 77 7e-81 68 c7 f2 01 fc 23 e2 .U..k%w~.h....#. 0040 - 98 88 8b a7 69 e6 79 6b-ae ae 77 54 f2 7e ab 54 ....i.yk..wT.~.T 0050 - 70 e1 5a 31 98 b9 dd 42-4a 64 cd 2f e6 d5 2f 77 p.Z1...BJd./../w 0060 - 0d 6d 5f 44 c0 bc fa 85-9b 38 ba 53 68 06 4c fe .m_D.....8.Sh.L. 0070 - 41 93 80 28 af 56 0a ed-47 2b 89 32 b9 65 34 0c A..(.V..G+.2.e4. 0080 - d8 00 a4 86 b8 db d3 40-33 0e 3c db 97 ed 01 2b .......@3.<....+ 0090 - f1 92 fe ea a0 d2 03 4d-11 b8 90 fb a7 be c6 5a .......M.......Z 00a0 - 3a aa b7 54 f8 fd 70 18-df 1e 36 40 4e 97 02 12 :..T..p...6@N... Compression: 1 (zlib compression) Start Time: 1321002877 Timeout : 300 (sec) Verify return code: 0 (ok) --- SSL3 alert read:warning:close notify closed SSL3 alert write:warning:close notify
Anpassen der /etc/openldap/ldap.conf (Client)
Für die Konfiguration des LADP-Clients auf dem Server, erweitern wir die betreffende Konfigurationsdatei im Verzeichnis /etc/openladp/.
# vim /etc/openldap/ldap.conf
- /etc/openldap/ldap.conf
# # LDAP Defaults # # See ldap.conf(5) for details # This file should be world readable but not world writable. #BASE dc=example, dc=com #URI ldap://ldap.example.com ldap://ldap-master.example.com:666 # Django: 2011-10-26 BASE dc=nausch, dc=org # Definition des standardmäßig abgefragten Teilbaums / Searchbase # Anfragen werden unterhalb von dc=nausch, dc=org ausgeführt. URI ldap://ldap.dmz.nausch.org # Definition des LDAP-Servers # Django: 2011-11-11 LDAPs Konfigiuration # TLS_REQCERT allow # Specifies what checks to perform on server certificates in a TLS session, if any. # The server certificate is requested. If no certificate is provided, the session proceeds normally. If a bad # certificate is provided, it will be ignored and the session proceeds normally. TLS_REQCERT allow #SIZELIMIT 12 #TIMELIMIT 15 #DEREF never
Konfigurationstest
Nun ist es an der Zeit unsere erste Suchanfrage über unseren neu geschaffenen verschlüsselten Weg an unseren OpenLDAP-Server zu richten:
# ldapsearch -x -LLL -H ldaps://ldap.dmz.nausch.org -b "dc=nausch,dc=org" "uid=django" -W -D "cn=Technischeruser,dc=nausch,dc=org"
Enter LDAP Password: dn: uid=django,ou=People,dc=nausch,dc=org uid: django cn: Django objectClass: account objectClass: posixAccount objectClass: top objectClass: shadowAccount userPassword:: e2NyeXB0fSQ2JENna3VQVFplJDRiT2wvR2dSMUg4OWlxQjRtaU4yYVN5VndHUWE 2SVlubW40eGlGdzJkVjRsbWNKakRoYzlxd2tFYWJQdTZUL1BITWNXcWFLbW9KUnd6NlhwVTd3Vm0x shadowLastChange: 15272 shadowMin: 0 shadowMax: 99999 shadowWarning: 7 loginShell: /bin/bash uidNumber: 500 gidNumber: 500 homeDirectory: /home/django gecos: Django
Im LDAP-Log wird unsere erfolgreiche verschlüsselte Abfrage über Port 636 entsprechend dokumentiert.
# tail -f /var/log/ldap.log
Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 fd=16 ACCEPT from IP=10.0.0.30:60097 (IP=0.0.0.0:636) Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 fd=16 TLS established tls_ssf=256 ssf=256 Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 op=0 BIND dn="cn=Technischeruser,dc=nausch,dc=org" method=128 Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 op=0 BIND dn="cn=Technischeruser,dc=nausch,dc=org" mech=SIMPLE ssf=0 Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 op=0 RESULT tag=97 err=0 text= Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 op=1 SRCH base="dc=nausch,dc=org" scope=2 deref=0 filter="(uid=django)" Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text= Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 op=2 UNBIND Nov 11 10:21:12 vml000030 slapd[27311]: conn=12 fd=16 closed
Clientkonfiguration (LDAPS Auth mit techn. User)
Bei der Absicherung unserer Clientabfragen mittels TLS setzen wir auf unsere bereits vorhanden Grundinstallation mit einem technischen User auf.
Die abschließende Konfiguration nehmen wir mit Hilfe vom system-config-authentication vor.
# system-config-authentication
In dem folgendem Fenster aktivieren wir erst einmal die notwendige TLS-Verschlüsselung, in dem wir die [Auswahlbox]] bei Use TLS to mencrypt connections anwählen.
Als nächstes müssen wir noch das Rootzertifikat der CA herunterladen, damit der Client später seine Anfragen mit Hilfe dieses Zertifikates verschlüsseln und an den OpenLDAP-Server übertragen kann. Wir wählen hier zu den Menüpunkt Download CA Certificate… aus.
Dort tragen wir die URL des Class 1 PKI Keys http://www.cacert.org/certs/root.crt ein.
Abschließend verlassen wir das Konfigurationsfenster in dem wir die Schaltfläche Apply anwählen.
Mit Hilfe eines geschickten Find-Befehles ermitteln wir nun, welche Konfigurationsdateien durch die vorangegangene Konfiguration in der GUI von system-config-authentication angetastet wurden.
# find -type f -printf '%TY.%Tm.%Td %p\n' | sort -nr | more
2011.11.11 ./pam_ldap.conf 2011.11.11 ./pam.d/system-auth-ac 2011.11.11 ./pam.d/smartcard-auth-ac 2011.11.11 ./pam.d/password-auth-ac 2011.11.11 ./pam.d/fingerprint-auth-ac 2011.11.11 ./openldap/ldap.conf 2011.11.11 ./openldap/cacerts/authconfig_downloaded.pem 2011.11.10 ./sysconfig/authconfig 2011.11.10 ./nsswitch.conf
pam_ldap.conf
In der Konfigurationsdatei /etc/pam_ldap.conf tragen wir folgende Daten nach:
- binddn dc=nausch,dc=org
- bindpw Klaus-ist-der-groesste!
- ssl start_tls
- tls_cacertdir /etc/openldap/cacerts
- pam_password sha512
Zur Bearbeitung der Konfigurationsdatei nutzen wir wie so oft immer unseren Editor der Wahl vim.
# vim /etc/pam_ldap.conf
- /etc/pam_ldap.conf
# @(#)$Id: ldap.conf,v 1.38 2006/05/15 08:13:31 lukeh Exp $ # # This is the configuration file for the LDAP nameservice # switch library and the LDAP PAM module. # # The man page for this file is pam_ldap(5) # # PADL Software # http://www.padl.com # # Your LDAP server. Must be resolvable without using LDAP. # Multiple hosts may be specified, each separated by a # space. How long nss_ldap takes to failover depends on # whether your LDAP client library supports configurable # network or connect timeouts (see bind_timelimit). # Django : 2011-10-28 LDAP Client-Authentication # default : host 127.0.0.1 # The distinguished name of the search base. # Django : 2011-11-10 LDAP Client-Authentication # base dc=example,dc=com binddn dc=nausch,dc=org # Another way to specify your LDAP server is to provide an # uri with the server name. This allows to use # Unix Domain Sockets to connect to a local LDAP Server. #uri ldap://127.0.0.1/ #uri ldaps://127.0.0.1/ #uri ldapi://%2fvar%2frun%2fldapi_sock/ # Note: %2f encodes the '/' used as directory separator # The LDAP version to use (defaults to 3 # if supported by client library) #ldap_version 3 # The distinguished name to bind to the server with. # Optional: default is to bind anonymously. #binddn cn=proxyuser,dc=example,dc=com # The credentials to bind with. # Optional: default is no credential. #bindpw secret # Django : 2011-11-10 LDAP Client-Authentication bindpw Klaus-ist-der-groesste! # The distinguished name to bind to the server with # if the effective user ID is root. Password is # stored in /etc/ldap.secret (mode 600) #rootbinddn cn=manager,dc=example,dc=com # The port. # Optional: default is 389. #port 389 # The search scope. #scope sub #scope one #scope base # Search timelimit #timelimit 30 # Bind/connect timelimit #bind_timelimit 30 # Reconnect policy: hard (default) will retry connecting to # the software with exponential backoff, soft will fail # immediately. #bind_policy hard # Idle timelimit; client will close connections # (nss_ldap only) if the server has not been contacted # for the number of seconds specified below. #idle_timelimit 3600 # Filter to AND with uid=%s #pam_filter objectclass=account # The user ID attribute (defaults to uid) #pam_login_attribute uid # Search the root DSE for the password policy (works # with Netscape Directory Server) #pam_lookup_policy yes # Check the 'host' attribute for access control # Default is no; if set to yes, and user has no # value for the host attribute, and pam_ldap is # configured for account management (authorization) # then the user will not be allowed to login. #pam_check_host_attr yes # Check the 'authorizedService' attribute for access # control # Default is no; if set to yes, and the user has no # value for the authorizedService attribute, and # pam_ldap is configured for account management # (authorization) then the user will not be allowed # to login. #pam_check_service_attr yes # Group to enforce membership of #pam_groupdn cn=PAM,ou=Groups,dc=example,dc=com # Group member attribute #pam_member_attribute uniquemember # Specify a minium or maximum UID number allowed #pam_min_uid 0 #pam_max_uid 0 # Template login attribute, default template user # (can be overriden by value of former attribute # in user's entry) #pam_login_attribute userPrincipalName #pam_template_login_attribute uid #pam_template_login nobody # HEADS UP: the pam_crypt, pam_nds_passwd, # and pam_ad_passwd options are no # longer supported. # # Do not hash the password at all; presume # the directory server will do it, if # necessary. This is the default. #pam_password clear # Hash password locally; required for University of # Michigan LDAP server, and works with Netscape # Directory Server if you're using the UNIX-Crypt # hash mechanism and not using the NT Synchronization # service. #pam_password crypt # Remove old password first, then update in # cleartext. Necessary for use with Novell # Directory Services (NDS) #pam_password clear_remove_old #pam_password nds # RACF is an alias for the above. For use with # IBM RACF #pam_password racf # Update Active Directory password, by # creating Unicode password and updating # unicodePwd attribute. #pam_password ad # Use the OpenLDAP password change # extended operation to update the password. #pam_password exop # Redirect users to a URL or somesuch on password # changes. #pam_password_prohibit_message Please visit http://internal to change your password. # RFC2307bis naming contexts # Syntax: # nss_base_XXX base?scope?filter # where scope is {base,one,sub} # and filter is a filter to be &'d with the # default filter. # You can omit the suffix eg: # nss_base_passwd ou=People, # to append the default base DN but this # may incur a small performance impact. #nss_base_passwd ou=People,dc=example,dc=com?one #nss_base_shadow ou=People,dc=example,dc=com?one #nss_base_group ou=Group,dc=example,dc=com?one #nss_base_hosts ou=Hosts,dc=example,dc=com?one #nss_base_services ou=Services,dc=example,dc=com?one #nss_base_networks ou=Networks,dc=example,dc=com?one #nss_base_protocols ou=Protocols,dc=example,dc=com?one #nss_base_rpc ou=Rpc,dc=example,dc=com?one #nss_base_ethers ou=Ethers,dc=example,dc=com?one #nss_base_netmasks ou=Networks,dc=example,dc=com?ne #nss_base_bootparams ou=Ethers,dc=example,dc=com?one #nss_base_aliases ou=Aliases,dc=example,dc=com?one #nss_base_netgroup ou=Netgroup,dc=example,dc=com?one # attribute/objectclass mapping # Syntax: #nss_map_attribute rfc2307attribute mapped_attribute #nss_map_objectclass rfc2307objectclass mapped_objectclass # configure --enable-nds is no longer supported. # NDS mappings #nss_map_attribute uniqueMember member # Services for UNIX 3.5 mappings #nss_map_objectclass posixAccount User #nss_map_objectclass shadowAccount User #nss_map_attribute uid msSFU30Name #nss_map_attribute uniqueMember msSFU30PosixMember #nss_map_attribute userPassword msSFU30Password #nss_map_attribute homeDirectory msSFU30HomeDirectory #nss_map_attribute homeDirectory msSFUHomeDirectory #nss_map_objectclass posixGroup Group #pam_login_attribute msSFU30Name #pam_filter objectclass=User #pam_password ad # configure --enable-mssfu-schema is no longer supported. # Services for UNIX 2.0 mappings #nss_map_objectclass posixAccount User #nss_map_objectclass shadowAccount user #nss_map_attribute uid msSFUName #nss_map_attribute uniqueMember posixMember #nss_map_attribute userPassword msSFUPassword #nss_map_attribute homeDirectory msSFUHomeDirectory #nss_map_attribute shadowLastChange pwdLastSet #nss_map_objectclass posixGroup Group #nss_map_attribute cn msSFUName #pam_login_attribute msSFUName #pam_filter objectclass=User #pam_password ad # RFC 2307 (AD) mappings #nss_map_objectclass posixAccount user #nss_map_objectclass shadowAccount user #nss_map_attribute uid sAMAccountName #nss_map_attribute homeDirectory unixHomeDirectory #nss_map_attribute shadowLastChange pwdLastSet #nss_map_objectclass posixGroup group #nss_map_attribute uniqueMember member #pam_login_attribute sAMAccountName #pam_filter objectclass=User #pam_password ad # configure --enable-authpassword is no longer supported # AuthPassword mappings #nss_map_attribute userPassword authPassword # AIX SecureWay mappings #nss_map_objectclass posixAccount aixAccount #nss_base_passwd ou=aixaccount,?one #nss_map_attribute uid userName #nss_map_attribute gidNumber gid #nss_map_attribute uidNumber uid #nss_map_attribute userPassword passwordChar #nss_map_objectclass posixGroup aixAccessGroup #nss_base_group ou=aixgroup,?one #nss_map_attribute cn groupName #nss_map_attribute uniqueMember member #pam_login_attribute userName #pam_filter objectclass=aixAccount #pam_password clear # Netscape SDK LDAPS #ssl on # Netscape SDK SSL options #sslpath /etc/ssl/certs # OpenLDAP SSL mechanism # start_tls mechanism uses the normal LDAP port, LDAPS typically 636 #ssl start_tls #ssl on # OpenLDAP SSL options # Require and verify server certificate (yes/no) # Default is to use libldap's default behavior, which can be configured in # /etc/openldap/ldap.conf using the TLS_REQCERT setting. The default for # OpenLDAP 2.0 and earlier is "no", for 2.1 and later is "yes". #tls_checkpeer yes # CA certificates for server certificate verification # At least one of these are required if tls_checkpeer is "yes" #tls_cacertfile /etc/ssl/ca.cert #tls_cacertdir /etc/ssl/certs # Seed the PRNG if /dev/urandom is not provided #tls_randfile /var/run/egd-pool # SSL cipher suite # See man ciphers for syntax #tls_ciphers TLSv1 # Client certificate and key # Use these, if your server requires client authentication. #tls_cert #tls_key # Disable SASL security layers. This is needed for AD. #sasl_secprops maxssf=0 # Override the default Kerberos ticket cache location. #krb5_ccname FILE:/etc/.ldapcache # SASL mechanism for PAM authentication - use is experimental # at present and does not support password policy control #pam_sasl_mech DIGEST-MD5 # Django : 2011-10-28 LDAP Client-Authentication, automatisch eingetragen mit Hilfe von authconfig uri ldap://ldap.dmz.nausch.org ssl start_tls tls_cacertdir /etc/openldap/cacerts pam_password sha256
system-auth
Es wurden auch folgenden pam.d-Konfigurationsdateien angepasst:
- /etc/pam.d/fingerprint-auth
- /etc/pam.d/password-auth
- /etc/pam.d/smartcard-auth
- /etc/pam.d/smtp
- /etc/pam.d/system-auth
Zur Bearbeitung der Konfigurationsdatei nutzen wir wie so oft immer unseren Editor der Wahl vim.
# vim /etc/pam.d/fingerprint-auth
- /etc/pam.d/fingerprint-auth
#%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth sufficient pam_fprintd.so auth required pam_deny.so account required pam_unix.so broken_shadow account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 500 quiet account [default=bad success=ok user_unknown=ignore] pam_ldap.so account required pam_permit.so password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session optional pam_oddjob_mkhomedir.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so session optional pam_ldap.so
# vim /etc/pam.d/password-auth
- /etc/pam.d/password-auth
#%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid >= 500 quiet auth sufficient pam_ldap.so use_first_pass auth required pam_deny.so account required pam_unix.so broken_shadow account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 500 quiet account [default=bad success=ok user_unknown=ignore] pam_ldap.so account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 type= password sufficient pam_unix.so sha256 shadow nullok try_first_pass use_authtok password sufficient pam_ldap.so use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session optional pam_oddjob_mkhomedir.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so session optional pam_ldap.so
# vim /etc/pam.d/smartcard-auth
- /etc/pam.d/smartcard-auth
#%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth [success=done ignore=ignore default=die] pam_pkcs11.so wait_for_card card_only auth required pam_deny.so account required pam_unix.so broken_shadow account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 500 quiet account [default=bad success=ok user_unknown=ignore] pam_ldap.so account required pam_permit.so password required pam_pkcs11.so session optional pam_keyinit.so revoke session required pam_limits.so session optional pam_oddjob_mkhomedir.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so session optional pam_ldap.so
# vim /etc/pam.d/smtp
- /etc/pam.d/smtp
#%PAM-1.0 auth include password-auth account include password-auth
# vim /etc/pam.d/system-auth
- /etc/pam.d/system-auth
#%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth sufficient pam_fprintd.so auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_succeed_if.so uid >= 500 quiet auth sufficient pam_ldap.so use_first_pass auth required pam_deny.so account required pam_unix.so broken_shadow account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 500 quiet account [default=bad success=ok user_unknown=ignore] pam_ldap.so account required pam_permit.so password requisite pam_cracklib.so try_first_pass retry=3 type= password sufficient pam_unix.so sha256 shadow nullok try_first_pass use_authtok password sufficient pam_ldap.so use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so session optional pam_oddjob_mkhomedir.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so session optional pam_ldap.so
ldap.conf
In der Konfigurationsdatei /etc/openldap/ldap.conf tragen wir folgende Daten nach:
- BASE dc=nausch, dc=org
- TLS_CACERTDIR /etc/openldap/cacerts
Zur Bearbeitung der Konfigurationsdatei nutzen wir wie so oft immer unseren Editor der Wahl vim.
# vim /etc/openldap/ldap.conf
- /etc/openldap/ldap.conf
# # LDAP Defaults # # See ldap.conf(5) for details # This file should be world readable but not world writable. #BASE dc=example, dc=com #URI ldap://ldap.example.com ldap://ldap-master.example.com:666 #SIZELIMIT 12 #TIMELIMIT 15 #DEREF never # Django : 2011-10-28 LDAP Client Authentication BASE dc=nausch, dc=org URI ldap://ldap.dmz.nausch.org TLS_CACERTDIR /etc/openldap/cacerts
authconfig
In der Konfigurationsdatei /etc/sysconfig/authconfig setzen wir die beiden folgenden Werte von no auf yes:
- USELDAP=yes (LDAP-Authentifizierung aktivieren.)
- FORCELEGACY=no (Da wir nun TLS bei der LDAP-Authentifizierung unter CentOS 6 nutzen wollen, setzen wir diem Option FORCELEGACY wieder auf no zurück.
Zur Bearbeitung der Konfigurationsdatei nutzen wir wie so oft immer unseren Editor der Wahl vim.
# vim /etc/sysconfig/authconfig
- /etc/sysconfig/authconfig
USEMKHOMEDIR=no USEPAMACCESS=no CACHECREDENTIALS=yes USESSSDAUTH=no USESHADOW=yes USEWINBIND=no USEDB=no FORCELEGACY=no USEFPRINTD=yes FORCESMARTCARD=no PASSWDALGORITHM=sha512 USELDAPAUTH=no USEPASSWDQC=no USELOCAUTHORIZE=yes USECRACKLIB=yes USEWINBINDAUTH=no USESMARTCARD=no USELDAP=yes USENIS=no USEKERBEROS=no USESYSNETAUTH=no USESMBAUTH=no USESSSD=no USEHESIOD=no
nsswitch.conf
In der Konfigurationsdatei /etc/pam.d/system-auth tragen wir folgende Daten nach:
- passwd: files ldap
- shadow: files ldap
- group: files ldap
- netgroup: ldap
- automount: files ldap
Zur Bearbeitung der Konfigurationsdatei nutzen wir wie so oft immer unseren Editor der Wahl vim.
# vim /etc/nsswitch.conf
- /etc/nsswitch.conf
# # /etc/nsswitch.conf # # An example Name Service Switch config file. This file should be # sorted with the most-used services at the beginning. # # The entry '[NOTFOUND=return]' means that the search for an # entry should stop if the search in the previous entry turned # up nothing. Note that if the search failed due to some other reason # (like no NIS server responding) then the search continues with the # next entry. # # Valid entries include: # # nisplus Use NIS+ (NIS version 3) # nis Use NIS (NIS version 2), also called YP # dns Use DNS (Domain Name Service) # files Use the local files # db Use the local database (.db) files # compat Use NIS on compat mode # hesiod Use Hesiod for user lookups # [NOTFOUND=return] Stop searching if not found so far # # To use db, put the "db" in front of "files" for entries you want to be # looked up first in the databases # # Example: #passwd: db files nisplus nis #shadow: db files nisplus nis #group: db files nisplus nis # Django : 2011-10-28 LDAP Client Authentication # default # passwd: files # shadow: files # group: files passwd: files ldap shadow: files ldap group: files ldap #hosts: db files nisplus nis dns hosts: files dns # Example - obey only what nisplus tells us... #services: nisplus [NOTFOUND=return] files #networks: nisplus [NOTFOUND=return] files #protocols: nisplus [NOTFOUND=return] files #rpc: nisplus [NOTFOUND=return] files #ethers: nisplus [NOTFOUND=return] files #netmasks: nisplus [NOTFOUND=return] files bootparams: nisplus [NOTFOUND=return] files ethers: files netmasks: files networks: files protocols: files rpc: files services: files # Django : 2011-10-28 LDAP Client Authentication # default # netgroup: nisplus netgroup: ldap publickey: nisplus # Django : 2011-10-28 LDAP Client Authentication # default # automount: files nisplus automount: files ldap aliases: files nisplus
Clienttest
Zum Testen unserer Konfiguration starten wir einfach unseren CentOS-6 Host und melden uns an.
Bei Bedarf beobachten wir das LDAP-Logfile auf dem OpenLDAP-Server.
# tail -f /var/log/ldap-log