|
If we use apache for services with user authentication we want to it to talk to Active Directory. It is possible to have Linux talk to the AD servers for user authentication. Apache can be configured to piggy back on top of this setup. There are 2 steps PAM talking to ActiveDirectoryThis is pretty easy and already documented at ActiveDirectory. Apache authenticating externallyThere are many ways to make apache use external authentication systems. the few we are interested in:
Apache talking to PAMIt sounds simple but has not been easy to do this. For some security reasons having apache talk to pam (the linux authentication system) is not common. I want to configure winbind+pam like I do on the other services so that I'm not maintaning and configuring multiple authentications systems. mod-auth-pamThis module is no longer maintained. For this reason I do not want to use it but it is the closest I have gotten to getting this stuff to work the way I want. Using other modules introduces more dependencies on other systems. http://pam.sourceforge.net/mod_auth_pam/ You must add these two lines into the Directory section of your apache config AuthPAM_Enabled on AuthBasicAuthoritative off For AuthBasicAuthoritative details see http://www.nabble.com/Bug-394097%3A-libapache2-mod-auth-pam-with-apache-%3E%3D-2.1-needs-AuthBasicAuthoritative-Off-tt7549314.html#a7549314 If authenticating against local users in the system you must also give the apache process read access to /etc/shadow. THIS IS A HUGE SECURITY RISK. The good news is that we don't really need that because we are authenticating against ActiveDirectory. Check /etc/pam.d/httpd or /etc/pam.d/apache2 to make sure that the apache pam process is using the common pam authentication rather than some other modules or settings. Debianapt-get install libapache2-mod-auth-pam Check /etc/pam.d/apache2 @include common-auth @include common-account RedHat/CentOS 5Since the module is not a built in package in RedHat I prefer to CompileFromSource. There are a few repositories on the web which have the module pre-compiled. WARNING It is risky to use software compiled by other people. You need to be able to trust the entity creating your software. This sounds paranoid because it is. Paranoia is the best way to keep systems secure. Check /etc/pam.d/httpd. create it if it does not exist. #%PAM-1.0 auth include system-auth account required pam_nologin.so account include system-auth password include system-auth session include system-auth Apache::AuthPAMhttp://search.cpan.org/~hdaniel/Apache-AuthPAM-0.01/AuthPAM.pm Apache using other authentication systemsmod-authnz-externalThis is a module that allows apache to use an external source for authentication. Unfortunately, I havent' found documentation on how to use pam as the external source. mod-auth-ldapLDAP can be used to talk to ActiveDirectory but I don't want to configure two systems. Apache using Active Directory through mod_auth_pamFirst I setup pam to authenticate against ActiveDirectory and tested with ssh. Next I modified apache's configs to use pam authentication. Main siteIf you want to password protect the main website on the server you need to modify the main configuration file for apache. DebianModify /etc/apache2/sites-available/default NameVirtualHost *
<VirtualHost *>
ServerAdmin webmaster@domain.com
ServerName hg.domain.com
DocumentRoot /var/www/
<Directory />
AuthType basic
AuthName "Active Directory Authentication Required"
AuthPAM_Enabled on
AuthBasicAuthoritative off
Require valid-user
Options FollowSymLinks
AllowOverride None
</Directory>
ErrorLog /var/log/apache2/error.log
LogLevel warn
CustomLog /var/log/apache2/access.log combined
ServerSignature On
</VirtualHost>
RedHatEdit /etc/httpd/conf/httpd.conf <Directory />
AuthType basic
AuthName "Active Directory Authentication Required"
AuthPAM_Enabled on
AuthBasicAuthoritative off
Require valid-user
Options FollowSymLinks
AllowOverride None
</Directory>
Virtual HostIf the password protected site is only one of many virtual hosts you will need to configure it outside of the main website config. RedHatI suggest creating a file to contain the virtual hosts or append to one if you already have it. Put the following section in /etc/httpd/conf.d/vhosts.conf NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@domain.com
DocumentRoot /var/www/vhosts/domain.com
ServerName mysite.domain.com
<Directory />
AuthType basic
AuthName "Active Directory Authentication Required"
AuthPAM_Enabled on
AuthBasicAuthoritative off
Require valid-user
Options FollowSymLinks
AllowOverride None
</Directory>
</VirtualHost>
Now create the directory for the virtual site mkdir -p /var/www/vhosts/hg.domain.com Put a test index.html file in place and see if it works printf "<html><body>It works\!</body></html>\n" > /var/www/vhosts/hg.domain.com/index.html Each new site can be appended to this file. DebianAssuming that you do not already have virtual hosts: By default the configuration exports /var/www for the entire web tree. Backup the original default file and change it so that we can put the virtual hosts inside /var/www. mv /etc/apache2/sites-available/default /etc/sites-available/default.orig We will move the main site to /var/www/html. Create a new file /etc/apache2/sites-available/default with the following contents NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined
ServerSignature On
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
</VirtualHost>
Next we create another file for the virtual host site. You might call it mysite. LoadModule auth_pam_module modules/mod_auth_pam.so
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName mysite.domain.com
DocumentRoot /var/www/vhosts/mysite.domain.com
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/vhosts/mysite.domain.com>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
</VirtualHost>
Create the two new directories mkdir -p /var/www/html mkdir -p /var/www/vhosts/mysite.domain.com Enable the virtual host in apache with a2ensite. If that does not work then manually link the site ln -s ../sites-available/mysite /etc/apache2/sites-enabled/mysite Virtual Host with SSLSince this site is authenticating you may want to use SSL to encrypt the session. Note the use of port 443 in the examples below and the addition of the SSL lines in the apache configs. RedHatGenerate a certificate for use on the SSL site. cd /etc/pki/tls/certs make mysite.domain.com.pem If you want to only use ssl change the following section in /etc/httpd/conf.d/vhosts.conf. If you want both ssl and non ssl add this to the already existing file. LoadModule auth_pam_module modules/mod_auth_pam.so
NameVirtualHost *:443
<VirtualHost *:443>
ServerAdmin webmaster@domain.com
DocumentRoot /var/www/vhosts/domain.com
ServerName mysite.domain.com
SSLEngine On
SSLCertificateFile /etc/pki/tls/certs/mysite.domain.com.pem
<Directory />
AuthType basic
AuthName "Active Directory Authentication Required"
AuthPAM_Enabled on
AuthBasicAuthoritative off
Require valid-user
Options FollowSymLinks
AllowOverride None
</Directory>
</VirtualHost>
DebianInstall the ssl-cert package and generate a certificate. Fill in the appropriate values when asked. apt-get install ssl-cert /usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/certs/mysite.domain.com.pem Enable ssl. a2enmod ssl Modify the mysite configuration. If you want only ssl change to the text below. If you want both ssl and non ssl add this text to the file. NameVirtualHost *:443
<VirtualHost *:443>
ServerAdmin webmaster@localhost
ServerName mysite.domain.com
SSLEngine On
SSLCertificateFile /etc/ssl/certs/mysite.domain.com.pem
DocumentRoot /var/www/vhosts/mysite.domain.com
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/vhosts/mysite.domain.com>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
If the user will not authenticate after doing all this stuff try restarting the system. It may be that some service is affected that I don't know about. Restarting seems to allow the authentication to work. SELinuxSELinux is stopping pam from responding properly to apache. If I turn it off it works ok. I'll create a custom SELINUX policy to allow this to work. tail /var/log/audit/audit.log | audit2allow -m modauthpam > modauthpam.te checkmodule -m -M -omodauthpam.mod modauthpam.te semodule_package -o modauthpam.pp -m modauthpam.mod semodule -i modauthpam.pp After running this in loops to create custom rules I ended up with this for modauthpam.te module modauthpam 1.0;
require {
type httpd_t;
class netlink_audit_socket create;
}
require {
type httpd_t;
class netlink_audit_socket write;
}
require {
type httpd_t;
class netlink_audit_socket read;
}
require {
type httpd_t;
class netlink_audit_socket { write nlmsg_relay };
}
require {
type httpd_t;
class netlink_audit_socket { nlmsg_relay read };
}
#============= httpd_t ==============
allow httpd_t self:netlink_audit_socket { nlmsg_relay read };
allow httpd_t self:netlink_audit_socket create;
allow httpd_t self:netlink_audit_socket { write nlmsg_relay };
allow httpd_t self:netlink_audit_socket write;
allow httpd_t self:netlink_audit_socket read;
|