moonwatcher.it

Gianluca Riccardi's minimalistic website.

Home About

APOD Full Moon Silhouettes

Couldn't miss this, which I think is quite appropriate here ;) Enjoy this short Video published in today's APOD


[Read entire article]


Apache multiple authentication methods and options

Introduction

Apache2 can use several authentication methods and options in order to allow access to the same resource, configured in a single VirtualHost.

In the following case i've illustrated how i solved the needing to access via two different authentication/authorization methods the same <Location></Location> by users registered on different authentication systems and so to have different kinds of permissions on the resource, in this case, subversion repositories.

The Study case

The developers team of the company i actually work for, expressed the needing to give external occasional supporting developers, access to our subversion repositories made available through Apache2 HTTPS connection, behind a Nginx reverse proxy. They didn't want to register the external developers in our corporate SSO (OpenLDAP), instead they wanted to have them in separate authentication/authorization system, able to manage permissions on the repositories too.

Environment

Ubuntu 8.04 LTS in KVM virtual machine

  • Subversion 1.5.1

  • Apache2 mpm-itk

  • OpenSSL

Apache2 modules, basically the following:

  • auth_basic_module

  • mod_authn_file

  • authnz_ldap_module

  • dav_module

  • dav_svn_module

  • ldap_module

  • authz_svn_module

  • authn_alias_module, which is in the core as demonstrated by:

  • root@vm:/etc/apache2/sites-available# dpkg -S mod_authn_alias.so

  • apache2.2-common: /usr/lib/apache2/modules/mod_authn_alias.so

Pre-Requisites

An OpeLDAP server somewhere, already giving authentication;

Subversion installed and functional on the same machine and already giving privileges management through a svn_auth_file.

The Configuration

This functionality is available by using the apache2 directive: AuthnProviderAlias via the authn_alias_module obtained installing the package apache2.2-common. The directive's operating context is: server config, so it has to be inserted, in the case of Debian-based systems, in the /etc/apache2/apache2.conf.

The purpose is to to configure a set of authentication methods that can be made available to the VirtualHost's Location directives. The directive allows to define the method itself, a name for a single method and other specific configuration parameters, by specifing a directive for every single authentication method to be used. The AuthBasicProvider directive can then be used in the Location directives to make effectively use of them listing names after it. In this way the administrator can use a mix of authentication methods as needed per VirtualHost's Locations. Other specific configuration can be used inside the Location directive itself, as the LDAP DN, paths to privileges files and so on.

For this case i've used apache2-mpm-itk, which is stated to be still in experimental stage, so use it at your own risk, surely there are other methods to make an Apache2 VirtualHost run under a specified user. Furthermore there has to be take into consideration that the mpm-itk is a de facto version of a prefork, so: no threading.

The choice to make this VirtualHost running under a specified user is to give DAV physical access to the repositories in a permissions' coherent way, since the readings/writings operations are made by dav_svn_module installed via libapache2-svn Debian package.

The "AssignUserID uid gid" allows to specify, respectively, user name and group name to run under and its specific to mpm-itk

The usage of "UseCanonicalName on" makes DAV correctly identifying names to access the repositories since i'm using apache as a backend, in this way it correctly determines names as the Nginx reverse proxy passes through.

External users are authenticated on a htpasswd file, their permissions and privileges on the repositories are configured in a svn_auth_file, which defines users, groups of users and kind of permissions, it's related to only subversion, and in this case, is the second authentication/authorization system.

A configuration example follows:

apache2.conf excerpt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<AuthnProviderAlias ldap ldap1 >
    AuthBasicProvider ldap
    # just an example
    AuthLDAPURL "ldap://IP_or_DOMAIN/ou=organization-unit,DC=domain,DC=tld?uid?sub?"
</AuthnProviderAlias>

<AuthnProviderAlias file svnfile>
    AuthUserFile /path/to/your/.htpasswd
    AuthzSVNAccessFile /path/to/your/svn_conf/authz_access.conf
</AuthnProviderAlias&>

VirtualHost.conf excerpt(replace the file name accordingly):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<VirtualHost *>

  ServerName scm.domain.tld
  ServerAdmin sysadm@domain.tld

  ErrorLog /var/logs/error
  CustomLog /var/logs/access combined

  # accept up to 10MB file size uploads
  LimitRequestBody 10485760

  # assign the uid and gid user to this VH
  AssignUserID uid gid

  UseCanonicalName on

  <Location /repos>

    DAV svn
    SVNParentPath /path/to/svn_repos_dir
    SVNListParentPath on

    AuthBasicProvider ldap1 svnfile

    AuthType basic
    AuthName "Your REALM name here"
    AuthzLDAPAuthoritative on

    # owned by uid
    AuthzSVNAccessFile /path/to/conf/authz_access.conf

    require valid-user
    require ldap-group cn=gid,ou=group,dc=domain,dc=tld

  </Location>
</VirtualHost>

In this way it'll be possibile access the repositories with a URL like https://domain.tld/repos/repo_name by using a registered user name in either OpenLDAP or htpasswd file when the authentication credentials will be requested. The users in the htpasswd file will be subject to the permissions defined in the SVN authentication file /path/to/conf/authz_access.conf.

The configuration illustrated here is just A solution not THE solution, i think there can be find other ways of accomplishing the same results, so use the above instructions at your own risk, i'm not responsible of what the reader does on her/his administered systems.

HTH,

Gianluca

Some References

The AuthnProviderAlias directive

The AuthBasicProvider directive

The authz_svn_module configuration directives

The dav_svn_module configuration directives

The Apache MPM-ITK

The dav_svn_module Configuration Directives, from the svnbook

The authz_svn_module directives, from the svnbook

SVN Path-Based Authorization, from the svnbook


[Read entire article]


HTTPS access to SVN repositories

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.

Contents

  1. Nginx, compilation and installation
  2. OpenSSL certificate and key generation
  3. Installing SSL key and certificate in Nginx
  4. Apache2.2 installation and configuration
  5. Nginx, HTTPS reverse-proxying to apache2
  6. Apache2, configuring the LDAP authentication
  7. Apache2, configuring the SVN DAV modules and access
  8. 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:

1
2
3
4
5
6
7
        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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#! /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 -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:

1
2
3
        /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:

1
2
3
        # Virtual hosts a la Debian

        include sites-enabled/*;

in the sites-available directory, copy a file as the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
            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:

1
2
3
            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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    <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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        <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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
        <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.


[Read entire article]


Moon at 30:20:43.6, 187:32:51.3 observing from Rome, IT


Recent Posts

APOD Full Moon Silhouettes
Apache multiple authentication methods and options
HTTPS access to SVN repositories

Categories

Astro
Sysadmin

all entries feeds   follow me on twitter   my LinkedIn profile

Powered by Moonwatcher.it ShortPosts.