User Tools

Site Tools


ldap:openldap_openssl

Table of Contents

OpenLDAP with SSL

LDAP Over SSL vs LDAP with STARTTLS

There are two ways to encrypt LDAP connections with SSL/TLS.
Traditionally, LDAP connections that needed to be encrypted were handled on a separate port, typically 636. 
The entire connection would be wrapped with SSL/TLS. This process, called LDAP over SSL, uses the ldaps:// 
protocol. This method of encryption is now deprecated.
STARTTLS is an alternative approach that is now the preferred method of encrypting an LDAP connection. 
STARTTLS "upgrades" a non-encrypted connection by wrapping it with SSL/TLS after/during the connection 
process. This allows unencrypted and encrypted connections to be handled by the same port. This guide will 
utilize STARTTLS to encrypt connections.

Steps

This is not the proper way to create a certificate chain.

1. create a certificate authority
2. create a server certificate
3. sign the server certificate with the CA
4. extract the password from server certificate into a key

https://www.digitalocean.com/community/tutorials/how-to-encrypt-openldap-connections-using-starttls

Generate a certificate OK

TMPDIR=/etc/openldap/ssl/templates
PRIVDIR=/etc/openldap/ssl/private
CERTDIR=/etc/openldap/certs
mkdir -p $TMPDIR
mkdir -p $PRIVDIR
mkdir -p $CERTDIR

cat > $TMPDIR/ca_server.conf << EOF
cn = LDAP Server CA
ca
cert_signing_key
EOF

cat > $TMPDIR/ldap_server.conf << EOF
organization = "My Company Luxembourg"
cn = lnxldap1.tst.com
tls_www_server
encryption_key
signing_key
expiration_days = 3652
EOF

certtool -p --outfile $PRIVDIR/ca_server.key
certtool -s --load-privkey $PRIVDIR/ca_server.key --template $TMPDIR/ca_server.conf --outfile $CERTDIR/ca_server.pem
certtool -p --sec-param high --outfile $PRIVDIR/ldap_server.key
certtool -c --load-privkey $PRIVDIR/ldap_server.key --load-ca-certificate $CERTDIR/ca_server.pem --load-ca-privkey $PRIVDIR/ca_server.key --template $TMPDIR/ldap_server.conf --outfile $CERTDIR/ldap_server.pem
chmod 640 $PRIVDIR/ldap_server.key
chown :ldap $PRIVDIR/ldap_server.key

ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/certs/ca_server.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/ldap_server.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/ssl/private/ldap_server.key
EOF

service slapd force-reload

install certtool

# yum -y install gnutls-utils

install certtool

# certtool --generate-privkey --outfile /etc/pki/CA/private/ca-key.key
# certtool --generate-self-signed --load-privkey /etc/pki/CA/private/ca-key.key --outfile /etc/pki/CA/certs/ca-cert.pem --template /etc/pki/CA/private/cert.cfg
# certtool --generate-privkey --outfile /etc/pki/tls/private/ldap.key
# certtool --generate-certificate --load-privkey /etc/pki/tls/private/ldap.key --outfile /etc/pki/tls/certs/ldap.pem --load-ca-certificate /etc/pki/CA/certs/ca-cert.pem --load-ca-privkey /etc/pki/CA/private/ca-key.key --template /etc/pki/CA/private/cert.cfg

cat cert.cfg

# X.509 Certificate options
#
# DN options

# The organization of the subject.
organization = "Koko inc."

# The organizational unit of the subject.
unit = "sleeping dept."

# The locality of the subject.
# locality =

# The state of the certificate owner.
state = "Attiki"

# The country of the subject. Two letter code.
country = GR

# The common name of the certificate owner.
cn = "Cindy Lauper"

# A user id of the certificate owner.
#uid = "clauper"

# Set domain components
#dc = "name"
#dc = "domain"

# If the supported DN OIDs are not adequate you can set
# any OID here.
# For example set the X.520 Title and the X.520 Pseudonym
# by using OID and string pairs.
#dn_oid = "2.5.4.12 Dr."
#dn_oid = "2.5.4.65 jackal"

# This is deprecated and should not be used in new
# certificates.
# pkcs9_email = "none@none.org"

# An alternative way to set the certificate's distinguished name directly
# is with the "dn" option. The attribute names allowed are:
# C (country), street, O (organization), OU (unit), title, CN (common name),
# L (locality), ST (state), placeOfBirth, gender, countryOfCitizenship, 
# countryOfResidence, serialNumber, telephoneNumber, surName, initials, 
# generationQualifier, givenName, pseudonym, dnQualifier, postalCode, name, 
# businessCategory, DC, UID, jurisdictionOfIncorporationLocalityName, 
# jurisdictionOfIncorporationStateOrProvinceName,
# jurisdictionOfIncorporationCountryName, XmppAddr, and numeric OIDs.

#dn = "cn = Nikos,st = New\, Something,C=GR,surName=Mavrogiannopoulos,2.5.4.9=Arkadias"

# The serial number of the certificate
# Comment the field for a time-based serial number.
serial = 007

# In how many days, counting from today, this certificate will expire.
# Use -1 if there is no expiration date.
expiration_days = 700

# Alternatively you may set concrete dates and time. The GNU date string 
# formats are accepted. See:
# http://www.gnu.org/software/tar/manual/html_node/Date-input-formats.html

#activation_date = "2004-02-29 16:21:42"
#expiration_date = "2025-02-29 16:24:41"

# X.509 v3 extensions

# A dnsname in case of a WWW server.
#dns_name = "www.none.org"
#dns_name = "www.morethanone.org"

# An othername defined by an OID and a hex encoded string
#other_name = "1.3.6.1.5.2.2 302ca00d1b0b56414e5245494e2e4f5247a11b3019a006020400000002a10f300d1b047269636b1b0561646d696e"
#other_name_utf8 = "1.2.4.5.6 A UTF8 string"
#other_name_octet = "1.2.4.5.6 A string that will be encoded as ASN.1 octet string"

# Allows writing an XmppAddr Identifier
#xmpp_name = juliet@im.example.com

# Names used in PKINIT
#krb5_principal = user@REALM.COM
#krb5_principal = HTTP/user@REALM.COM

# A subject alternative name URI
#uri = "http://www.example.com"

# An IP address in case of a server.
#ip_address = "192.168.1.1"

# An email in case of a person
email = "none@none.org"

# TLS feature (rfc7633) extension. That can is used to indicate mandatory TLS
# extension features to be provided by the server. In practice this is used
# to require the Status Request (extid: 5) extension from the server. That is,
# to require the server holding this certificate to provide a stapled OCSP response.
# You can have multiple lines for multiple TLS features.

# To ask for OCSP status request use:
#tls_feature = 5

# Challenge password used in certificate requests
challenge_password = 123456

# Password when encrypting a private key
#password = secret

# An URL that has CRLs (certificate revocation lists)
# available. Needed in CA certificates.
#crl_dist_points = "http://www.getcrl.crl/getcrl/"

# Whether this is a CA certificate or not
#ca

# Subject Unique ID (in hex)
#subject_unique_id = 00153224

# Issuer Unique ID (in hex)
#issuer_unique_id = 00153225

#### Key usage

# The following key usage flags are used by CAs and end certificates

# Whether this certificate will be used to sign data (needed
# in TLS DHE ciphersuites). This is the digitalSignature flag
# in RFC5280 terminology.
signing_key

# Whether this certificate will be used to encrypt data (needed
# in TLS RSA ciphersuites). Note that it is preferred to use different
# keys for encryption and signing. This is the keyEncipherment flag
# in RFC5280 terminology.
encryption_key

# Whether this key will be used to sign other certificates. The
# keyCertSign flag in RFC5280 terminology.
#cert_signing_key

# Whether this key will be used to sign CRLs. The
# cRLSign flag in RFC5280 terminology.
#crl_signing_key

# The keyAgreement flag of RFC5280. It's purpose is loosely
# defined. Not use it unless required by a protocol.
#key_agreement

# The dataEncipherment flag of RFC5280. It's purpose is loosely
# defined. Not use it unless required by a protocol.
#data_encipherment

# The nonRepudiation flag of RFC5280. It's purpose is loosely
# defined. Not use it unless required by a protocol.
#non_repudiation

#### Extended key usage (key purposes)

# The following extensions are used in an end certificate
# to clarify its purpose. Some CAs also use it to indicate
# the types of certificates they are purposed to sign.


# Whether this certificate will be used for a TLS client;
# this sets the id-kp-serverAuth (1.3.6.1.5.5.7.3.1) of 
# extended key usage.
#tls_www_client

# Whether this certificate will be used for a TLS server;
# This sets the id-kp-clientAuth (1.3.6.1.5.5.7.3.2) of 
# extended key usage.
#tls_www_server

# Whether this key will be used to sign code. This sets the
# id-kp-codeSigning (1.3.6.1.5.5.7.3.3) of extended key usage
# extension.
#code_signing_key

# Whether this key will be used to sign OCSP data. This sets the
# id-kp-OCSPSigning (1.3.6.1.5.5.7.3.9) of extended key usage extension.
#ocsp_signing_key

# Whether this key will be used for time stamping. This sets the
# id-kp-timeStamping (1.3.6.1.5.5.7.3.8) of extended key usage extension.
#time_stamping_key

# Whether this key will be used for email protection. This sets the
# id-kp-emailProtection (1.3.6.1.5.5.7.3.4) of extended key usage extension.
#email_protection_key

# Whether this key will be used for IPsec IKE operations (1.3.6.1.5.5.7.3.17).
#ipsec_ike_key

## adding custom key purpose OIDs

# for microsoft smart card logon
# key_purpose_oid = 1.3.6.1.4.1.311.20.2.2

# for email protection
# key_purpose_oid = 1.3.6.1.5.5.7.3.4

# for any purpose (must not be used in intermediate CA certificates)
# key_purpose_oid = 2.5.29.37.0

### end of key purpose OIDs

### Adding arbitrary extensions
# This requires to provide the extension OIDs, as well as the extension data in
# hex format. The following two options are available since GnuTLS 3.5.3.
#add_extension = "1.2.3.4 0x0AAB01ACFE"

# As above but encode the data as an octet string
#add_extension = "1.2.3.4 octet_string(0x0AAB01ACFE)"

# For portability critical extensions shouldn't be set to certificates.
#add_critical_extension = "5.6.7.8 0x1AAB01ACFE"

# When generating a certificate from a certificate
# request, then honor the extensions stored in the request
# and store them in the real certificate.
#honor_crq_extensions

# Alternatively only specific extensions can be copied.
#honor_crq_ext = 2.5.29.17
#honor_crq_ext = 2.5.29.15

# Path length contraint. Sets the maximum number of
# certificates that can be used to certify this certificate.
# (i.e. the certificate chain length)
#path_len = -1
#path_len = 2

# OCSP URI
# ocsp_uri = http://my.ocsp.server/ocsp

# CA issuers URI
# ca_issuers_uri = http://my.ca.issuer

# Certificate policies
#policy1 = 1.3.6.1.4.1.5484.1.10.99.1.0
#policy1_txt = "This is a long policy to summarize"
#policy1_url = http://www.example.com/a-policy-to-read

#policy2 = 1.3.6.1.4.1.5484.1.10.99.1.1
#policy2_txt = "This is a short policy"
#policy2_url = http://www.example.com/another-policy-to-read

# Name constraints

# DNS
#nc_permit_dns = example.com
#nc_exclude_dns = test.example.com

# EMAIL
#nc_permit_email = "nmav@ex.net"

# Exclude subdomains of example.com
#nc_exclude_email = .example.com

# Exclude all e-mail addresses of example.com
#nc_exclude_email = example.com

# IP
#nc_permit_ip = 192.168.0.0/16
#nc_exclude_ip = 192.168.5.0/24
#nc_permit_ip = fc0a:eef2:e7e7:a56e::/64


# Options for proxy certificates
#proxy_policy_language = 1.3.6.1.5.5.7.21.1


# Options for generating a CRL

# The number of days the next CRL update will be due.
# next CRL update will be in 43 days
#crl_next_update = 43

# this is the 5th CRL by this CA
# Comment the field for a time-based number.
#crl_number = 5

# Specify the update dates more precisely.
#crl_this_update_date = "2004-02-29 16:21:42"
#crl_next_update_date = "2025-02-29 16:24:41"

# The date that the certificates will be made seen as
# being revoked.
#crl_revocation_date = "2025-02-29 16:24:41"
chmod 640 /etc/pki/tls/certs/ldap.pem
chmod 640 /etc/pki/tls/private/ldap.key
chmod 644 /etc/pki/CA/certs/ca-cert.pem
chgrp ldap /etc/pki/tls/certs/ldap.pem
chgrp ldap /etc/pki/tls/private/ldap.key
chgrp ldap /etc/pki/CA/certs/ca-cert.pem

Verify the certificate:

# certtool --certificate-info --infile /etc/pki/CA/certs/ca-cert.pem 
# openssl x509 -noout -text -in /etc/pki/CA/certs/ca-cert.pem

Apply olcTLS directive in LDAP server configuration:

[root@rhldap1 private]# ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/pki/tls/certs/ldap.pem
EOF
modifying entry "cn=config"

[root@rhldap1 private]# ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=config
changetype: modify
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/pki/tls/private/ldap.key
EOF
modifying entry "cn=config"

[root@rhldap1 private]# ldapmodify -Q -Y EXTERNAL -H ldapi:/// <<EOF
dn: cn=config
changetype: modify
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/pki/CA/certs/ca-cert.pem
EOF
modifying entry "cn=config"

[root@rhldap1 private]# ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config | grep olcTLS
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
olcTLSCipherSuite: HIGH:MEDIUM:-SSLv2
olcTLSVerifyClient: demand
olcTLSCertificateFile: /etc/pki/tls/certs/ldap.pem
olcTLSCertificateKeyFile: /etc/pki/tls/private/ldap.key
olcTLSCACertificateFile: /etc/pki/CA/certs/ca-cert.pem

Check you config

[root@rhldap1 private]#  gnutls-cli-debug -p 636 localhost
unknown protocol ldaps
Checking for SSL 3.0 support... yes
unknown protocol ldaps
Checking whether %COMPAT is required... no
unknown protocol ldaps
Checking for TLS 1.0 support... yes
unknown protocol ldaps
Checking for TLS 1.1 support... yes
unknown protocol ldaps
Checking fallback from TLS 1.1 to... N/A
Checking for TLS 1.2 support... yes
unknown protocol ldaps
Checking whether we need to disable TLS 1.2... N/A
Checking whether we need to disable TLS 1.1... N/A
Checking whether we need to disable TLS 1.0... N/A
Checking for Safe renegotiation support... no
unknown protocol ldaps
Checking for Safe renegotiation support (SCSV)... yes
unknown protocol ldaps
Checking for HTTPS server name... not checked
unknown protocol ldaps
Checking for version rollback bug in RSA PMS... dunno
unknown protocol ldaps
Checking for version rollback bug in Client Hello... no
unknown protocol ldaps
Checking whether the server ignores the RSA PMS version... yes
unknown protocol ldaps
Checking whether the server can accept Hello Extensions... yes
unknown protocol ldaps
Checking whether the server can accept HeartBeat Extension... yes
unknown protocol ldaps
Checking whether the server can accept small records (512 bytes)... yes
unknown protocol ldaps
Checking whether the server can accept cipher suites not in SSL 3.0 spec... yes
unknown protocol ldaps
Checking whether the server can accept a bogus TLS record version in the client hello... yes
unknown protocol ldaps
Checking for certificate information... N/A
Checking for trusted CAs... N/A
Checking whether the server understands TLS closure alerts... partially
unknown protocol ldaps
Checking whether the server supports session resumption... no
unknown protocol ldaps
Checking for anonymous authentication support... no
unknown protocol ldaps
Checking anonymous Diffie-Hellman group info... N/A
Checking for ephemeral Diffie-Hellman support... yes
unknown protocol ldaps
Checking ephemeral Diffie-Hellman group info... N/A
Checking for ephemeral EC Diffie-Hellman support... yes
unknown protocol ldaps
Checking ephemeral EC Diffie-Hellman group info...
 Curve SECP256R1
unknown protocol ldaps
Checking for AES-128-GCM cipher support... yes
unknown protocol ldaps
Checking for AES-128-CBC cipher support... yes
unknown protocol ldaps
Checking for CAMELLIA-128-GCM cipher support... no
unknown protocol ldaps
Checking for CAMELLIA-128-CBC cipher support... yes
unknown protocol ldaps
Checking for 3DES-CBC cipher support... yes
unknown protocol ldaps
Checking for ARCFOUR 128 cipher support... yes
unknown protocol ldaps
Checking for MD5 MAC support... yes
unknown protocol ldaps
Checking for SHA1 MAC support... yes
unknown protocol ldaps
Checking for SHA256 MAC support... yes
unknown protocol ldaps
Checking for ZLIB compression support... no
unknown protocol ldaps
Checking for max record size... no
unknown protocol ldaps
Checking for OpenPGP authentication support... no
[root@rhldap1 private]# nmap -Pn -p T:636 --script ssl-enum-ciphers localhost

Starting Nmap 6.40 ( http://nmap.org ) at 2016-12-13 15:01 CET
Nmap scan report for localhost (127.0.0.1)
Host is up (-1400s latency).
Other addresses for localhost (not scanned): 127.0.0.1
PORT    STATE SERVICE
636/tcp open  ldapssl
| ssl-enum-ciphers:
|   TLSv1.2:
|     ciphers:
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - strong
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - strong
|       TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - strong
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - strong
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - strong
|       TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong
|       TLS_RSA_WITH_AES_128_CBC_SHA - strong
|       TLS_RSA_WITH_AES_128_CBC_SHA256 - strong
|       TLS_RSA_WITH_AES_128_GCM_SHA256 - strong
|       TLS_RSA_WITH_AES_256_CBC_SHA - strong
|       TLS_RSA_WITH_AES_256_CBC_SHA256 - strong
|       TLS_RSA_WITH_AES_256_GCM_SHA384 - strong
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - strong
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - strong
|       TLS_RSA_WITH_RC4_128_MD5 - strong
|       TLS_RSA_WITH_RC4_128_SHA - strong
|       TLS_RSA_WITH_SEED_CBC_SHA - strong
|     compressors:
|       NULL
|_  least strength: strong

Nmap done: 1 IP address (1 host up) scanned in 0.71 seconds

https://www.gnutls.org/manual/html_node/certtool-Invocation.html

http://www.itzgeek.com/how-tos/linux/centos-how-tos/step-step-openldap-server-configuration-centos-7-rhel-7.html

https://help.ubuntu.com/lts/serverguide/openldap-server.html

ldap/openldap_openssl.txt · Last modified: 2021/01/01 21:25 (external edit)