Log in |
Certificate Mapping in ApacheBeware that this how-to is work in progress! Since I have some Zope webservices to support that use BasicAuth and I wanted to move towards certificates I was faced with the problem of having to convert the subject name of the client certificate to REMOTE_USER. The FakeBasicAuth of mod_ssl is unusable in this context as it produces a username that is different than the usernames already used in Zope. So I managed to use mod_rewrite in Apache to create a mapping facility. In the current installation I only want to require client authentication for the /admin subdirectory. First the httpd.conf configuration:
(Server context - nothing unusual)
SSLPassPhraseDialog builtin
SSLSessionCache dbm:logs/ssl_scache
SSLSessionCacheTimeout 300
SSLMutex file:logs/ssl_mutex
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
(Virtual host context for SSL port)
<VirtualHost _default_:443>
SSLEngine on
SSLCertificateFile conf/butterfly.crt
SSLCertificateKeyFile conf/butterfly.key
SSLCACertificateFile conf/ssl.crt/eionet-ca.crt
SSLVerifyClient none
SSLVerifyDepth 10
RewriteMap dnmap txt:/etc/httpd/conf/certmap
RewriteMap escape int:escape
RewriteEngine on
RewriteCond %{LA-U:SSL_CLIENT_S_DN} (..*)
RewriteRule (.*) ${escape:%1} [C]
RewriteRule (.*) - [e=REMOTE_USER:${dnmap:$1},C]
RewriteRule .* %{REQUEST_URI} [L]
<Location /admin>
SSLVerifyClient require
SSLVerifyDepth 1
SSLOptions -StdEnvVars -FakeBasicAuth
</Location>
</VirtualHost>
What happens here is that if there is an SSL_CLIENT_S_DN server variable, then the url gets rewritten with the SSL_CLIENT_S_DN for further processing. I escape the spaces in the DN and then I apply a rewritemap called dnmap, that contains the DN and the userid. The content of the certmap file looks like this: I have a small problem here; There is a space between Soren and Roug in the DN. I use the escape internal map to convert space into %20, but since the rewrite module takes the %2 and translates it into the empty string, what has to go into the mapping file is a 0 everywhere there was a space. I have been unable to get around this problem. Maybe if I used a dbm-file, and used a loading program that used tabs instead of space as a delimiter. The next step is to configure Zope to use authentication through Apache. This is not covered here yet, but take a look on this:
CaveatsWhile the above looks like a simple way to provide single-signon, in practice it could reduce the security. Rather than entering a password from memory, the user presents a certificate stored on the computer's harddisk. You as a server administrator don't know if the user has a password on the certificate or not. Therefore if the user is careless with his certificate it could end up in the wrong hands. Even if it is protected with a password. If it gets stolen, the thief can leisurely apply many computers to run a dictionary attack on the password. Nobody would notice. If a password-guessing attack was perpetrated against a regular webserver with Basic-Auth, you would notice in the server log-files after a few hours (or weeks) and could terminate that account. Nowadays we use certificates more as a two-factor login approach. You must present a valid certificate, but also login the normal way with Basic-Auth. We simply let Apache check the cert and Zope the login/password. Therefore the mapping business shown above is not used by us at the moment. If you plan to do the same, here is what you put into Apache's configuration file: #SSLCACertificatePath /etc/httpd/conf/ssl.crt SSLCACertificateFile /etc/httpd/conf/ssl.crt/orgcacert.crtorgcacert.crt is the CA certificate that you created with openssl. This ensures that only certificates generated/signed by your organization can be verified.
SSLOptions +OptRenegotiate
SSLVerifyClient require
SSLVerifyDepth 1
<Location />
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Widget Company, Inc."
</Location>
This specifies that only user certificates whose O in the DN
is Widget Company, Inc. can gain entry. That makes it possible
for you to create certificates with other O content
that can't be used for entry. Feel free to use any other
field such as OU.
|