Archive for the 'Apache' Category

Active Directory Authentication on Apache with mod_authnz_ldap

<directory /path/to/top/secret/area>
    AuthName "Top Secret Area"
    AuthType Basic
    AuthBasicProvider ldap
    AuthzLDAPAuthoritative Off
    AuthLDAPURL "ldap://example.com:389/DC=example,DC=com?sAMAccountName?sub?(objectClass=*)" NONE
    AuthLDAPBindDN apacheldapauth@example.com
    AuthLDAPBindPassword mypassword
    Require valid-group cn=Admins,ou=Groups,DC=example.com,DC=com
</directory>

In this example, I am password-protecting /path/to/top/secret/area. The AuthLDAPURL directive contains the address of your active directory server (ldap://example.com:389), the base DN to search (DC=example,DC=com), and the LDAP attribute that contains the user’s username (sAMAccountName). In order to perform the search, Apache will bind to the Active Directory server using the credentials defined in AuthLDAPBindDN and AuthLDAPBindPassword. If a user is found and the password matches, one last search is done to make sure they belong to the appropriate group (cn=Admins,ou=Groups,DC=example.com,DC=com).

There’s nothing special about this example so far as it relates to Active Directory. The same config should work on any LDAP server. However, the real key to making this work with Active Directory is by adding the following to /etc/openldap/ldap.conf:

REFERRALS off

Note that since the bind password is stored in plain text, make sure your Apache config file file can only be read by authorized users.

Redirect to the SSL Version of a Page with mod_rewrite on Apache

User: The web interface doesn’t work.
Mike: Type “https” instead of “http.”
User: Oh yeah, now it works.

A quick exchange like this is not a big deal on its own, but as every sysadmin knows, little things like this can add up and become annoying very quickly (for all parties involved). I find that if I can prevent these little distractions from happening in the first place, everyone is a little happier and more productive.

One way I accomplish this is by not expecting users to remember which sites need to be accessed via SSL and which do not. I just allow them to connect to everything on port 80, then I let mod_rewrite redirect them to the SSL version as needed:

<location "/">    
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</location>

Apache HostnameLookups implicitly enabled?

I finally figured out why my site has been so slow for some people. After multiple sessions of staring at tcpdump output and grep-ing through error logs, I finally noticed that Apache’s access_log was full of hostnames… Duh! This meant that Apache was doing a reverse lookup on every address that accessed my site.

(For those who don’t undrstand why this is such a serious performance bottleneck, Apache won’t display the page until the hostname is resolved. This will take a couple seconds in a lot of cases, and in the worst case (if there’s no PTR record associated with the client’s IP address), Apache will wait up to 30 seconds before giving up and displaying the page anyway.)

“Ah ha,” I exclaimed, as I fired up vi and scrolled down to HostnameLookups in my httpd.conf, but I became even more confused when I discovered that HostnameLookups was already disabled. Just to be sure, I grep-ed my entire /etc partition for HostnameLookups, but it was definately turned off. So why was Apache continuing to do reverse lookups even though I told it not to? The answer was a faulty “deny” statement in one of my access lists. I was originally commenting my deny statements like this:

Deny from 10.20.30 #some jerk

But apparently, the entire line (including the comment) was being misinterpreted as a hostname, which implicitely enabled HostnameLookups. The solution was to move the comments to their own lines like this:

#some jerk
Deny from 10.20.30

I hope this saves someone out there a lot of time and confusion.