Section 10.1. Controlling Access to the Repository


10.1. Controlling Access to the Repository

Subversion supplies you with a number of different repository access schemas that can be used from a Subversion client (as illustrated in Figure 10.1). Each schema represents not only a different access mechanism, but also a differing level of access control available to the administrator. The range of control varies from simply being able to use the operating system's file access controls to limit access to the whole repository using direct local repository access, to fine-grained per-directory access control via HTTP/HTTPS. Additionally, with all of the access methods (except direct local access), you can control whether users are allowed to access the repository through an insecure, unencrypted (albeit slightly faster) connection, or are required to access the repository through an encryption layer, such as SSH or SSL.

Figure 10.1. The respository access schema layer.


10.1.1. Direct Access Control

Subversion repositories on your local machine can be accessed directly by using a local access schema, through a file:// URL. This is a handy way to access a repository that is only going to be used by one person, or even a couple of people using the same machine. However, this method doesn't scale up particularly well as the number of users grows. Subversion itself does not supply any sort of built-in access controls for direct repository access, so your ability to control access is limited to your operating system's capability to control read/write access to the repository itself. Also, there is no built-in way to provide access controls of a finer grain than whether a user has read or write access to the whole repository. You can use hook scripts (see Chapter 11, "The Joy of Automation") to provide better control, but because the user needs full filesystem access to the repository, those controls can be circumvented.

The security advantage gained from using direct access to access a repository is the lack of network access. Direct access doesn't require you to have any sort of server process running, and requires no network ports to be opened. Therefore, if you limit repository access to direct access, there is no way for anyone to access the repository without local access to the machine. (Remember, never access a Subversion repository from a network share if you're using Berkeley DB as your storage backend.)

10.1.2. svnserve Access Control

An alternate to direct access is the standalone Subversion server, svnserve. It allows you to make the repository available to remote users, while retaining access that is available only to certain users. Additionally, repository access can be performed using a custom Subversion protocol (easier) or through a tunneled SSH or RSH connection (more secure). Unfortunately, access through svnserve does have the same all-or-nothing limitations that direct access does, although hook scripts can still be used to limit access.

Unlike direct access, the Subversion protocol does not require you to allow filesystem access to every user, so hook script access controls are a little more secure when using the Subversion protocolbut passwords are transferred in plaintext. If you use tunneled SSH/RSH, you don't have to worry about plaintext passwords, but you do need to provide filesystem-level access to the repository, so hook script access controls could theoretically be circumvented. In general, svnserve is not a good choice if security is a concern.

If svnserve is started with either the -i or -d options, it will handle requests on a dedicated port, communicating over the custom Subversion access protocol. Access is provided to all users that are found in a Subversion-specific password file, pointed to by the svnserve configuration file. The svnserve configuration file is named svnserve.conf, and is located in the conf directory of the repository that the file refers to (each repository has its own svnserve.conf file).

The svnserve.conf file

The svnserve.conf file tells svnserve how it should handle user authentication. It is set up similar to the Subversion user configuration files (see Chapter 7, "Configuring the Client"), and has a single section named [general]. In that section, there are a number of options that you can set.

If you would like to allow anonymous access to the repository, you can set up the anon-access option. If you want to allow anonymous users to get files from the repository, but not commit, you can set anon-access to read. Or, if you want to allow anonymous users full access to the repository, you can give them read/write access with the value write. On the other hand, if you don't want any sort of anonymous access, set anon-access to none.

Assuming you would like more than just anonymous access to the repository, you will need to set up some users with access. To tell Subversion where to find the file containing these users, you point it to the password file by setting the password-db file to the path to the password file. I'll describe the contents of the password file shortly.

Sometimes, you will have multiple repositories that should all share the same set of users. If you would like users to be able to authenticate with all of the repositories as a single group (i.e., cached authentication with one repository allows access to the other repositories), you can set up a realm. The realm is set with the svnserve.conf option realm, and should be the name you would like to use for the realm (users will see this when they log in). As a word of caution, make sure you have each repository in the realm point to the same password file. Otherwise, a user's ability to log into the realm may be dependent on which repository the user accesses first.

A complete svnserve.conf file may look something like this:

 [general] anon-access = read password-db = /srv/svnrepos/conf/passwd realm = Very Snazzy Repositories 

The Passwords Database File

The passwords database for a repository (identified by the svnserve.conf file) contains a list of username/password pairs that identify the valid users for that repository. Each entry will be of the form username = password, with the passwords stored in their plaintext form (so make sure that only authorized people have access to the password file). The collection of username/password pairs will then all fall under the [users] section, as you can see in the following sample password database.

 [users] bill = ABadPassword bob = K@tZ7&D()g$5 

Secure Communication over SSH

Another option that is available for securing svnserve is tunneling it over SSH, by using an svn+ssh:// URL (or svn+rsh:// to tunnel over RSH). If you are tunneling svnserve, the svnserve program will be run locally on the server machine, using the -t option. It will also be run as the OS-level user who invoked the SSH tunnel session. That means two things.

  • Instead of listing the users in a Subversion-specific password database file, each user will need to be a full user on the server system, with access to log in via SSH.

  • Each user with access to the repository will need either read or read/write access to the actual repository, just as with direct access.

With SSH tunneling, the svnserve.conf file is not needed. After the user has authenticated, access is essentially identical to direct repository access.

10.1.3. HTTP/HTTPS Access Control

By far, your most flexible security options come from using the Apache HTTP/HTTPS repository server. In addition to allowing similar authentication options to svnserve, the Apache server allows you to define per-directory security constraints. This allows you to give individual users access to only some of the directories in a repository, instead of being forced to use all-or-nothing authentication.

Setting Up Password Protection

After you have Apache set up and serving a repository (see Chapter 3, "Installing Subversion"), you're probably going to want to protect it from unauthorized access (even open source projects don't usually allow unfettered write access to their repositoriesit helps keep references to petrified movie stars out of the code). To add password authentication to your repository, you need to add a couple of lines to the <Location> section that points to your Subversion repository. These entries will tell Apache that it should require a username and password from all who try to connect, as well as where to find the file that lists the users and their passwords.

Apache supports two types of authentication: basic password protection and digest password protection. Basic authentication has wider support among Web browsers, but it sends passwords in what is essentially plaintext form. Digest authentication offers much better password security by using a challenge/response mechanism that avoids the transmission of the password itself. Although it is not quite as well supported, unless you need to have your users access the repository via an ancient browser, you are much better off using digest (the svn client program supports digest authentication). A password protected repository location entry with digest authentication will end up looking something like the following example.

 <Location /myrepos>   DAV svn   SVNPath /srv/svnrepos   AuthType Digest   AuthName "My Subversion Realm"   AuthDigestDomain /myrepos/   AuthDigestFile /srv/svnrepos/svn-auth-file   Require valid-user </Location> 

In this case, the five options of real interest are the four that begin with Auth and Require.

  • The AuthType entry tells Apache that it should use digest authentication for challenging the client.

  • The AuthName enTRy gives a realm name, which is displayed to the user when logging in. This realm is also used to match the username/password that the user gives when authenticating.

  • The AuthDigestDomain entry gives a domain for the authentication. All paths underneath the given domain are included in an authenticated domain (for example, /myrepos/trunk/ or /myrepos/branches).

  • The AuthDigestFile enTRy defines the file where the digest passwords are stored.

  • Require informs Apache that it should require users to enter a valid username/password before allowing access.

The digest password file should be a file created with htdigest, containing the usernames, realms, and encrypted passwords of every user that is allowed access to the repository. The file originally is created by running htdigest with the -c option, which tells it to create a new file. The following example shows how you might create a new password file containing the user fredj. Notice that the realm matches the AuthName given in your <Location> description earlier. This is necessary for the given username/password pair to work for that location. As you can see, htdigest prompts you for the password to use before creating the file.

 $ htdigest -c /srv/svnrepos/svn-auth-file "My Subversion Realm" fredj Adding password for fredj in realm My Subversion Realm. New password: Re-type new password: Adding password for user fredj 

After you have an existing digest file, you can use htdigest to add to that file by leaving off the -c argument.

Further Securing with SSL

The problem with password authentication under Apache is that it only keeps unauthorized users from accessing the repository, but does nothing to protect the data as it travels between the server and client. The casual user is prevented from going through your repository, but determined attackers will have no problems capturing data in transit. Therefore, in order to tack on an added layer of security, it is a good idea to also use the Secure Socket Layer (SSL) to encrypt all data that travels over the network.

The first thing you need to do when enabling SSL for Apache is to make sure that the mod_ssl.so module is loaded into Apache when it starts. This is accomplished in Apache by calling LoadModule ssl_module mod_ssl.so somewhere in the Apache configuration files. In many cases, this will already exist in your base Apache install, but may need to have something defined in order to turn it on, such as by running Apache with a -D SSL option.

After you have SSL enabled in Apache, you need to set your repository share to require the use of SSL for communications. This is done simply by adding the a SSLRequireSSL statement to your repository <Location>. So, the repository location from earlier would become.

 <Location /myrepos>   DAV svn   SVNPath /srv/svnrepos   AuthType Digest   AuthName "My Subversion Realm"   AuthDigestDomain /myrepos/   AuthDigestFile /srv/svnrepos/svn-auth-file   Require valid-user   SSLRequireSSL </Location> 

Creating an SSL Certificate

SSL works on a trust-by-association mechanism for securely ensuring a site's identity. Any site that uses SSL will have a certificate that identifies the site (name, IP address, domain, and so on). That certificate will then be digitally signed by a certificate authority that vouches for the certificate's authenticity. That way, if someone attempts to intercept communications to your server by pretending to be you, he won't have the proper signed certificate and the Web browser or Subversion client will warn the user that something is amiss.

Certificate authorities (CAs) come in two flavors. The first variety is the large commercial CA, such as Verisign or Thawte, which gives your certificate a wide trust base (for a hefty annual cost, in most cases). Then, there are locally created certificate authorities, usually generated for intranets, where trust can more easily be established. Additionally, you can also self-sign a certificate, which is by far the easiest approach to getting an SSL-protected server up and going, but it is also the most vulnerable to attacks that intercept data from clients and pretend to be your server (this is known as a man in the middle attack).

If you want to set up SSL on your Web server, you need to set up some sort of SSL certificate. Dealing with a commercial CA and creating your own intranet CA are beyond the scope of this book. The steps toward creating a self-signed certificate are fairly simple though. If the number of developers accessing your repository is small (especially if they're all on an intranet), this is probably sufficient.

The first step toward creating a certificate is to generate a private key, which will be stored locally and not be accessible to anyone else. The key is generated by using the openssl program, with the genrsa command. In its simplest form, the command takes the name of the encryption cypher to use (des3 in the following example), the number of bits to use (at least 1024), and a file to output the key into. To improve the security of your key, you should also provide a source of random data to be used when calculating the key. The best source to use is /dev/random (assuming you're on a UNIX-like machine that has a /dev/random); but if that is not available, you can also enter a file that has been otherwise populated with random data, or even a list of randomly chosen files from your system, separated by colons.

When openssl genrsa is run, it asks you for a passphrase, which protects your key from unauthorized users, even if the key itself is compromised. The downside to the passphrase is that it needs to be typed every time the Web server is started (which is likely undesireable). Therefore, you will probably want to remove the passphrase from the file and ensure that the resulting private key file is only readable by the root user, which you can do by running the openssl rsa command.

 $ openssl genrsa -des3 -rand /dev/random -out svnsrv.key 1024 $ openssl rsa -in svnsrv.key -out svnsrv.pem 

After you have your key generated, you need to generate a certificate request, which could then be sent to a certificate authority for signing, or you can self-sign it (as I'll show you how to do shortly). To generate the certificate request, you need to run the openssl req command, and give it your key. When the command runs, it asks you a number of questions about who you are, which are then included as a part of the signed certificate (and sent to clients that are trying to verify the certificate's authenticity). You can fill in as many or as few of the fields as you would like.

 $ openssl req -new -key svnsrv.pem -out svnsrv.req You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:Indiana Locality Name (eg, city) []:Terre Haute Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:William Nagel Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: 

After you've created the certificate request, you can then use that to create a self-signed certificate.

 $ openssl req -x509 -days 365 -in svnsrv.req -key svnsrv.pem -out svnsrv.crt 

Configuring Your SSL Certificate in Apache

The last thing you need to do to configure Apache to use SSL is to set it up to create a virtual host that is accessible on port 443 (the default SSL port). In your Apache configuration files, you need to add a <VirtualHost> directive similar to the following.

 <VirtualHost _default_:443>    DocumentRoot "/srv/www/localhost/htdocs"    SSLEngine on    SSLCertificateFile /etc/apache2/ssl/svnsrv.crt    SSLCertificateKeyFile /etc/apache2/ssl/svnsrv.pem </VirtualHost> 

Per-directory Access Control

One of the big advantages of using Apache as your repository server is the ability to control user access to the repository on a per-directory basis. For each subdirectory in the repository, you are able to specify read or read/write access (or no access) for individual users or groups of users.

To set up access on a per-directory basis, you need to load the mod_authz_svn.so module by placing a LoadModule mod_authz_svn.so entry after the LoadModule entry for mod_dav_svn.so. Then, configure your repository to use the Authz module, by pointing it to an access file, using the AuthzSVNAccessFile option. I'll explain shortly how to set up the access file. First, though, this is how you might build on the example <Location> section we've been using.

 <Location /myrepos>   DAV svn   SVNPath /srv/svnrepos   AuthzSVNAccessFile /srv/svnrepos/svn-authz-access   AuthType Basic   AuthName "My Subversion Repository"   AuthUserFile /srv/svnrepos/svn-auth-file   Require valid-user   SSLRequireSSL </Location> 

The Authz access file itself can be placed anywhere, but needs to be readable by Apache. The repository directory is a good choice, because the repository already needs to be accessible by Subversion, and logically you then keep the authorization file near to the repository.

The access file itself contains a number of directory sections, followed by the users who are allowed (or disallowed) access to that directory (and its subdirectories). For example, you might want to give read access for the whole repository to all valid users, but only give write access to the users melinda and joe, which would give you an access file that looked like the following:

 [/] * = r melinda = rw joe = rw 

Then, if you also want to give andrew write access to /branches, and deny access to /TRunk/private_project to everyone except bob, you could add the following two entries to your file. Notice that the wildcard entry in the private project section has no permissions listed after the =. This tells Subversion to deny all access to the given users (in this case, everyone who isn't explicitly listed).

 [/branches] andrew = rw [/trunk/private_project] * = bob = rw 

Additionally, you can set up groups of users that can be used in place of individual users in the directory permission sections. For instance, you might create a group that would be used for all of the developers on the project foo, to give them all read/write access to that project's directory. The following example shows how you would set up that group, and then use it in the directory section for foo. The @ is used in front of the foodevs group name to indicate that you are specifying a group, and not an individual user.

 [groups] foodevs = joe, bob, janet, trisha [/foo] * = r @foodevs = rw 

If you are using the SVNParentPath directive instead of SVNPath (see Chapter 3 for more information), you can have all of your repositories share a single access file. To specify permissions for a specific repository, a section label should have both the repository name and the path separated by a colon, as in the following access entries that set different permissions for the trunk directories of two different repositories.

 [repos_1:/trunk] betty = rw [repos_2:/trunk] * = r kate = rw 

If you are using SVNParentPath and you don't specify a specific repository, the given entry will apply to that path in all of your repositories. This can be handy, for instance, to have a common set of permissions for every /tags directory.

If you use wildcards in your Authz access file, permission will be granted for all valid users, but anonymous access will still be denied. If you would like to allow anonymous access, you need to add the Satisfy Any directive to your <Location>, so that it would look like this:

 <Location /myrepos>   DAV svn   SVNPath /srv/svnrepos   AuthzSVNAccessFile /srv/svnrepos/svn-authz-access   AuthType Basic   AuthName "My Subversion Repository"   AuthUserFile /srv/svnrepos/svn-auth-file   Require valid-user   Satisfy Any   SSLRequireSSL </Location> 

10.1.4. Authenticating against a Windows Domain Controller

Using Samba and Apache, you can get a Subversion repository on a Linux server to use a Windows Domain Controller (WDC) as the source for its valid user list and authentication information. This can be very handy if you have an existing Windows Domain that you use for other server authentication, as it negates the necessity for you to keep multiple sets of usernames up to date.[1]

[1] The steps for authenticating with a WDC, described in this section, were graciously provided by Stuart Robinson and his employer, Absolute Systems (www.absolutesys.com).

Configuring Apache

The first thing that you need to get working is the mod_auth_pam module for Apache. PAM (Pluggable Authentication Manager) will be used by Apache to authenticate with Samba (which will in turn talk to the domain controller). Most Apache installations don't have mod_auth_pam, so to get it you need to download it from the PAM project's Web site, pam.sourceforge.net/mod_auth_pam/. You should be able to build and install it by running make and make install in the mod_auth_pam source.

After you have mod_auth_pam installed, you need to enable it in Apache, by adding a LoadModule line to the Apache configuration file, which will look similar to the following example.

 LoadModule auth_pam_module modules/mod_auth_pam.so 

Additionally, you need to create a new file named /etc/pam.d/httpd (or edit if it already exists). This sets up PAM to grant access to users that have a Windows Domain account, but no local system account. To set this up, you will want your httpd file to look like the following.

 #%PAM-1.0 auth    required    pam_nologin.so auth    required    pam_stack.so service-system-auth account required    pam_permit.so 

After this is all done, Apache should be set up correctly. You can restart the Apache server and you'll be good to go. However, before Windows Domain accounts will work, you also need to set up Samba.

Configuring Samba

To configure Samba, you need to edit some of the options in the /etc/samba/smb.conf file. This file contains a large number of options, but the ones you need to edit are in the [global] section. When edited, the file will need to look something like the following.

 [global]    workgroup = MYWORKGRP    server string = Subversion    security = domain    password server = 192.168.0.128    wins server = 192.168.0.128    winbind enum users = yes    winbind enum groups = yes    obey pam restrictions = yes    realm = mydomain.com 

The details of all the possible Samba options are well beyond the scope of this book. However, the important options to pay attention to when setting up Windows Domain accounts are the workgroup, password server, and wins server. The IP addresses point to the WINS server, and the workgroup option defines the Windows Domain that you would like your Subversion server to connect to.

Next, you need to set up the Kerberos configuration files to point to the Windows Domain. To the file /etc/krb.conf, you need to add the lines

 myworkgrp myworkgrp    192.168.0.128:88 myworkgrp    192.168.0.122:88 admin server 

And to the /etc/krb5.conf file, you need to add a default_realm entry to the [libdefaults] section, so that it looks something like the following.

 [libdefaults]    default_realm = myworkgrp    dns_lookup_realm = true    dns_lookup_kdc = true 

Also, to the same file, you need to add the following line to the [realms] section.

 [realms]    myworkgrp = {      kdc = 192.168.0.128:88      admin_server = 192.168.0.128:88    } 

Then, you need to set up /etc/nsswitch.conf to include references to winbind. (Note: These are not the only entries in the file, just the ones that should reference winbind.)

 passwd:        files winbind shadow:        files winbind group:         files winbind protocols:     files winbind services:      files winbind netgroup:      files winbind automount:     files winbind 

After /etc/nsswitch.conf is edited, you need to set up PAM to use winbind. To do this, edit the /etc/pam.d/system-auth file and add the following three lines:

 auth      sufficient  /lib/security/$ISA/pam_winbind.so use_first_pass account    [default=bsd success=ok user_unknown=ignore] /lib/security/$ISA/pam_winbind.so password  sufficient  /lib/security/$ISA/pam_winbind.so use_authtok 

When all of these files are correctly configured, you can restart smb and winbind (likely by running /etc/init.d/samba restart and /etc/init.d/winbind restart). After things are restarted, you can tell Samba to join the Windows Domain by running

 $ net join -w MYWORKGRP -U Administrator 



    Subversion Version Control. Using The Subversion Version Control System in Development Projects
    Subversion Version Control. Using The Subversion Version Control System in Development Projects
    ISBN: 131855182
    EAN: N/A
    Year: 2005
    Pages: 132

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net