I am not joking. After a significant amount of fiddling and application of Occam's Razor I have come to a configuration of Apache 2.2 that delivers a completely functional and relatively secure SVN server. To be honest it isn't instant, but it is pretty easy to do and will give a robust configuration that should not need post-install tweaking.
Get the pre-requisite software and libraries in place
- Download and install the MSI for Apache 2.2 for Windows with OpenSSL
- Download the archive of Apache 2.2 Subversion binaries
- Extract
svn-win32-1.5.5.zip
- Copy
bin\intl3_svn.dll and bin\libdb44.dll to Apache2.2\bin
- Copy
bin\mod_authz_svn.so and bin\mod_dav_svn.so to Apache2.2\modules
- Download the Apache 2.2 version of mod_auth_sspi
- Extract
mod_auth_sspi-1.0.4-2.2.2.zip
- Copy
bin\mod_auth_sspi.so to Apache2.2\modules
Sign Yourself an SSL Certificate (it is better to buy one, but this is cheaper)
Create
Apache2.2\createSSLCert.bat with the following content:
bin\openssl req -config conf\openssl.cnf -new -out my-server.csr
bin\openssl genrsa -out conf\privkey.pem 2048
bin\openssl rsa -in conf\privkey.pem -out conf\server.key
bin\openssl req -new -key conf\server.key -out conf\server.csr -config conf\openssl.cnf
bin\openssl x509 -in conf\server.csr -out conf\server.crt -req -signkey conf\server.key -days 4000
bin\openssl x509 -in conf\server.crt -out conf\server.der.crt -outform DER
Carefully fill out the SSL Certificate Details
It is critical that the Common Name on the Certificate match the fully qualified domain name of the server. I found that Apache was unable to use it for SSL otherwise. A mismatched Common Name (CN) also confuses the hell out of client software. Double-click createSSLCert.bat to start the process of building the SSL cert and key. There are a lot of prompts so be patient.
Create new file Apache2.2\conf\extras\httpd-dav-svn.conf:
LoadModule ssl_module modules/mod_ssl.so
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule sspi_auth_module modules/mod_auth_sspi.so
Listen 443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
SSLPassPhraseDialog builtin
SSLSessionCache shm:logs/ssl_scache(512000)
SSLSessionCacheTimeout 300
SSLMutex default
<VirtualHost _default_:443>
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile conf/server.crt
SSLCertificateKeyFile conf/server.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory "cgi-bin">
SSLOptions +StdEnvVars
</Directory>
CustomLog logs/ssl_request.log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
<Location />
DAV svn
SVNListParentPath on
SVNParentPath C:/Repositories
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIOfferBasic On
SSPIBasicPreferred On
# SSPIDomain DEVDOMAIN (Optional)
Require valid-user
</Location>
</VirtualHost>
Add to end of
Apache2.2\conf\httpd.conf:
Include conf/extra/httpd-dav-svn.conf
IMPORTANT: Restart the server (use shutdown -r -t 3 from the Command Prompt if you are using RDP)
You need to restart because otherwise the modules will not load correctly. I am not exactly sure why, but I tried this several times without restarting and it failed every time. This is not superstition it is actually required.
Add a new repository to your server
- Add svn-win32-1.5.5\bin to your System Path
- Run
svnadmin create C:\Repositories\svn
One particularly nice thing is that you can add any number of repositories without having to dig into Apache's config and without restarting Apache.
Take a look at https://localhost/ with your web browser. You should now have a functional Subversion server authenticating against your ActiveDirectory Domain listing svn as a repository. Enjoy :)
Tested Working Clients
- svn command line on Windows
- Internet Explorer 6 on Windows
- Chrome on Windows
- Firefox on Windows
- svn command line on Mac OS X
- Subversive in Eclipse on Mac OS X
- WebKit on Mac OS X
Oddly enough Internet Explorer actually chokes if SSPIBasicPreferred is not on. In theory it should successfully authenticate with NTLM in the single sign-on style, but it hangs or gets rejected by the server instead. We are using SSL anyway so HTTP Basic is reasonably safe.