Authenticating Apache against Active Directory

From SambaWiki


Basic LDAP authentication

Example of where you need this: You want Apache to permit access to a directory on your webserver just for AD users that are members of a defined AD group (I used group "test" in the example). Username and password should be validated against AD.

  • Create a new user in ADUC or with samba-tool, that Apache will use for connecting to the AD (I used "apache-connect" in the example below).
  • Add the following to your .htaccess or your httpd.conf (vHost/directory/... directive):
AuthName "AD authentication"
AuthBasicProvider ldap
AuthType Basic
AuthLDAPGroupAttribute member
AuthLDAPGroupAttributeIsDN On
AuthLDAPURL ldap://{AD-Hostname/IP}:389/cn=Users,dc={your Domain DN}?sAMAccountName?sub?(objectClass=*)
AuthLDAPBindDN cn=apache-connect,cn=Users,{your Domain DN}
AuthLDAPBindPassword {password}
require ldap-group cn=test,cn=Users,{your Domain DN}

With this configuration, the username is searched for just in the "Users" container and below. If you want to search in any OU of your domain, then you have to add

REFERRALS off

to your "/etc/openldap/ldap.conf". Otherwise accessing doesn't work and apache will log "auth_ldap authenticate: user xxx authentication failed; URI / [ldap_search_ext_s() for user failed][Operations error]!". If you're still getting this error after turning referrals off, set Apache to connect to Samba/AD port 3268 (AD global catalog) instead to the standard LDAP 389 port.

  • Make sure that your configuration file is only readable by the webserver, because of the password!
  • Restart apache.



Apache single sign-on

This section shows you how to authenticate a login to an apache hosted website on your intranet without having to type your password in. The Kerberos authentication used with AD will pass from your desktop domain login and therefore avoid the need to challenge again for credentials (so called Single Sign On). It will however drop back to a simple password challenge if suitable Kerberos credentials are missing.

For this to all work we require a correctly configured krb5.conf and a working DNS setup for your AD domain. The webserver machine used may or may not be joined to AD, it shouldn't matter.

The krb5.conf file should be copied from the sample one generated on Samba AD provisioning (and should be the /etc/krb5.conf on the DC if you have setup things properly) to /etc/krb5.conf on the webserver. Obviously if hosting the webserver on your Samba DC there should be nothing to do.

On DNS, we require a working forward and reverse DNS for the webserver. The DNS provisioned during the setup only comes out of the box with a working forward zone (and only a forward entry for the DC, so you will need a forward entry added for your webserver, too if not using your DC as a webserver).

To add a reverse zone use (with the subnet my webserver is on being 192.168.1.0/24):

# samba-tool dns zonecreate ADC 1.168.192.in-addr.arpa

where "ADC" is the name of the Active Directory domain controller.

Then you can add a reverse record for your webserver.

# samba-tool dns add s4dc 1.168.192.in-addr.arpa 150 PTR servername.domainname

where "servername" is the name of this webserver that has an IP of 192.168.1.150. "domainname" is your domain's DNS domain name, usually the realm name lower case.

Adding and mapping the service account (ktpass equivalent)

We next need to setup an SPN (Service Principal Names) for the server name that any website resolves to (so the actual server name that a CNAME points to, fully qualified). If not using virtual hosting the web address and the machine name will be the same. So:

# samba-tool user create --random-password http-servername
# samba-tool spn add HTTP/servername.domainname http-servername
# samba-tool domain exportkeytab /root/httpd.keytab --principal=HTTP/servername.domainname@YOUR_REALM_NAME.TLD

where "servername" is the name of this webserver, including the one in "http-servername". "YOUR_REALM_NAME.TLD" should be replaced by your AD realm name.

It is helpful to know that the samba-tool spn add and samba-tool domain exportkeytab steps are analogous to the ktpass command found in similar documentation elsewhere for tools expecting to work against a Windows AD.

Transfer and configure keytab for apache

Transfer this /root/httpd.key tabfile to your webserving machine and place in /etc/httpd/conf/httpd.keytab. Then chown and chmod this file so apache can read but not alter it i.e

# chown root:apache /etc/httpd/conf/httpd.keytab
# chmod 640 /etc/httpd/conf/httpd.keytab

Then add to your Apache configuration something like:

<location "/login.html">
       AuthType Kerberos
       AuthName "Network Login"
       KrbMethodNegotiate On
       KrbMethodK5Passwd On
       KrbAuthRealms YOUR_REALM_NAME.TLD
       require valid-user
       Krb5KeyTab /etc/httpd/conf/httpd.keytab
       KrbLocalUserMapping On
</Location>

Again replace YOUR_REALM_NAME.TLD with the AD realm name.

This is securing the "login.html" page so as the user accessing it, it must have a domain login.

On the client side, for Single Sign On to work there is a little configuration required. Windows IE is already configured to pass Kerberos credentials with Intranet (non-fully qualified) addresses.

On Firefox, on all platforms, enter "about:config" in the address bar. Search for "negotiate"

Add your site or sites to "network.negotiate-auth.trusted-uris" e.g. "http://servername, http://servername.domainname". You can just use http:// and it will pass your credentials to any site that asks for them (not recommended even though they are encrypted). Ensure "network.negotiate-auth.using-native-gsslib" is set to true (default).

On Chrome/Chromium, launch with:

  1. google-chrome --auth-server-whitelist="servername,servername.domainname" --auth-negotiate-delegate-whitelist="servername,servername.domainname"

Again these parameters take "*", but again will pass your credentials to any site that asks for them. But more subtile wildcarding is possible, to make this more convenient for many sites.

(Windows seems to not require this for Chrome)

So then using any of these browsers accessing the url (in this case) of http://servername/login.html should take you there without prompting for a password, if on a AD joined computer and logged in using a domain user.

If you use a non-joined computer you should get prompted for your login and password. Providing a domain user login should let you in to the site.

(This tutorial was provided by Colin Simpson. Thanks.)



Zarafa single sign-on

This Apache config is based on information found here: https://community.zarafa.com/pg/blog/read/18332/zarafa-outlook-amp-webaccess-sso-with-samba4

It has been tested on Debian Wheezy & Jessie and Ubuntu 12.04 & 14.04

You will need to install the libapache2-mod-auth-kerb package (Debian)

an apache2.4 kerberos auth example:

AuthType Kerberos
AuthName "Website Login"
KrbMethodNegotiate On
KrbMethodK5Passwd Off
KrbServiceName HTTP
KrbAuthRealms SAMDOM.EXAMPLE.COM
Krb5KeyTab /etc/apache2/hostname-apache.keytab
require valid-user

Setting notes:

KrbServiceName HTTP

Kerberos Primary used for httpd-linux user is HTTP (which seems to be hard coded in Zarafa). If the SPN is created with samba-tool using: samba-tool spn add HTTP/zarafa-server you can force the use of the HTTP, without the setting it may try to use 'http/zarafa-server' and the primary SPN must match.

KrbMethodNegotiate On
KrbMethodK5Passwd Off

These two settings disable the use of password based authentication for Kerberos v5. Users will not be allowed to type a password here, there must be passthrough auth with kerberos. If authentication fails, the user will never reach the website, this is what is normally required.

You will need to create 2 users:

samba-tool user create zarafa-linux --description="Unprivileged user for Zarafa Services" --random-password
samba-tool user create httpd-linux --description="Unprivileged user for Apache/zarafa Services on HOSTNAME.EXAMPLE.COM" --random-password

Set the users to never expire:

samba-tool user setexpiry zarafa-linux --noexpiry
samba-tool user setexpiry httpd-linux --noexpiry

Add SPNs to the newly created users:

samba-tool spn add zarafa/hostname.example.com zarafa-linux
samba-tool spn add zarafa/hostname.example.com@SAMDOM.EXAMPLE.COM zarafa-linux
samba-tool spn add HTTP/hostname.example.com httpd-linux
samba-tool spn add HTTP/hostname.example.com@SAMDOM.EXAMPLE.COM httpd-linux

Now export the required keytabs:

mkdir /etc/keytabs
samba-tool domain exportkeytab --principal=zarafa/hostname.example.com /etc/keytabs/hostname-zarafa-zarafa.keytab
samba-tool domain exportkeytab --principal=HTTP/hostname.example.com /etc/keytabs/hostname-http-zarafa.keytab

Set the correct Apache keytab file permissions:

chown www-data:www-data hostname-http-zarafa.keytab
chmod 400 hostname-http-zarafa.keytab

This setup is based on information supplied by L.P.H van Belle