Single-Sign-On With Apache and Linux
Home Page | Comments | Articles | Faq | Documents | Search | Archive | Tales from the Machine Room | Contribute | Set language to:en it | Login/Register
This system is a bit of a botch-up system to run a SSO system using Apache on Linux connected to an AD server (Microsoft). It works but is only viable with Microsoft Internet Explorer and in an Intranet environment. It won't work with things like Firefox, opera or the like, and it won't work if you can't change the default security settings of the browser (aka: not in an intranet) 'cause it require the browser to always send his authentication to the server.
I've no idea if it could work through a VPN (never tried) and another drawback of the solution is that you can't log out. Yep, as soon as you connect to your web site, you'll be logged in and can't logout.
If this is not what you want, stop reading now.
You'll need an Apache Web Server (doh!) with mod_ntlm an AD server and a lot of patience.
Mod_ntlm can be obtained from Sourceforge as source code or you could get a pre-compiled version for your system, if your system doesn't came with it or you can't find one, then you'll have to recompile it from the sources. This could be tricky.
If you end up in need to recompile it, you'll need both APR and APR_UTIL compiled with ldap support, if your version of Apache doesn't have them you'll get an error message during compile with something like "Need LDAP Support in APR_UTIL" (can't remember the correct error message now, but is quite clear). At this point you can try recompile your Apache with LDAP support and check if apr_util gets compiled correctly, to do so, after compile, check in /where/are/your/apache/sources/srclib/apr-util/config.status and if you have
If that last '1' is a '0', then you're apr doesn't have ldap support.
At this point the best option is to get the sources for APR and APR_UTIL from Apache's web site and then recompile them with LDAP support (for which you'll need the ldap libraries and the include files).
Warning: you can't get a version of apr/apr_util and then compile it like this, you'll need the same version of apr/apr_util that your Apache uses or the closest one available. So don't get the last version 'cause chances are that the module you compile won't run in your Apache if it doesn't have the same libraries.
Daunting? A little.
Ok, compile apr and apr_util is not so difficult, just do the usual configure/make/make install and you're set. After that you'll need to recompile your Apache with those apr and apr_util disabling the built-in ones.
You'll need to give the correct with-apr=... and with-apr-util=.. option at the configure script. Then make/make install.
The same goes for mod_ntlm.
Once you've compile mod_ntlm copy it into the Apache's modules directory and then add the required LoadModule directives into Apache.
LoadModule ntlm_module modules/mod_ntlm.so
Check if an apachectl configtest doesn't return any error, if it complaints that the module can't be loaded something ain't right.
If apachectl doesn't complaints, you're almost set.
At this point you need to setup your web site to always require authentication for your users. To do so, you'll need an .htaccess file in the root of your web site or an entry in the httpd.conf.
You'll need to always require authentication, this is the core of the sso system: if your web site require authentication and the browser is setup to provide the information, your application will get the username righht away without asking and you'll be able to use it in your application.
To require authentication you can use an .htaccess file in the docroot directory or put the request in the httpd.conf, in both cases you need something like this:
AuthType NTLM NTLMAuth on NTLMAuthoritative on NTLMBasicAuth off NTLMBasicRealm yourdomaingoeshere NTLMDomain yourfqdngoes.here NTLMServer fqdn.ofthe.dc Require valid-user
All the paramters have to be IN CAPITAL and they have to be the correct one. Especially the DC. It has to be the FQDN of the DC. Not some ip address. And no, you can't get away with a simple entry in /etc/hosts. Your DNS have to be correct.
Once done this, you should be able to restart your Apache (if you've changed httpd.conf) and point a browser to your web site and see a request for username and password. And you should be able to login using a username and password that are valid in your MS Domain.
If you get an error or can't authenticate, check in the error_log of Apache what is the problem. Chances are that your DNS ain't setup correctly.
To setup the clients you'll need to do two things:
Both are done on the client side (IE) through the Internet Options menu options and then in the 'security' tab.
Once done that, you should be able to reload the web site and get in without any password request. Be sure you close and re-open IE, otherwise the authentication will be cached.
Warning: there is no way to force the browser to send the authentication without altering its security settings, it simply can't be done from the server side.
So, now, whenever a user goes into your intranet, it will authenticate (even if he doesn't know it) sending the same authentication token that was used to authenticate to the pc. That should be enough.
Now, the problem is if you have a web site (php, perl, wathever) and you want to know who the heck is he, so you can setup some 'special' thing depending on the user.
To catch the username, you need to pick the environment variable REMOTE_USER.
The simplest way to check this, is to use the default 'printenv' cgi script provided by Apache as a cgi example. If you enable it and recall, you should see something like:
AUTH_TYPE="NTLM" ...blah blah... REMOTE_USER="yourusername" ...more blah blah...
So your username is available on the server side. Note that the password is not available anyway.
How do you use this information is up to you and how the application you're trying to tie into the AD domain is made. The simplest option is to change the part of the application that does the authentication to get the username from the environment variable and the use that to pick up all the required information for your user and forget about checking for a password (the authentication has been done by the ntlm module anyway).
This could be simple or not, it depends by the application. Sorry but I can't guide you in this.
This is not exactly a simple process, and if you have the need to recompile bits of your server it can be not so easy and lots of things can go pear-shaped. If something doesn't work you can start looking at various "usual suspects".
mod_ntlm doesn't compile
This usually means that you are missing some bits of the apr or apr_util or your apr_util ain't compiled with ldap.
make mod_ntlm doesn't return any error but there is no mod_ntlm.so to be
This happened to me in the beginning and I discovered that, for some reason, the module was into a .lib/ subdir in the mod_ntlm source directory. No idea why the heck it was there but it was. So I just got it and copied by hand where it belongs (with the others Apache modules).
Internal Server Error when trying to connect to the site
Check in the error_log what's the real problem.
send_ntlm_challenge: no conn. handle...trouble communicating with PDC/BDC? returning internal server error
This could be because the DNS ain't correct or your firewall prevent the Apache server to connect to the DC. Stop the firewall, if the problem persist then is the DNS. I'll say it again: you need a DNS! correctly configured! With both forward and reverse zone for the DC, the web site and whatever else you have. No, a simple entry in /etc/hosts won't do it. The resolution have to work from the DC and the website and everything else.
RFCNB_Call: RFCNB_Session_Req failed
with errno -1 - Called_Name 192 Calling_Name website.name.here
This has the same meaning as the one before: your DNS ain't setup correctly.
No 'REMOTE_USER' in the environment
This can only means that the browser doesn't recognize the web site as belonging to the 'intranet'. It could be a problem in the naming of the site or a problem in the networking structure. Basically, if your web site is in the same network it should have the same domain name, if it doesn't, probably your browser won't consider it 'intranet' even if you tr to force it.
Comments are added when and more important if I have the time to review them and after removing Spam, Crap, Phishing and the like. So don't hold your breath. And if your comment doesn't appear, is probably becuase it wasn't worth it.
Fred By Fred posted 14/08/2008 12:29
The ugly thing is that on my server, it does work with FF... and not with IE !!
thanks for the info
send_ntlm_challenge By diegus posted 15/09/2009 13:15
@ diegus By Davide Bianchi posted 15/09/2009 13:52
By Enrico Betti posted 25/05/2012 11:46
Ciao, ho fatto un po' di prove e volevo aggiungere un paio di commenti al post.
Per prima cosa il modulo auth_ntml sbaglia spesso a compilare su linux, ma si puo' usare
(lo trovi in internet), che e' un moduletto in perl, che non richiede installazione tra i moduli di apache ma solo un make, e poi impostare KeepAlive=on su httpd.conf
Credo che la configurazione di .htaccess sia la stessa, cmq da me ha funzionato praticamente subito.
Come seconda cosa, sul pannello di controllo devi abilitare l' invio di credenziali ai siti attendibili, come:
Computer Configuration – Windows Settings – Security Settings – Local Policies – Security Options
e dopo aver individuato la chiave “Network security: LAN Manager authentication level” impostiamone il valore su
“Send LM & NTLM – use NTLMv2 session security if negotiated”
- internet explorer: il sito deve essere tra quelli atendibili e l'invio di credenziali abilitato.
- firefox: bisogna usare about:config, e cambiare la chiave network.automatic-ntlm-auth.trusted-uris listando su questa i siti attendibili separati da virgola.
- chrome: funziona direttamente. Chrome, molto irresponsabilmente, invia le credenziali appena il pannello di controllo e' impostato per poterle inviare.. non molto sicuro.
firstname.lastname@example.org-- Enrico Betti
Davide Bianchi, works as Unix/Linux administrator for an hosting provider in The Netherlands.
Do you want to contribute?
This site is made by me with blood, sweat and gunpowder, if you want to republish or redistribute any part of it, please drop me (or the author of the article if is not me) a mail.
This site was composed with VIM, now is composed with VIM and the (in)famous CMS FdT.
This site isn't optimized for vision with any specific browser, nor
it requires special fonts or resolution.
You're free to see it as you wish.