Thursday, October 4, 2012

Part 3, Integrating Red Hat Enterprise Linux 6 with Active Directory: enabling ldap starttls

In the previous part we implemented AD authentication. But as stated in previous part, our ldap queries are still in plaintext, moreover we can not guarantee if the DC (Domain controller) we are talking to, is the DC we expected to talk to.

Prerequisites

Windows Server 2008 R2 Enterprise with
  • Active Directory Domain Services role enabled and configured
  • Trusted Root Certification Authorities role enabled and configured

Red Hat Enterprise Linux 6.3 or CentOS release 6.3 (Final)
samba-winbind-clients-3.5.10-125.el6.x86_64
samba-winbind-3.5.10-125.el6.x86_64
samba-client-3.5.10-125.el6.x86_64
openldap-2.4.23-26.el6_3.2.x86_64
openldap-clients-2.4.23-26.el6_3.2.x86_64
root CA certificate in pem format

Other versions of prerequisites will probably due if they do not differ a lot. This setup was tested with listed versions.

Theoretical

Why this is dangerous: suppose we base sudo access on AD groups. If the system then queries the ldap DC for the members of a group, a man in the middle can theoretically add himself to the group in a tampered ldap response. This is just one theoretical example.

Next to this a whole lot of ldap information is going in plain text over the wire. So everybody with the correct network access can pick this up.

But there is a solution for this, setting up an SSL tunnel to the ldap server.

There are 2 ways to achieve this for a Windows 2008 R2 DC.

1) A full blown SSL tunnel on port 636
2) Using starttls on port 389

As I did not find any way to enable option 1 for the idmap_rid backend, I went for option 2.

Note that you can use option 1 with winbind, (use idmap_ldap backend) .

For both options you need to have the root CA certificate of your domain controller installed on your linux box to verify the domain controller's certificate.(If everything is setup correctly the DC certificate should be signed by the CA, running on the DC). This is standard pki stuff.

Practical

Before you start, you need to make sure the "Active Directory Certificate Services" role is enabled and configured on your DC. (Make sure to not make a standalone CA, but one that is integrated in AD). The details on how to setup this, are not in the scope of this post.

Also install the necessary ldap libraries/binaries as they are used by winbind "behind the screens".

yum install openldap openldap-clients

After this you need to get the root CA certificate,

On the DC open up the certificate manager for the computer account
"search box > type "mmc" > File > Add/Remove snap-in > Certificates > Computer account >Finish>OK."




The certificate is locate somewhere in the "Trusted Root Certification Authorities". By default it has a name like "<domain>-<DCNAME>-CA" , but your mileage may vary. I noticed there are usually two of them looking the same, I am no Microsoft expert, so I do not know the reason behind this.

Right-click on the certificate>all taks>export and export it as a Base-64 encoded.x509. Now copy this file over to your linux box and store it in /etc/openldap/cacerts, create this folder first if it does not exist yet.

After this run

cacertdir_rehash /etc/openldap/cacerts

Next edit your /etc/openldap/ldap.conf (yes this seems confusing, because you are not using pam_sss or pam_ldap, still winbind seems to borrow some libaries from the openldap packages).

The only entries for now need to be:


TLS_CACERTDIR /etc/openldap/cacerts
TLS_REQCERT    never 


We are not there yet, you need to tell winbind to use starttls too.

In smb.conf make sure following settings are set


ldap ssl ads = yes
ldap ssl = start tls (This is the default)



Remove cache and restart winbind to test connection:

rm -fv /var/lib/samba/gencache.tdb && rm -fv /var/lib/samba/winbindd_cache.tdb && service winbind restart  && wbinfo -u

 If this wbinfo -u is succesful you know the ldap configuration settings are correct.

But since option "TLS_REQCERT    never" was set in /etc/openldap/ldap.conf we did not test yet if the CA certificate can validate the certificate of the DC.

I advise to first test this manually with the aid of openssl.

Although our traffic will go to port 389 you can test if the CA certificate can validate the DC certificate by doing:

  openssl s_client -connect dc.domain.com:636 -CAfile /etc/openldap/cacerts/<yourCA>.cer.

Check the response, somewhere on the last lines should be: "Verify return code: 0 (ok)". If this is the case the CA is good, if this is not the case, something is wrong with your CA. Please resolve this issue first before continuing. Do not run production with "TLS_REQCERT    never" as you do not validate the identity of the DC in this case!

If your CA passed the openssl test: comment out "TLS_REQCERT    never".

Your  /etc/openldap/ldap.conf now looks like this:


TLS_CACERTDIR /etc/openldap/cacerts
#TLS_REQCERT    never


 Remove cache and restart winbind to test connection:

rm -fv /var/lib/samba/gencache.tdb && rm -fv /var/lib/samba/winbindd_cache.tdb && service winbind restart  && wbinfo -u

Congratulations, if this command returns your AD users, you are done.

Aftermath

Since I am a curious person, I want to validate the before and after encryption sniffing results.

For this I used wireshark, I cleared the cache before every test to force winbind to connect to the DC.

See following screenshots:

Before: no encryption, we can intercept and read everything

 



After: encryption (every ldap query is going through an TLSv1 tunnel)




Our total smb.conf now looks like this

[global]
        workgroup = DOMAIN
        realm = DOMAIN.COM
        security = ADS
        password server = dc.domain.com,  *
        log level = 3
        disable netbios = Yes
        name resolve order = host
        ldap ssl ads = Yes
        idmap uid = 15000-17000
        idmap gid = 15000-17000
        winbind separator = +
        winbind reconnect delay = 2
        winbind use default domain = Yes
        winbind nss info = rfc2307
        winbind offline logon = Yes
        idmap config DOMAIN : range = 10000000-29999999
        idmap config DOMAIN : default = yes
        idmap config DOMAIN : backend = rid



If any remarks our questions, feel free to ask.

No comments:

Post a Comment