    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Setting up a Subversion Server for Remote Use</title>
        <link>https://members.accu.org/index.php/articles/838</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Project Management + CVu Journal Vol 17, #5 - Oct 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c66/">Management</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c94/">175</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c66-94/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c66+94/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Setting up a Subversion Server for Remote Use</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 October 2005 06:00:00 +01:00 or Sun, 02 October 2005 06:00:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>Revision control is a critical part of any significant development project. Having secure full time access to your repository from wherever you are can be important. In some environments, such as open source projects, it's absolutely crucial to the functioning of the development team.</p>
</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>Revision control is a critical part of any significant
development project. Having secure full time access to your
repository from wherever you are can be important. In some
environments, such as open source projects, it's absolutely crucial
to the functioning of the development team.</p>
<p>My first exposure to the Subversion [<a href=
"#subversion">subversion</a>] revision control system was when I
was searching for something to replace CVS for the Scribus project,
whose CVS server I administer. There were a number of problems with
our use of CVS over ssh, namely server security concerns, cross
platform issues, and configuration complexity.</p>
<p>After some research, I decided that Subversion was a good
candidate to replace CVS. Subversion is a fairly new revision
control system with the stated goal of being a &quot;better CVS than
CVS.&quot; One particularly attractive feature is the use of HTTPs for a
secure, fast, encrypted transport that eliminates the need for an
SSH tunnel. Additionally, Subversion is becoming increasingly
popular in the open source development community, so more and more
useful tools and graphical clients are becoming available.</p>
<p>I'll be covering how to set up a Subversion server for your
team, so they can work on your code wherever they are without
introducing major security risks. Specifically, I'll be explaining
how to set up a Subversion server configured for use with WebDAV
over HTTPs, using SSL client certificates for an additional layer
of authentication. The goal is revision control that's fast,
secure, and easy to use from anywhere. I'll be assuming that you're
using a UNIX variant, but it should be quite possible to set all
this up on Mac OS X or even Windows NT/2k/2k3 as well.</p>
<p>This article won't try to explain how to use Subversion, why you
might want revision control, basic UNIX command line use, or any
related topics. We're going to focus specifically on setting up
reasonably secure remote access to a subversion repository. As this
article also avoids going into extreme depth on the use of
subversion and other finer points of its configuration, it is
strongly recommended that you examine the excellent Subversion book
[<a href="#svnbook">svnbook</a>] (freely available on-line) for
more detail.</p>
<p>It is important to note that your author is not a security
expert. I am an experienced system administrator who has operated
Internet-accessible systems hosting public services for some time,
but beyond that has no specific security qualifications. This
article does not provide some magic recipe for a secure server
configuration - but it should help you get started along the
way.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e40" id="d0e40"></a>Why use Client
Certificates?</h2>
</div>
<p>The use of client certificates provides an extra layer of
authentication. A user can't even attempt to authenticate against
your svn server until they've provided a client certificate that
you can verify is signed by your CA and has not been revoked. For a
bit of extra security, you can also store client certificates
separately from the client host - on a USB key or potentially even
a smart card - and remove them when not in use.</p>
<p>Client certificates are also useful for controlling access to
more than your source code repository. They can be used to help
secure SSL/TLS-based mail services such as encrypted IMAP, POP3,
and SMTP. They are also useful if you wish to offer controlled
HTTPs-based remote access to your organization's intranet web
server for roaming users. You can also use the same client
certificate infrastructure to permit users to encrypt and/or sign
email within the organization using S/MIME (though recipients who
have not imported your CA certificate won't be able to verify
signed mail).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e47" id="d0e47"></a>What You'll
Need</h2>
</div>
<p>First, you'll need a server with the Apache 2 web server, the
<tt class="literal">mod_dav_svn</tt> Apache 2 server module, and
the subversion tools installed. On Debian GNU/Linux 3.1, just
<tt class="literal">apt-get install apache2 libapache2-svn
subversion</tt>. For other platforms, if you're unsure how to go
about installing Apache 2 or <tt class="literal">mod_dav_svn</tt>,
the Subversion web site [<a href="#subversion">subversion</a>] has
plenty of information.</p>
<p>OpenSSL [<a href="#openssl">openssl</a>] will be required to
create certificates, so unless you have an existing CA and x.509
PKI scheme you'll need to install that.</p>
<p>If you want to use your repository from anywhere, you'll need an
Internet-accessible IP, or a port forwarded through your firewall.
You can use a VPN if you prefer to further limit the accessibility
of your server.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e71" id="d0e71"></a>Certificate
Creation and Management</h2>
</div>
<p>The creation and management of SSL certificates can be a
complicated business. Once it's familiar you will find that it's
not generally an issue, but the initial process can appear somewhat
daunting.</p>
<p>If your organization has existing X.509 based PKI
infrastructure, you may well be able to use your existing client
certificates and CA certificate to control access to your
Subversion server. Should you be so lucky, you can escape the need
to deal with OpenSSL. Similarly, if you have an existing server
certificate, you can use that rather than creating your own. It
doesn't have to be signed by the same CA as your client
certificates.</p>
<p>To create your certificate authority, client certificates, and
your web server certificate, you can use the OpenSSL tools. There
is not enough space to discuss this in the detail it demands, but I
can provide some brief coverage of the procedure. Alas, OpenSSL is
rather sparsely documented (especially on the broader scale), and
does not ship with any suitable references for most tasks. Your
author is no expert on SSL in general, or on OpenSSL in particular,
being just a lowly system administrator and programmer. Errors are
possible, so do be careful.</p>
<p>Some useful additional information can be found in the Apache
<tt class="literal">mod_ssl</tt> FAQ [<a href=
"#modssl">modssl</a>], at <a href="pseudonym.org" target=
"_top">pseudonym.org</a> [<a href="#pseudonym">pseudonym</a>], and
for Windows at stunnel.org [<a href="#stunnel">stunnel</a>].</p>
<p>I'll be assuming that you have OpenSSL already installed, as per
the requirements above.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e99" id="d0e99"></a>Creating a
Certificate Authority</h2>
</div>
<p>Before you can create client certificates, or useful server
certificates, you need to obtain a signing certificate. It is
possible to buy such certificates from SSL certificate vendors, but
this is unnecessary if you only intend to use the certificate
scheme within your organization and with your own users. You can
simply create your own certificate authority with a self-signed
certificate. The only significant limitation of such a certificate
is that it must be installed in clients before they will recognise
the validity of certificates you have signed.</p>
<p>I suggest that you set up your certificate authority on a
different host if possible, and in as secure a location as you can
arrange. Removable external media may be worth considering.</p>
<p>First you need to create a suitable openssl.cnf, the
configuration file that will drive your CA. The OpenSSL
distribution ships with a sample file that you can customise. Alas,
if you got your copy of OpenSSL through a vendor package library,
this could be almost anywhere on your system. If you can't find it,
you can download a sample config file from the OpenSSL project's
public CVS browser [<a href="#getfile">getfile</a>].</p>
<p>Now we need to make a directory to store your CA in, and put a
copy of openssl.cnf in it. I'm going to refer to this directory as
CA hereafter. With that done, openssl.cnf needs to be customised to
your site. Start with the section [ CA_default ], setting dir to
the path to your CA directory. This tells OpenSSL where to put (and
look for) the various files and directories used when managing your
CA. I tend to use an absolute path, but if your CA will be stored
on removable media where the path may not be constant, you can use
. (the current directory) instead, then always work by changing
into the CA directory.</p>
<p>Next, under [ <tt class="literal">req_distinguished_name</tt> ],
adjust the <tt class="literal">_default</tt> parameters to suit
your site. You can <tt class="literal">add _default</tt> parameters
to options that do not have them, or remove them if you don't want
to provide defaults for a parameter.</p>
<p>To finish our preparation, create the structure to store the
CA's various information by creating the subdirectories certs,
newcerts, crl and private within your CA directory, then create a
file called <tt class="filename">serial</tt> (no extension)
containing only the digits <tt class="literal">01</tt>, and create
an empty file called index.txt . Be sure to set the access
permissions on private so that only the user who will be managing
the CA can see its contents or modify it.</p>
<p>It's finally time to create the CA certificate that signs all
your client certificates and lets you verify them later. Pick a
good pass phrase to use on your CA's key, and record it somewhere
secure and offline. Now create the self-signed certificate that you
can use as your CA, supplying the pass phrase you decided on when
prompted:</p>
<pre class="screen">
openssl req -new -x509 -keyout private/cakey.pem 
   -out cacert.pem -days 365 -config ./openssl.cnf
</pre>
<p>When prompted to enter details for the certificate, you should
enter the details you wish to appear if a user queries the CA
certificate (eg in a browser). As such, Common Name should
generally by set to the organization name, not the name of the
creator of the certificate. Note that the certificate was created
with an expiry date one year from today. You can extend the expiry
date of the CA certificate as it approaches expiry with:</p>
<pre class="screen">
mv cacert.pem old_cacert.pem
openssl x509 -in old_cacert.pem -days 365 
   -out cacert.pem -signkey private/cakey.pem
</pre>
<p>Note that clients will treat certificates signed by an expired
root certificate as invalid, and must import the updated root
certificate. As such, you may wish to choose a reasonably long
validity period.</p>
<p>You can examine your CA certificate by dumping a human-readable
version with:</p>
<pre class="screen">
openssl x509 -in cacert.pem -text
</pre>
<p>If that looks alright, you've created your CA. You're now ready
to start creating and signing certificates. Make a backup of your
CA directory somewhere secure, safe, and off-line, then copy your
CA certificate file (but absolutely not the CA key) to somewhere
that Apache 2 can access it. Apache needs the CA certificate to
verify that client certificates were really signed by your CA.</p>
<p>For security reasons, it is crucial that you do not keep your CA
key on the Subversion server. Put it somewhere safe, preferably on
encrypted storage that's not connected to the Internet. I favour
the use of a small old laptop that's kept in a safe when not in
use, but some might accuse me of excessive paranoia. No matter
where you store your CA, remember to keep a backup somewhere safe
and secure, such as on CD or tape.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e150" id="d0e150"></a>Creating a
Server Certificate</h2>
</div>
<p>If you don't have an existing SSL server certificate for the
host you want to run your Subversion server on, you need to create
one. It is necessary to first create a certificate request, then
sign that request with your CA. Be sure to provide the DNS name of
your Subversion server in the common name field of the request,
otherwise clients will be warned every time they try to connect to
your server. You must use the publicly visible DNS name of the
server, rather than its internal host name. In the following,
replace new with your host name, eg myhostname_req.pem for
new_req.pem.</p>
<p>Here I show the creation of a key without a pass phrase. This
means that the key can be used by anybody who obtains it. It is
possible to use a key with a password on a web server, but with
Apache the password must be entered interactively. This interacts
rather poorly with log rotation scripts, and means that if your
server ever goes down it won't come back up without manual
intervention. I dislike the use of an unencrypted private key, but
have found no viable alternative for my use. If you can afford the
possible issues involved with using an encrypted key, then I
encourage you to use one - simply add <tt class=
"literal">-des3</tt> to the first command line below.</p>
<p>Create a private key (append -des3 to encrypt the key):</p>
<pre class="screen">
openssl genrsa -out new_key.pem
</pre>
<p>Create a certificate request using your key:</p>
<pre class="screen">
openssl req -new -key new_key.pem 
   -out new_req.pem -days 360 
   -config ./openssl.cnf
</pre>
<p>then sign it with your CA:</p>
<pre class="screen">
openssl ca -policy policy_anything 
   -out new_cert.pem -config openssl.cnf 
   -infiles new_req.pem
</pre>
<p>If all has gone well, you should have a server certificate.
Check it with:</p>
<pre class="screen">
openssl x509 -in new_cert.pem -text
</pre>
<p>to ensure that it's correct, then copy <tt class=
"filename">new_cert.pem</tt> and <tt class=
"filename">new_key.pem</tt> to somewhere Apache can access them,
and save backup copies somewhere secure, safe, and off-line. Be
sure to set the permissions on <tt class="filename">newkey.pem</tt>
so that only the Apache user can read the file, and nobody can
modify it. You can now discard <tt class=
"filename">new_req.pem</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e190" id="d0e190"></a>Creating the
Client Certificates</h2>
</div>
<p>With a working CA established, you're equipped to create and
sign client certificates for use by your users. While it's possible
to get users to make their own certificate requests, I'll assume
you'll be doing that for them then supplying them with a pre-made
certificate. The first stage of the procedure for making a client
certificate request is actually the same as that for the server
certificate described above, except that you should provide the
user's name and email address for the common name and email fields,
respectively. You only need the certificate and key files
temporarily, so there is no need to save them anywhere.</p>
<p>Once you have the certificate for the user, created the same was
as the server certificate above, you need to convert them to
PKCS#12 format, a &quot;packaged&quot; certificate format that most clients
understand. You can bundle the CA certificate into this package so
that it's automatically imported by most client software when it
loads the PKCS#12 certificate. I suggest you save the certificate
with a suitable name that makes it easy to identify the owner of
the certificate later, such as <tt class=
"literal">firstname.lastname_at_domain.p12</tt>.</p>
<p>To do this, assuming your user's temporary certificate and key
files are in <tt class="filename">new_key.pem</tt> and <tt class=
"filename">new_cert.pem</tt> respectively, run:</p>
<pre class="screen">
openssl pkcs12 -in new_cert.pem 
  -inkey new_key.pem -certfile cacert.pem -out
  user_name.p12 -export -name &quot;User's
  Subversion certificate for MyOrganization&quot;
</pre>
<p>If you encrypted the user's key, you will be prompted for the
password to decrypt it. You will then be prompted for a password to
encrypt their new PKCS#12 file with. This is the password you will
need to supply to the user for them to use their new client
certificate.</p>
<p>Once the PKCS#12 file has been created you can discard
<tt class="filename">new_cert.pem</tt>, <tt class=
"filename">new_key.pem</tt>, and <tt class=
"filename">new_req.pem</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e223" id="d0e223"></a>Setting up a
Test Repository</h2>
</div>
<p>For the purposes of this article, it's best if you create a new
subversion repository to work with. You should probably work on a
dummy repository before going live with your server even if you
have an existing one or plan to convert from CVS.</p>
<p>Setting up a new repository is simple. Assuming that you want it
to live in /var/svn:</p>
<pre class="screen">
# mkdir /var/svn
# svnadmin create /var/svn fsfs
</pre>
<p>Now let's add a dummy module for testing. First, create the
files to import in some temporary directory:</p>
<pre class="screen">
# mkdir testproject
# echo 'It worked!' &gt; testproject/test.txt
</pre>
<p>then import the temporary testproject directory into the new
repository:</p>
<pre class="screen">
# svn import testproject
   file:///var/svn/testproject/trunk 
   -m &quot;first import&quot;
</pre>
<p>You can now discard the testproject directory.</p>
<p>The Subversion website has detailed documentation on how to
create a repository, import sources, or convert a CVS repository to
Subversion using cvs2svn, so I'm not going to discuss it in any
more detail here. You might want to look up the Subversion book
[<a href="#stunnel">stunnel</a>] if you're unsure how to proceed
when it comes time to get your project's live code into svn.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e247" id="d0e247"></a>Setting up
the Web Server</h2>
</div>
<p>When using client certificates, it is generally be best to set
up your Subversion server in a separate Apache 2 virtual host
running on a non-standard port. This is necessary because of
limitations in the SSL implementation of common clients.</p>
<p>Apache installations and configuration specifics differ a huge
amount across different OSes and even Linux distributions.
Consequently I can discuss the general configuration approach to
take, but not necessarily all of the specifics of what files to
edit and what to put where. You may need to adapt the sample
configuration discussed below to suit your system.</p>
<p>In the following configuration I make the assumption that your
repository is in <tt class="filename">/var/svn</tt>, and you'll use
<tt class="filename">/var/www/projectname</tt> for things like
WebSVN[12]. You can use whatever paths you prefer, so long as you
configure Apache accordingly. First, it may be necessary to add or
uncomment the configuration directives to load <tt class=
"literal">mod_dav</tt> and <tt class=
"literal">mod_dav_svn</tt>:</p>
<pre class="screen">
LoadModule dav_module path/to/mod_dav.so
LoadModule dav_svn_module path/to/mod_dav_svn.so
LoadModule authz_svn_module path/to/mod_authz_svn.so
</pre>
<p>The exact paths to the modules will vary depending on your
Apache and mod_dav_svn installation. If your Apache is not already
configured for SSL, you may also need to uncomment or add a
directive such as:</p>
<pre class="screen">
LoadModule ssl_module path/to/mod_ssl.so
</pre>
<p>To actually configure the Subversion server you'll need to add
something like this to your Apache 2 configuration:</p>
<pre class="programlisting">
# Tell Apache to listen on port 4430 for connections
Listen 4430
# And set up a virtual host to handle connection on # that port:
NameVirtualHost *:4430
&lt;VirtualHost *:4430&gt;
  # Set up SSL for the virtual host. 
  SSLEngine on
  # The CA certificate file that you'll be
  # validating client certificates against:
  SSLCACertificateFile /path/to/your/cacert.pem
  # The server certificate the web server will
  # identify its self with. If you have an existing
  # SSL virtual host, you can use that certificate
  # for this virtual host too (just specify
  # the same path here). It need not be signed by
  # the CA specified above.
  SSLCertificateFile /path/to/your/servercert.pem
  # Only set this if you have a separate key file
  # for your server certificate:
  SSLCertificateKeyFile /path/to/your/serverkey
  # Require clients to have a certificate signed by
  # one of the CA certificates specified earlier:
  SSLVerifyClient require
  SSLVerifyDepth 1

  # Require a valid username and password to access
  # any part of this virtual host, and make the
  # default access control &quot;deny&quot;.
  &lt;Directory /&gt;
    # Only talk to clients using SSL
    SSLRequireSSL
    # Don't permit the use of .htaccess files to
    # override these settings
    AllowOverride None
    # This tells Apache to use BASIC password
    # authentication. You can rely purely on client
    # certificates if you wish to - look up 
    # FakeBasicAuth in the mod_ssl documentation.
    # You can also authenticate against a database,
    # or against LDAP, if you prefer - see the
    # Apache documentation. Here BASIC
    # authentication with a simple password is used.
    AuthType Basic
    AuthName &quot;ProjectName SVN&quot;
    # Your password file. Put this somewhere safe,
    # and outside the DocumentRoot configured below.
    AuthUserFile /path/to/apache2/config/
       projectname_svn_htpasswd
    # Reject access from users who give no / wrong
    # passwords.
    Require valid-user
    # and, for the root directory, reject all
    # access. This is overridden in later
    # subsections.
    Order deny,allow
    deny from all
  &lt;/Directory&gt;

  # Tell Apache to look for files starting in
  # /var/www/projectname
  DocumentRoot /var/www/projectname
  # And permit any authenticated user access to the
  # files under it.
  &lt;Directory /var/www/projectname&gt;
    Order allow,deny
    Allow from all
  &lt;/Directory&gt;

  # Set up the Subversion server, giving it the
  # virtual location &quot;/svn&quot; in URLs.
  &lt;Location /svn&gt;
    # Turn on the svn server
    Dav svn
    # Tell it our repository is in /var/svn
    SVNPath /var/svn
    # Uncomment the following line to enable Authz
    # Authentication
    # AuthzSVNAccessFile /etc/apache2/dav_svn.authz
    # Permit access to this location (still requires
    # valid user and client cert as specified
    # earlier).
    Order allow,deny
    Allow from all
  &lt;/Location&gt;
  # Enable gzip compression if available
  &lt;ifmodule mod_deflate.c&gt;
  DeflateBufferSize 8096
  DeflateCompressionLevel 9
  SetOutputFilter DEFLATE
  SetInputFilter DEFLATE
  &lt;/ifmodule&gt;
&lt;/VirtualHost&gt;
</pre>
<p>You may need to edit the existing virtual host directives to
explicitly specify the port they listen on (80 for HTTP, 443 for
HTTPs) using the same form as shown above.</p>
<pre class="programlisting">
If you want to offer anonymous read-only access to your repository (common for Open Source projects) then you can add a section like this to your normal HTTP and/or HTTPs virtual host(s):

# Anonymous read-only access to the repository
&lt;Location /svn&gt;
  Dav svn
  SVNPath /var/svn
  &lt;LimitExcept GET PROPFIND OPTIONS REPORT&gt;
    Order deny,allow
    Deny from all
  &lt;/LimitExcept&gt;
&lt;/Location&gt;
</pre>
<p>You will probably want to enable gzip compression as well, as
shown in the main configuration listing. Using gzip compression on
the server saves bandwidth and results in faster checkouts, but at
the cost of some server CPU time.</p>
<p>You should now be done configuring the web server. Test your
configuration's syntax with <tt class="literal">apachectl -t</tt>
(<tt class="literal">apache2ctl -t</tt> on some systems) and
restart Apache 2.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e292" id="d0e292"></a>Final Server
Configuration</h2>
</div>
<p>Before you can test the newly configured Subversion server, you
must ensure that your repository is writeable by the web server.
The exact procedure for this depends on if you plan to offer access
to your repository using other methods too. Assuming that you'll
only be using the repository via the Apache-based Subversion server
and you're running under a modern UNIX, <tt class="literal">chown
-R webserverid /var/svn</tt> (where <tt class=
"literal">webserverid</tt> is the user ID your apache2 is running
under) should do the job. If you're not sure what user ID apache is
running under, the first column of the output of <tt class=
"literal">ps aux | egrep '(http|apache)'</tt> should show you.</p>
<p>Red Hat Fedora users need to be aware of of SELinux, which can
interfere with the operation of your Subversion server. If you find
that you are getting &quot;permission denied&quot; or &quot;403 Forbidden&quot; errors
that make no sense, the chances are good that SELinux is involved.
Reconfiguring SELinux is beyond the scope of this article. For
testing purposes only you can disable it using <tt class=
"literal">setenforce Permissive as root</tt>. Consider tweaking the
SELinux configuration for Apache 2 rather than permanently
disabling SELinux, since SELinux provides additional isolation
between the various network services on your system.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e311" id="d0e311"></a>Adding Users
on the Server</h2>
</div>
<p>Since you're using HTTP BASIC authentication with a plain
password file, you need to add some users to the password file. To
set up the password file, use this command:</p>
<pre class="screen">
# htpasswd -c /path/to/htpasswd_file username-to-add
</pre>
<p>where <tt class="literal">/path/to/htpasswd_file</tt> is the
same as the path you gave in your Apache 2 configuration. Now
ensure that the file is readable but not writeable by Apache:</p>
<pre class="screen">
# chgrp apachegroupid /path/to/htpasswd_file
# chmod 640 /path/to/htpasswd_file
and start adding more users with:
# htpasswd /path/to/htpasswd_file 
   username-to-add
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e325" id="d0e325"></a>Setting up
the Client</h2>
</div>
<p>If all has gone well, you're now ready to test out the new
server by connecting with a subversion client.</p>
<p>First, you need to install your PKCS#12 format client
certificate. Exactly how to do this depends on what subversion
client you are using. With the command line client on UNIX, I tend
to put the certificate file into <tt class=
"filename">$HOME/.subversion</tt>. I then edit <tt class=
"filename">$HOME/.subversion/servers</tt>, adding a line like
<tt class="literal">mysvn = hostname.of.my.svn.server</tt> to the
[groups] section, and add a new section for that server:</p>
<pre class="programlisting">
[mysvn]
ssl-client-cert-file = /path/to/client/cert/file.p12
# If you want to have svn remember the password to 
# your cert file, set this. Since you're using BASIC
# auth as well, this is generally fine. Many GUI svn
# clients don't seem to be able to prompt for a
# certificate password, so saving it here also helps
# to avoid confusing those clients.
ssl-client-cert-password = yourPasswordToSave
</pre>
<p>At the time of writing the Subversion client did not appear to
read the CA certificate out of the PKCS#12 client certificate file.
As such, you need to provide cacert.pem to your users if you
created your SSL server certificate using your self-signed CA. This
can be skipped if you bought a server certificate from one of the
major certificate authorities.</p>
<p>To install the CA cert, copy it to:</p>
<pre class="screen">
$HOME/.subversion/myorganization.pem
</pre>
<p>then edit the [ global ] section of $HOME/.subversion/servers
and add a line such as:</p>
<pre class="screen">
ssl-authority-files = /path/to/myorganization.pem
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e353" id="d0e353"></a>Testing</h2>
</div>
<p>With that configuration done, you're ready to check out the
module you created earlier. Using the command line subversion
client:</p>
<pre class="screen">
svn checkout https://username@hostname:port/svn/
   testproject/trunk testproject
</pre>
<p>Naturally you'll need to adjust the URL above to use your user
name in the Apache password file, svn server host name, and server
port.</p>
<p>You should be prompted for your password, then the checkout
should complete, leaving you with the same testproject/test.txt
file you checked in earlier. You can now work within your checkout
directory as if it was your usual local source tree, then commit
changes back to the repository with <tt class="literal">svn
commit</tt>. Subversion will remember the repository URL, so you
don't need to specify it when working within a checked-out
tree.</p>
<p>If you install your client certificate into your web browser (in
Firefox: <tt class="literal">Edit-&gt;Preferences, Advanced, Manage
Certificates, import</tt>, then edit the CA cert under Authorities
and mark it as trusted), you should be able to explore the
repository by visiting <tt class=
"literal">https://hostname:port/svn</tt>. This can be useful when
troubleshooting configuration problems.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e375" id="d0e375"></a>Locking it
Down</h2>
</div>
<p>In the opinion of the author, there's almost no such thing as
enough paranoia when securing your source code repository. That's
doubly true if you're making it accessible over the Internet. It's
well worth looking into hosting the repository on a dedicated
server or isolated OS instance, limiting access by IP address,
putting the server behind a VPN gateway, storing client
certificates on external media, etc. Naturally, you'll also want to
keep the server and the clients up-to-the-minute with all security
patches. Don't forget to make backups - and to periodically archive
the backups.</p>
<p>Remember that your clients are important too. It's easier to
clean up from an attacker committing to your repository through a
client than it is from a server compromise, but if their changes
are not recognised as from an impostor, you still risk shipping
malicious code to users.</p>
<p>When it comes to server security, the more you can isolate the
Apache 2 / Subversion service from whatever else might be running
on the machine the better. An entirely separate Apache 2 instance
running under a different user ID just for svn may be worth
considering if your server also runs Apache for other public
services. A physically separate server or OS a separate instance is
even better. Linux users may wish to investigate Xen [<a href=
"#xensource">xensource</a>] or VMWare [<a href=
"#vmware">vmware</a>] for isolating OS instances on the same
hardware; Solaris users may want to consider using zones [<a href=
"#sun">sun</a>]. The better your svn server and repository are
isolated from any other potential sources of attack, the less
impact a service compromise is likely to have.</p>
<p>There's no such thing as a secure computer - especially when
exposed to the Internet - and this article can't teach you even a
fraction of how to truly secure things. Don't just follow what's
described here, but try to go out and get help locking your server
down as tight as possible.</p>
<p>There's little worse than discovering that the system hosting
your source code repository has been compromised, so you should
probably do everything you can to make sure that it doesn't happen,
and that if it does you're prepared and able to quickly recover.
&quot;Sorry, we just shipped a rootkit/virus/trojan with our last
product&quot; isn't an announcement you ever want to have to make.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e397" id="d0e397"></a>Subversion
and the Scribus Project</h2>
</div>
<p>The Scribus project is still using CVS+SSH. Our tests of
Subversion were quite successful, but many of the team want
graphical merge and history browser tools that they didn't feel to
be sufficiently mature. As the KDE project has moved to Subversion,
I'm hoping to see some improved svn clients available soon, after
which I hope it will be possible to migrate the project to
Subversion.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e402" id="d0e402"></a>Resources</h2>
</div>
<div class="bibliomixed"><a name="subversion" id="subversion"></a>
<p class="bibliomixed">[subversion] <span class=
"bibliomisc"><a href="http://subversion.tigris.org/" target=
"_top">http://subversion.tigris.org/</a></span></p>
</div>
<div class="bibliomixed"><a name="svnbook" id="svnbook"></a>
<p class="bibliomixed">[svnbook] <span class="bibliomisc"><a href=
"http://svnbook.red-bean.com/" target=
"_top">http://svnbook.red-bean.com/</a></span></p>
</div>
<div class="bibliomixed"><a name="openssl" id="openssl"></a>
<p class="bibliomixed">[openssl] <span class="bibliomisc"><a href=
"http://www.openssl.org/" target=
"_top">http://www.openssl.org/</a></span></p>
</div>
<div class="bibliomixed"><a name="modssl" id="modssl"></a>
<p class="bibliomixed">[modssl] <span class="bibliomisc"><a href=
"http://www.modssl.org/docs/2.8/ssl_faq.html" target=
"_top">http://www.modssl.org/docs/2.8/ssl_faq.html</a></span></p>
</div>
<div class="bibliomixed"><a name="pseudonym" id="pseudonym"></a>
<p class="bibliomixed">[pseudonym] <span class=
"bibliomisc"><a href="http://www.pseudonym.org/ssl/ssl_cook.html"
target=
"_top">http://www.pseudonym.org/ssl/ssl_cook.html</a></span></p>
</div>
<div class="bibliomixed"><a name="stunnel" id="stunnel"></a>
<p class="bibliomixed">[stunnel] <span class="bibliomisc"><a href=
"http://www.stunnel.org/examples/ms-ca-newbie.html" target=
"_top">http://www.stunnel.org/examples/ms-ca-newbie.html</a></span></p>
</div>
<div class="bibliomixed"><a name="getfile" id="getfile"></a>
<p class="bibliomixed">[getfile] <span class="bibliomisc"><a href=
"http://cvs.openssl.org/getfile/openssl/apps/openssl.cnf?v=1.23.2.4"
target=
"_top">http://cvs.openssl.org/getfile/openssl/apps/openssl.cnf?v=1.23.2.4</a></span></p>
</div>
<div class="bibliomixed"><a name="xensource" id="xensource"></a>
<p class="bibliomixed">[xensource] <span class=
"bibliomisc"><a href="http://www.xensource.com/" target=
"_top">http://www.xensource.com/</a></span></p>
</div>
<div class="bibliomixed"><a name="vmware" id="vmware"></a>
<p class="bibliomixed">[vmware] <span class="bibliomisc"><a href=
"http://www.vmware.com/" target=
"_top">http://www.vmware.com/</a></span></p>
</div>
<div class="bibliomixed"><a name="sun" id="sun"></a>
<p class="bibliomixed">[sun] <span class="bibliomisc"><a href=
"http://www.sun.com/bigadmin/content/zones/" target=
"_top">http://www.sun.com/bigadmin/content/zones/</a></span></p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
