HTTPS access to SVN repositories |
| |
| 2008-11-22 13:00:00 |
Introduction
It's possibile to configure an HTTPS access to Subversion repositories, using a webserver like Apache2.2, with WebDAV functionalities provided by the DAV apache modules. The SSL connection provides a secure tunnel and users will authenticate against a OpenLDAP directory service authenticating only users pertaining to a allowed group.
Structure
The HTTPS will be made available by a front-end web server, Nginx, HTTP reverse-proxying to Apache2 on port 80, that will take care of users authetication and authorization, accessing the subversion repositories. The Apache2.2 virtual host will be running as a system user owning the repositories and thus having the needed read and write permissions.
Nginx will be listening on the public IP interface on port 443 (or another port of choice) making the SSL connection using self signed certificate and key. Apache2.2 can be installed on the same machine and listening on the loopback, or can be installed on another virtual or physical machine in a private IP network, listening on port 80. Having the back-end server on a private network is a choice of network design, it can be varied on particular needings as well, but it will be the only one discussed here.
The operating system of choice is GNU/Linux, having a SLES10.3 SP1 running on the front-end machine and a Ubuntu 8.10 server edition on the back-end server.
The (not so)big picture
Contents
- Nginx, compilation and installation
- OpenSSL certificate and key generation
- Installing SSL key and certificate in Nginx
- Apache2.2 installation and configuration
- Nginx, HTTPS reverse-proxying to apache2
- Apache2, configuring the LDAP authentication
- Apache2, configuring the SVN DAV modules and access
- Subversion, creating and migrating repositories
1. Nginx, compilation and installation
In the Nginx compilation and installation wiki page there's thorough documentation giving details on the process, here will be showed an example of how to compile with the required SSL module, so get in the /usr/local/ directory and download the sources tar.gz package:
wget http://sysoev.ru/nginx/nginx-0.6.32.tar.gz
and unpack it:
tar -xzf nginx-0.6.32.tar.gz
before running the configure script it can be useful to check for latest updates to the configuration process:
./configure --help
get in the source directory and run the configure script:
./configure --with-http_ssl_module
and then compile:
make
make install
the contents of the sources dir should be as follows:
client_body_temp/
conf/
fastcgi_temp/
html/
logs/
proxy_temp/
sbin/
having the nginx binary in the sbin/ directory.
1.2 Nginx configuration and test
An init script is needed in order to manage the sevice and correctly boot-up:
#! /bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the nginx web server
# Description: starts nginx using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/sbin/nginx
NAME=nginx
DESC=nginx
test -x $DAEMON || exit 0
# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
. /etc/default/nginx
fi
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
--exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/nginx.pid
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile \
/usr/local/nginx/logs/nginx.pid --exec $DAEMON
sleep 1
start-stop-daemon --start --quiet --pidfile \
/usr/local/nginx/logs/nginx.pid --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/nginx.pid \
--exec $DAEMON
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
edit it as needed then copy the above script in the /etc/init.d/ directory and add it to the default runlevels using chkconfig command:
chkconfig --add /etc/init.d/nginx
as a facility, create the symlink to the boot script in the SLES style:
ln -s /etc/init.d/nginx /usr/sbin/rcnginx
before starting the Nginx web server, a minimum configuration of the main nginx.conf file is needed, giving the webserver a name through the server_name directive; if a DNS hostname is not yet available, it's possibile to configure a static route (fake host in the /etc/hosts file in the local desktop computer in the case of unix based OSes) just for testing/learning before releasing, and make sure the listen directive is, for now, with value 80 and then, as root,
start the server:
root# rcnginx start
and using a web-browser verify that a 200 http response is received, usually displaying the default static page.
2. OpenSSL certificate and key generation
A private key and certificate for the nginx server are needed in order to make the SSL connection possible, in this a self signed-certificate will be created and used, it's assumed that a OpenSSL installation is already available in the running SLES10.
Generating the key:
root# openssl genrsa -out privkey 1024
generating the certificate request:
root# openssl req -new -key privkey -out signing_request
note: a few params will be requested, the most important is the 'Common Name' which has to be the server name otherwise the certificate will not be accepted, having the nginx unable to initiate the SSL connection itself.
generating the self-signed certificate:
root# openssl x509 -req -days <validity_days_in_number> -in signing_request -signkey privkey -out server_certificate
issuing the last opennsl command will generate the certificate to be configured in the nginx server, for a deeper and complete OpenSSL documentation refer to the local installation Docs and/or make a websearch.
3. Installing SSL key and certificate in Nginx
3.1 Confgiuring Nginx
In order to have Nginx correctly initiate and establish a HTTPS connection, the generated certificate file and key must be installed.
The Virtual Hosts configuration will be kept in separate files and location than the nginx.conf, in a directory contained under the conf/ dir of the Nginx installation:
/usr/local/nginx/conf/sites-available
/usr/local/nginx/conf/sites-enabled
as can be noted the Debian style won. In the sites-available directory will be put the Virtual Host files holding the host specific configurations, while in the sites-enabled will be put the symlinks pointing to the hosts wanted to be live. In the nginx.conf main configuration file will be specified the directive to include the sites-enabled contents, as following:
# Virtual hosts a la Debian
include sites-enabled/*;
in the sites-available directory, copy a file as the following:
server {
listen 443;
server_name hostname.domain;
ssl on;
ssl_certificate /etc/ssl/certs/server_certificate;
ssl_certificate_key /etc/ssl/certs/privkey;
access_log logs/hostname.domain_access.log;
error_log logs/hostname.domain_error.log;
location / {
root html;
index index.html index.htm;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header Host $http_host;
# proxy_pass http://IP_Addr;
# proxy_redirect off;
set $dest $http_destination;
if ($http_destination ~ "^https://(.+)") {
set $dest http://$1;
}
}
}
by reading the ssl_certificate and ssl_certificate_key directives values, the locations of certificate file and key can be found, after editing the configuration file, symlink this file from the sites-enabled directory to make them included and restart the nginx server.
After restarting nginx, open a https connection in the web-browser and verify the SSL connection working without errors.
The Nginx configuration can be considerd complete and working, later on nginx will be configured to reverse-proxy to apache2.
4. Apache2.2 installation and configuration
4.1 Installing Apache2 mpm-ITK
In order to have every Virtual Host running under a separate user, apache2 mpm-itk will be installed on the Ubuntu back-end server:
root# aptitude install apache2-mpm-itk
4.2 configuring the base Virtual Host
On the machine hosting the central repositories, there will be the need to create and administer the subversion repositories themselves, for this reason a special user, dedicated to the purpose, will be created:
root# addgroup --system scm-local
root# adduser --system --home /path/to/repos -g scm-local scm
in this way, the directory trees starting from the scm home dir will have a coherent permissions scheme, and the scm user will be the user the VirtualHost will be running as. The group is named scm-local because there is a already created and populated LDAP group named scm.
The basic apache2 virtual host configuration will be similar to:
<VirtualHost IP_addr:80>
ServerName hostname.dominio
ErrorLog /path/to/logs/scm_error
CustomLog /path/to/logs/scm_access combined
# assign the scm user to this VH
AssignUserID scm scm-local
# only needed for testing
DocumentRoot /scm/home/dir
</VirtualHost>
after testing the acces, on the local listening IP interface, using a web-browser(elinks) and verified that everything is running, the next step will be to configure Nginx to reverse proxy to apache2
5. Nginx, HTTPS reverse-proxying to apache2
In the nginx virtual host configuration file uncomment the proxy_* directives and comment the root and index directives and test by accessing the https://hostname.domain from the outside, the default apache2 static page, in the DocumentRoot should be displayed while apache should give a 200 http response.
It is now time to get on the Apache2.2 SVN and LDAP configuration.
6. Apache2, configuring the LDAP authentication
6.1 Installing the Apache2 needed modules
On the back-end server install the modules for LDAP authentication, as root:
root# a2enmod authnz_ldap
then modify the virtual host configuration:
<VirtualHost IP_addr:80>
ServerName hostname.domain
ErrorLog /path/to/logs/error
CustomLog /path/to/logs/access combined
# assign the scm user to this VH
AssignUserID scm scm-local
DocumentRoot /scm/home/dir
UseCanonicalName on
AuthType basic
AuthUserFile /dev/null
AuthBasicProvider ldap
AuthName "SCM auth"
AuthzLDAPAuthoritative on
AuthLDAPURL "ldap://IP_addr:PORT/ou=people,DC=hostname,DC=domain?uid?sub?"
require valid-user
require ldap-group cn=Group_name,ou=group,dc=hostname,dc=domain
</VirtualHost>
as usual, make a test accessing the hostname.domain trying to authenticate a user with correct credenials and group membership, then with un unprivileged user and be sure to get success and error responses.
7. Apache2, configuring the SVN DAV modules and access
7.1 Installing the dav modules:
as root:
root# a2enmod dav_svn
and modify the virtual host configuration as following:
<VirtualHost IP_addr:80>
ServerName hostname.domain
ErrorLog /path/to/logs/error
CustomLog /path/to/logs/access combined
# assign the scm user to this VH
AssignUserID scm scm-local
UseCanonicalName on
<Location /repos>
DAV svn
SVNParentPath /path/to/repos
SVNListParentPath on
AuthType basic
AuthUserFile /dev/null
AuthBasicProvider ldap
AuthName "SCM auth"
AuthzLDAPAuthoritative on
AuthLDAPURL "ldap://IP_Addr:Port/ou=people,DC=hostname,DC=domain?uid?sub?"
require valid-user
require ldap-group cn=Scm,ou=group,dc=hostname,dc=domain
</Location>
</VirtualHost>
after these changes to the configuration it's possible to use the repositories as either using the svn CLI or web access. The use of UseCanonicalName on is in conjunction with the set destination Nginx configuration, in order to make DAV correctly operating on files and destinations.
8. Subversion, creating and migrating repositories
Since Subversion 1.5 has been released, i took the chance to migrate the repositories to the new version:
on the back-end server, which hosts the SVN repositories, become the 'scm' user and start creating the new repositories:
scm$ svnadmin create repo1
it is a good time now for testing the access to the newly created repository and make some test commit/update just to be sure all the structure is working as wanted;
to migrate the repositories a dump of the old ones is needed, so get on the old svn central repositories machine and issue a dump:
scm$ svnadmin dump repo_name > repo_name_oldversion.dump
and transfer the file containing the dump on the back-end server in the 'scm' home directory, maybe by using a scp copy;
before loading the dump create the repository named as the old one which the dump comes from:
scm$ svnadmin create repo_name
and then load the dump:
scm$ svnadmin load repo_name < repo_name_oldversion.dump
this was a brief example of subversion dump/load cycle.
Conclusions
This was quite a fast tour in configuring such a structure, by following it are not excluded issues, but in this way it should be possible to use a subversion repositories collection by either svn cli or web-access. Hope it helps.
|
|
|