Chapter 3. Setting Up A Server

Table of Contents

Apache Based Server
Introduction
Installing Apache
Installing Subversion
Configuration
Multiple Repositories
Path-Based Authorization
Authentication With a Windows Domain
Multiple Authentication Sources
Securing the server with SSL
Using client certificates with virtual SSL hosts
Svnserve Based Server
Introduction
Installing svnserve
Running svnserve
Basic Authentication with svnserve
Better Security with SASL
Authentication with svn+ssh
Path-based Authorization with svnserve

To use TortoiseSVN (or any other Subversion client), you need a place where your repositories are located. You can either store your repositories locally and access them using the file:// protocol or you can place them on a server and access them with the http:// or svn:// protocols. The two server protocols can also be encrypted. You use https:// or svn+ssh://. This chapter shows you step by step on how you can set up such a server on a Windows machine.

More detailed information on the Subversion server options, and how to choose the best architecture for your situation, can be found in the Subversion book under Server Configuration .

If you don't have a server and you work alone then local repositories are probably your best choice. You can skip this chapter and go directly to Chapter 4, The Repository.

If you were thinking about setting up a multi-user repository on a network share, think again. Read the section called “Accessing a Repository on a Network Share” to find out why we think this is a bad idea.

Apache Based Server

Introduction

The most flexible of all possible server setups for Subversion is the Apache based one. Although a bit more complicated to set up, it offers benefits that other servers cannot:

WebDAV

The Apache based Subversion server uses the WebDAV protocol which is supported by many other programs as well. You could e.g. mount such a repository as a “Web folder” in the Windows explorer and then access it like any other folder in the file system.

Browsing The Repository

You can point your browser to the URL of your repository and browse the contents of it without having a Subversion client installed. This gives access to your data to a much wider circle of users.

Authentication

You can use any authentication mechanism Apache supports, including SSPI and LDAP.

Security

Since Apache is very stable and secure, you automatically get the same security for your repository. This includes SSL encryption.

Installing Apache

The first thing you need before installing Apache is a computer with Windows 2000, Windows XP+SP1, Windows 2003, Vista or Server 2008.

Warning

Please note that Windows XP without the service pack 1 will lead to bogus network data and could therefore corrupt your repository!

  1. Download the latest version of the Apache web server from http://httpd.apache.org/download.cgi . Make sure that you download the version 2.2.x - the version 1.3.xx won't work!

    The msi installer for Apache can be found by clicking on other files, then browse to binaries/win32. You may want to choose the msi file apache-2.2.x-win32-x86-openssl-0.9.x.msi (the one that includes OpenSSL).

  2. Once you have the Apache2 installer you can double click on it and it will guide you through the installation process. Make sure that you enter the server-URL correctly (if you don't have a DNS name for your server just enter the IP-address). I recommend to install Apache for All Users, on Port 80, as a Service. Note: if you already have IIS or any other program running which listens on port 80 the installation might fail. If that happens, go to the programs directory, \Apache Group\Apache2\conf and locate the file httpd.conf. Edit that file so that Listen 80 is changed to a free port, e.g. Listen 81. Then restart the installation - this time it should finish without problems.

  3. Now test if the Apache web server is running correctly by pointing your web browser to http://localhost/ - a preconfigured Website should show up.

Caution

If you decide to install Apache as a service, be warned that by default it will run as the local system account. It would be a more secure practice for you to create a separate account for Apache to run as.

Make sure that the account on the server that Apache is running as has an explicit entry in the repository directory's access control list (right-click directory | properties | security), with full control. Otherwise, users will not be able to commit their changes.

Even if Apache runs as local system, you still need such an entry (which will be the SYSTEM account in this case).

If Apache does not have this permission set up, your users will get “Access denied” error messages, which show up in the Apache error log as error 500.

Installing Subversion

  1. Download the latest version of the Subversion Win32 binaries for Apache. Be sure to get the right version to integrate with your version of Apache, otherwise you will get an obscure error message when you try to restart. If you have Apache 2.2.x go to http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100 .

  2. Run the Subversion installer and follow the instructions. If the Subversion installer recognized that you've installed Apache, then you're almost done. If it couldn't find an Apache server then you have to do some additional steps.

  3. Using the windows explorer, go to the installation directory of Subversion (usually c:\program files\Subversion) and find the files /httpd/mod_dav_svn.so and mod_authz_svn.so. Copy these files to the Apache modules directory (usually c:\program files\apache group\apache2\modules ).

  4. Copy the file /bin/libdb*.dll and /bin/intl3_svn.dll from the Subversion installation directory to the Apache bin directory.

  5. Edit Apache's configuration file (usually C:\Program Files\Apache Group\Apache2\conf\httpd.conf) with a text editor such as Notepad and make the following changes:

    Uncomment (remove the '#' mark) the following lines:

    #LoadModule dav_fs_module modules/mod_dav_fs.so
    #LoadModule dav_module modules/mod_dav.so
    

    Add the following two lines to the end of the LoadModule section.

    LoadModule dav_svn_module modules/mod_dav_svn.so
    LoadModule authz_svn_module modules/mod_authz_svn.so
    

Configuration

Now you have set up Apache and Subversion, but Apache doesn't know how to handle Subversion clients like TortoiseSVN yet. To get Apache to know which URL will be used for Subversion repositories you have to edit the Apache configuration file (usually located in c:\program files\apache group\apache2\conf\httpd.conf) with any text editor you like (e.g. Notepad):

  1. At the end of the config file add the following lines:

    <Location /svn>
      DAV svn
      SVNListParentPath on
      SVNParentPath D:\SVN
      #SVNIndexXSLT "/svnindex.xsl"
      AuthType Basic
      AuthName "Subversion repositories"
      AuthUserFile passwd
      #AuthzSVNAccessFile svnaccessfile
      Require valid-user
    </Location>
    

    This configures Apache so that all your Subversion repositories are physically located below D:\SVN. The repositories are served to the outside world from the URL: http://MyServer/svn/ . Access is restricted to known users/passwords listed in the passwd file.

  2. To create the passwd file, open the command prompt (DOS-Box) again, change to the apache2 folder (usually c:\program files\apache group\apache2) and create the file by entering

    bin\htpasswd -c passwd <username>
    

    This will create a file with the name passwd which is used for authentication. Additional users can be added with

    bin\htpasswd passwd <username>
    

  3. Restart the Apache service again.

  4. Point your browser to http://MyServer/svn/MyNewRepository (where MyNewRepository is the name of the Subversion repository you created before). If all went well you should be prompted for a username and password, then you can see the contents of your repository.

A short explanation of what you just entered:

Table 3.1. Apache httpd.conf Settings

SettingExplanation
<Location /svn> means that the Subversion repositories are available from the URL http://MyServer/svn/
DAV svn tells Apache which module will be responsible to serve that URL - in this case the Subversion module.
SVNListParentPath on For Subversion version 1.3 and higher, this directive enables listing all the available repositories under SVNParentPath.
SVNParentPath D:\SVN tells Subversion to look for repositories below D:\SVN
SVNIndexXSLT "/svnindex.xsl" Used to make the browsing with a web browser prettier.
AuthType Basic is to activate basic authentication, i.e. Username/password
AuthName "Subversion repositories" is used as an information whenever an authentication dialog pops up to tell the user what the authentication is for
AuthUserFile passwd specifies which password file to use for authentication
AuthzSVNAccessFile Location of the Access file for paths inside a Subversion repository
Require valid-user specifies that only users who entered a correct username/password are allowed to access the URL


But that's just an example. There are many, many more possibilities of what you can do with the Apache web server.

  • If you want your repository to have read access for everyone but write access only for specific users you can change the line

    Require valid-user
    

    to

    <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
    </LimitExcept>
    

  • Using a passwd file limits and grants access to all of your repositories as a unit. If you want more control over which users have access to each folder inside a repository you can uncomment the line

    #AuthzSVNAccessFile svnaccessfile
    

    and create a Subversion access file. Apache will make sure that only valid users are able to access your /svn location, and will then pass the username to Subversion's AuthzSVNAccessFile module so that it can enforce more granular access based upon rules listed in the Subversion access file. Note that paths are specified either as repos:path or simply path. If you don't specify a particular repository, that access rule will apply to all repositories under SVNParentPath. The format of the authorization-policy file used by mod_authz_svn is described in the section called “Path-Based Authorization”

  • To make browsing the repository with a web browser 'prettier', uncomment the line

    #SVNIndexXSLT "/svnindex.xsl"
    

    and put the files svnindex.xsl, svnindex.css and menucheckout.ico in your document root directory (usually C:/Program Files/Apache Group/Apache2/htdocs). The directory is set with the DocumentRoot directive in your Apache config file.

    You can get those three files directly from our source repository at http://tortoisesvn.tigris.org/svn/tortoisesvn/trunk/contrib/other/svnindex . If you're asked for authentication for this link, enter guest as username and leave the password empty.

    The XSL file from the TortoiseSVN repository has a nice gimmick: if you browse the repository with your web browser, then every folder in your repository has an icon on the right shown. If you click on that icon, the TortoiseSVN checkout dialog is started for this URL.

Multiple Repositories

If you used the SVNParentPath directive then you don't have to change the Apache config file every time you add a new Subversion repository. Simply create the new repository under the same location as the first repository and you're done! In my company I have direct access to that specific folder on the server via SMB (normal windows file access). So I just create a new folder there, run the TortoiseSVN command TortoiseSVNCreate repository here... and a new project has a home...

If you are using Subversion 1.3 or later, you can use the SVNListParentPath on directive to allow Apache to produce a listing of all available projects if you point your browser at the parent path rather than at a specific repository.

Path-Based Authorization

The mod_authz_svn module permits fine-grained control of access permissions based on user names and repository paths. This is available with the Apache server, and as of Subversion 1.3 it is available with svnserve as well.

An example file would look like this:

[groups]
admin = john, kate
devteam1 = john, rachel, sally
devteam2 = kate, peter, mark
docs = bob, jane, mike
training = zak
# Default access rule for ALL repositories
# Everyone can read, admins can write, Dan German is excluded.
[/]
* = r
@admin = rw
dangerman =
# Allow developers complete access to their project repos
[proj1:/]
@devteam1 = rw
[proj2:/]
@devteam2 = rw
[bigproj:/]
@devteam1 = rw
@devteam2 = rw
trevor = rw
# Give the doc people write access to all the docs folders
[/trunk/doc]
@docs = rw
# Give trainees write access in the training repository only
[TrainingRepos:/]
@training = rw

Note that checking every path can be an expensive operation, particularly in the case of the revision log. The server checks every changed path in each revision and checks it for readability, which can be time-consuming on revisions which affect large numbers of files.

Authentication and authorization are separate processes. If a user wants to gain access to a repository path, she has to meet both, the usual authentication requirements and the authorization requirements of the access file.

Authentication With a Windows Domain

As you might have noticed you need to make a username/password entry in the passwd file for each user separately. And if (for security reasons) you want your users to periodically change their passwords you have to make the change manually.

But there's a solution for that problem - at least if you're accessing the repository from inside a LAN with a windows domain controller: mod_auth_sspi!

The original SSPI module was offered by Syneapps including source code. But the development for it has been stopped. But don't despair, the community has picked it up and improved it. It has a new home on SourceForge .

  • Download the module which matches your apache version, then copy the file mod_auth_sspi.so into the Apache modules folder.

  • Edit the Apache config file: add the line

    LoadModule sspi_auth_module modules/mod_auth_sspi.so
    

    to the LoadModule section. Make sure you insert this line before the line

    LoadModule auth_module modules/mod_auth.so
    

  • To make the Subversion location use this type of authentication you have to change the line

    AuthType Basic
    

    to

    AuthType SSPI
    

    also you need to add

    SSPIAuth On
    SSPIAuthoritative On
    SSPIDomain <domaincontroller>
    SSPIOmitDomain on
    SSPIUsernameCase lower
    SSPIPerRequestAuth on
    SSPIOfferBasic On
    

    within the <Location /svn> block. If you don't have a domain controller, leave the name of the domain control as <domaincontroller>.

Note that if you are authenticating using SSPI, then you don't need the AuthUserFile line to define a password file any more. Apache authenticates your username and password against your windows domain instead. You will need to update the users list in your svnaccessfile to reference DOMAIN\username as well.

Important

The SSPI authentication is only enabled for SSL secured connections (https). If you're only using normal http connections to your server, it won't work.

To enable SSL on your server, see the chapter: the section called “Securing the server with SSL”

Tip

Subversion AuthzSVNAccessFile files are case sensitive in regard to user names (JUser is different from juser).

In Microsoft's world, Windows domains and user names are not case sensitive. Even so, some network administrators like to create user accounts in CamelCase (e.g. JUser).

This difference can bite you when using SSPI authentication as the windows domain and user names are passed to Subversion in the same case as the user types them in at the prompt. Internet Explorer often passes the username to Apache automatically using whatever case the account was created with.

The end result is that you may need at least two entries in your AuthzSVNAccessFile for each user -- a lowercase entry and an entry in the same case that Internet Explorer passes to Apache. You will also need to train your users to also type in their credentials using lower case when accessing repositories via TortoiseSVN.

Apache's Error and Access logs are your best friend in deciphering problems such as these as they will help you determine the username string passed onto Subversion's AuthzSVNAccessFile module. You may need to experiment with the exact format of the user string in the svnaccessfile (e.g. DOMAIN\user vs. DOMAIN//user) in order to get everything working.

Multiple Authentication Sources

It is also possible to have more than one authentication source for your Subversion repository. To do this, you need to make each authentication type non-authoritative, so that Apache will check multiple sources for a matching username/password.

A common scenario is to use both Windows domain authentication and a passwd file, so that you can provide SVN access to users who don't have a Windows domain login.

  • To enable both Windows domain and passwd file authentication, add the following entries within the <Location> block of your Apache config file:

    AuthBasicAuthoritative Off
    SSPIAuthoritative Off
    

Here is an example of the full Apache configuration for combined Windows domain and passwd file authentication:

<Location /svn>
  DAV svn
  SVNListParentPath on
  SVNParentPath D:\SVN

  AuthName "Subversion repositories"
  AuthzSVNAccessFile svnaccessfile.txt

# NT Domain Logins.
  AuthType SSPI
  SSPIAuth On
  SSPIAuthoritative Off
  SSPIDomain <domaincontroller>
  SSPIOfferBasic On

# Htpasswd Logins.
  AuthType Basic
  AuthBasicAuthoritative Off
  AuthUserFile passwd

  Require valid-user
</Location>

Securing the server with SSL

Even though Apache 2.2.x has OpenSSL support, it is not activated by default. You need to activate this manually.

  1. In the apache config file, uncomment the lines:

    #LoadModule ssl_module modules/mod_ssl.so
    

    and at the bottom

    #Include conf/extra/httpd-ssl.conf
    

    then change the line (on one line)

    SSLMutex "file:C:/Program Files/Apache Software Foundation/\
    Apache2.2/logs/ssl_mutex"
    

    to

    SSLMutex default
    

  2. Next you need to create an SSL certificate. To do that open a command prompt (DOS-Box) and change to the Apache folder (e.g. C:\program files\apache group\apache2) and type the following command:

    bin\openssl req -config conf\openssl.cnf -new -out my-server.csr
    

    You will be asked for a passphrase. Please don't use simple words but whole sentences, e.g. a part of a poem. The longer the phrase the better. Also you have to enter the URL of your server. All other questions are optional but we recommend you fill those in too.

    Normally the privkey.pem file is created automatically, but if it isn't you need to type this command to generate it:

    bin\openssl genrsa -out conf\privkey.pem 2048
    

    Next type the commands

    bin\openssl rsa -in conf\privkey.pem -out conf\server.key
    

    and (on one line)

    bin\openssl req -new -key conf\server.key -out conf\server.csr \
    -config conf\openssl.cnf
    

    and then (on one line)

    bin\openssl x509 -in conf\server.csr -out conf\server.crt
                     -req -signkey conf\server.key -days 4000
    

    This will create a certificate which will expire in 4000 days. And finally enter (on one line):

    bin\openssl x509 -in conf\server.cert -out conf\server.der.crt
                     -outform DER
    

    These commands created some files in the Apache conf folder (server.der.crt, server.csr, server.key, .rnd, privkey.pem, server.cert).

  3. Restart the Apache service.

  4. Point your browser to https://servername/svn/project ...

SSL and Internet Explorer

If you're securing your server with SSL and use authentication against a windows domain you will encounter that browsing the repository with the Internet Explorer doesn't work anymore. Don't worry - this is only the Internet Explorer not able to authenticate. Other browsers don't have that problem and TortoiseSVN and any other Subversion client are still able to authenticate.

If you still want to use IE to browse the repository you can either:

  • define a separate <Location /path> directive in the Apache config file, and add the SSPIBasicPreferred On. This will allow IE to authenticate again, but other browsers and Subversion won't be able to authenticate against that location.

  • Offer browsing with unencrypted authentication (without SSL) too. Strangely IE doesn't have any problems with authenticating if the connection is not secured with SSL.

  • In the SSL "standard" setup there's often the following statement in Apache's virtual SSL host:

    SetEnvIf User-Agent ".*MSIE.*" \
                 nokeepalive ssl-unclean-shutdown \
                 downgrade-1.0 force-response-1.0
    

    There are (were?) good reasons for this configuration, see http://www.modssl.org/docs/2.8/ssl_faq.html#ToC49 But if you want NTLM authentication you have to use keepalive. If You uncomment the whole SetEnvIf you should be able to authenticate IE with windows authentication over SSL against the Apache on Win32 with included mod_auth_sspi.

Forcing SSL access

When you've set up SSL to make your repository more secure, you might want to disable the normal access via non-SSL (http) and only allow https access. To do this, you have to add another directive to the Subversion <Location> block: SSLRequireSSL.

An example <Location> block would look like this:

<Location /svn>
  DAV svn
  SVNParentPath D:\SVN
  SSLRequireSSL
  AuthType Basic
  AuthName "Subversion repositories"
  AuthUserFile passwd
  #AuthzSVNAccessFile svnaccessfile
  Require valid-user
</Location>

Using client certificates with virtual SSL hosts

Sent to the TortoiseSVN mailing list by Nigel Green. Thanks!

In some server configurations you may need to setup a single server containing 2 virtual SSL hosts: The first one for public web access, with no requirement for a client certificate. The second one to be secure with a required client certificate, running a Subversion server.

Adding an SSLVerifyClient Optional directive to the per-server section of the Apache configuration (i.e. outside of any VirtualHost and Directory blocks) forces Apache to request a client Certificate in the initial SSL handshake. Due to a bug in mod_ssl it is essential that the certificate is requested at this point as it does not work if the SSL connection is re-negotiated.

The solution is to add the following directive to the virtual host directory that you want to lock down for Subversion:

SSLRequire %{SSL_CLIENT_VERIFY} eq "SUCCESS"

This directive grants access to the directory only if a client certificate was received and verified successfully.

To summarise, the relevant lines of the Apache configuration are:

SSLVerifyClient Optional

### Virtual host configuration for the PUBLIC host 
### (not requiring a certificate)

<VirtualHost 127.0.0.1:443>
  <Directory "pathtopublicfileroot">
  </Directory>
</VirtualHost>

### Virtual host configuration for SUBVERSION 
### (requiring a client certificate)
<VirtualHost 127.0.0.1:443>
  <Directory "subversion host root path">
    SSLRequire %{SSL_CLIENT_VERIFY} eq "SUCCESS"
  </Directory>

  <Location /svn>
    DAV svn
    SVNParentPath /pathtorepository
  </Location>
</VirtualHost>