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.