Skip to content

Instantly share code, notes, and snippets.

@magnetikonline
Last active December 14, 2023 05:56
Star You must be signed in to star a gist
Save magnetikonline/0ccdabfec58eb1929c997d22e7341e45 to your computer and use it in GitHub Desktop.
Enable LDAP over SSL (LDAPS) for Microsoft Active Directory servers.

Enable LDAP over SSL (LDAPS) for Microsoft Active Directory servers

Microsoft active directory servers will default to offer LDAP connections over unencrypted connections (boo!).

The steps below will create a new self signed certificate appropriate for use with and thus enabling LDAPS for an AD server. Of course the "self-signed" portion of this guide can be swapped out with a real vendor purchased certificate if required.

Steps have been tested successfully with Windows Server 2012R2, but should work with Windows Server 2008 without modification. Requires a working OpenSSL install (ideally Linux/OSX) and (obviously) a Windows Active Directory server.

Create root certificate

Using OpenSSL, create new private key and root certificate. Answer country/state/org questions as suitable:

$ openssl genrsa -aes256 -out ca.key 4096
$ openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

Hold onto the resulting ca.key and ca.crt.

Import root certificate into trusted store of domain controller

  • From the active directory server, open Manage computer certificates.
  • Add the generated ca.crt to the certificate path Trusted Root Certification Authorities\Certificates.
  • Done.

Create client certificate

We will now create a client certificate to be used for LDAPS, signed against our generated root certificate.

From the active directory server:

  • Create a new request.inf definition with the following contents - replacing ACTIVE_DIRECTORY_FQDN with the qualified domain name of your active directory server:

     [Version]
     Signature="$Windows NT$"
    
     [NewRequest]
     Subject = "CN=ACTIVE_DIRECTORY_FQDN"
     KeySpec = 1
     KeyLength = 2048
     Exportable = TRUE
     MachineKeySet = TRUE
     SMIME = FALSE
     PrivateKeyArchive = FALSE
     UserProtected = FALSE
     UseExistingKeySet = FALSE
     ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
     ProviderType = 12
     RequestType = PKCS10
     KeyUsage = 0xa0
    
     [EnhancedKeyUsageExtension]
     OID = 1.3.6.1.5.5.7.3.1 ; Server Authentication
    
  • Run the following to create a client certificate request of client.csr (note: it's critical this is run from the active directory server itself to ensure correct private key -> certificate association):

     C:\> certreq -new request.inf client.csr

Back to our OpenSSL system:

  • Create v3ext.txt containing the following:

     keyUsage=digitalSignature,keyEncipherment
     extendedKeyUsage=serverAuth
     subjectKeyIdentifier=hash
    
  • Create a certificate client.crt from certificate request client.csr and root certificate (with private key):

     $ openssl x509 \
       -req -days 3650 \
       -in client.csr -CA ca.crt -CAkey ca.key -extfile v3ext.txt \
       -set_serial 01 -out client.crt
  • Verify generated certificate:

     $ openssl x509 -in client.crt -text
  • Ensure the following X509v3 extensions are all present:

    • X509v3 Key Usage: Digital Signature, Key Encipherment
    • X509v3 Extended Key Usage: TLS Web Server Authentication
    • X509v3 Subject Key Identifier

Accept and import certificate

  • From the active directory server with client.crt present, run the following:

     C:\> certreq -accept client.crt
  • Open Manage computer certificates, the new certificate should now be present under Personal\Certificates. Ensure that:

    • Certificate has a private key association.
    • The "Intended Purposes" is defined as "Server Authentication".
    • Certificate name is the FQDN of the active directory server.

Reload active directory SSL certificate

Alternatively you can just reboot the server, but this method will instruct the active directory server to simply reload a suitable SSL certificate and if found, enable LDAPS:

  • Create ldap-renewservercert.txt containing the following:

     dn:
     changetype: modify
     add: renewServerCertificate
     renewServerCertificate: 1
     -
    
  • Run the following command:

     C:\> ldifde -i -f ldap-renewservercert.txt

Test LDAPS using ldp.exe utility

  • From another domain controller, firstly install our generated root certificate ca.crt to the certificate path Trusted Root Certification Authorities\Certificates.

  • Open utility:

     C:\> ldp.exe
  • From Connection, select Connect.

  • Enter name of target domain controller.

  • Enter 636 as port number (this is the LDAPS port).

  • Click OK to confirm the connection works.

  • You're all done!

Reference

@gnivler
Copy link

gnivler commented Oct 25, 2019

Thanks very much for this guide! +100

@jmeddy
Copy link

jmeddy commented Apr 10, 2020

Thanks for the guide!

@magnetikonline

There is one line I would add to the [NewRequest] section of the INF file to ensure a stronger HashAlgorithm is being used as SHA1 hashes are technically "broken" since 2017, and I believe MS certreq defaults to a SHA1 hash (info and other supported algorithms are at https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certreq_1):

HashAlgorithm = SHA256

@SpaceCyclist
Copy link

Thank you! I had a problem using TLS 1.2 that does not accept our old self signed sha1 certificate, thus the ldap with tls was rejected. Now it works (following @jmeddy comment).

@matiya
Copy link

matiya commented Aug 30, 2020

Complementing this guide, if you need to add subject alternative names to the certificate

  1. Add to the request.inf the following section
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=*.example.com&"
_continue_ = "dns=example.com&"
_contiinue_=""ipaddress=10.0.1.1&"
  1. Add to the v3ext.txt the following section
subjectAltName = @alt_names
#Modify for your details. Must include the commonName in the list below also. 
#The *.example.com will allow all Domain controllers with 
#the hostname somthing.example.com to use the cert.
[alt_names]
DNS.1 = *.example.com
DNS.2 = example.com
IP.1 = 10.0.1.1
  1. You should be able to see the extensions with the openssl x509 -in client.crt -text command as:
X509v3 Subject Alternative Name: 
     DNS:*.example.com, DNS:example.com, IP Address:10.0.1.1

@HungryHowies
Copy link

This is great, work very good and no problems. Thank you...

@JHong-VA
Copy link

Complementing this guide, if you need to add subject alternative names to the certificate

  1. Add to the request.inf the following section
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=*.example.com&"
_continue_ = "dns=example.com&"
_contiinue_=""ipaddress=10.0.1.1&"
  1. Add to the v3ext.txt the following section
subjectAltName = @alt_names
#Modify for your details. Must include the commonName in the list below also. 
#The *.example.com will allow all Domain controllers with 
#the hostname somthing.example.com to use the cert.
[alt_names]
DNS.1 = *.example.com
DNS.2 = example.com
IP.1 = 10.0.1.1
  1. You should be able to see the extensions with the openssl x509 -in client.crt -text command as:
X509v3 Subject Alternative Name: 
     DNS:*.example.com, DNS:example.com, IP Address:10.0.1.1

This is a life-saver! Thank you very much.

Without this alternative name that specifies the IP address, the setup won't work.

@Photon94
Copy link

Thank you so much!

@npanke
Copy link

npanke commented Feb 1, 2023

ldifde -i -f ldap-renewservercert.txt
...

Add error on entry starting on line 1: Inappropriate Authentication
The server side error is: 0x8009030e No credentials are available in the security package

I've got this same error, for the same reason as those above (domain name instead of fqdn of domain controller). I re-did my request with the FQDN of the domain controller, and it shows correctly as DCNAME.DOMAINNAME.COM - but the error remains.

@jmcisvt
Copy link

jmcisvt commented Feb 8, 2023

Nice! but - Microsoft servers and other software will accept the 'root' certificate above, but some software (like pfsense! ) will not accept it as a CA without the CA flag in the cert. To actually create a CA root certificate, you need something like this in a conf file when creating the ca.crt above. Note the 'basicConstraints=critical,CA:TRUE'

[ my_extensions ]
keyUsage=critical, digitalSignature, keyEncipherment, keyCertSign
basicConstraints=critical,CA:TRUE
extendedKeyUsage=critical,serverAuth
subjectKeyIdentifier = hash

@mlkui
Copy link

mlkui commented Feb 16, 2023

Hello: it turns out; as I made a first attempt (wrongly, becasue I used just domain name instead of FQDN), and that certificate wrongly issued was on Service Account Store, so I deleted and export it from Computer Account Store the correct one, and got it to work:

C:\Users\AAA\Downloads\certif5>ldifde -i -f ldap-renewservercert.txt Connecting to "XXX.yyy.zzz" Logging in as current user using SSPI Importing directory from file "ldap-renewservercert.txt" Loading entries.. 1 entry modified successfully.

Followed this instructions to export and import in Service Account from: https://social.technet.microsoft.com/wiki/contents/articles/2980.ldap-over-ssl-ldaps-certificate.aspx#Exporting_the_LDAPS_Certificate_and_Importing_for_use_with_AD_DS

The command has completed successfully

Thanks very much for your very short and clear tutorial

This saved my day. Thank you!

@ianzav
Copy link

ianzav commented Jul 25, 2023

I went through the process but i'm getting an error on

ldap-renewservercert.txt

Add error on entry starting on line 1: No Such Attribute
The server side error is: 0x57 The parameter is incorrect.
The extended server error is: 000000557: LdapErr: DSID-0C09105D, comment: Error in attribute conversion operation, data 0, v4563

Server 2019

@cloud303-dthach
Copy link

Worked like a charm on Windows Server 2022 hosted on an EC2 Instance in AWS!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment