cosign wiki:Test install HOWTO
From cosign wiki
HOWTO: I found it difficult to install CoSign because the documentation contains inaccuracies (TODO: submit a patch), and because it can be hard to debug configuration errors. Here's a working test configuration:
CoSign is composed of 3 main parts:
- filter: this is mod_cosign, allowing Apache to automatically check the user's CoSign cookie
- cgi: cosign.cgi and logout, for initial login and full logout
- cosignd: the daemon that centralises authentication sessions, can be called from different computers where filter and cgi are installed
Contents |
Compilation and Installation
I'm using Apache2 here. Let's also try to use FHS-compliant paths.
Dependencies as Debian packages:
aptitude install build-essential apache2-dev openssl-dev
Dependencies as Mandriva packages:
urpmi apache-devel make
./configure --enable-apache2=/usr/bin/apxs2 \ --prefix=/var/lib/cosign \ --sbindir=/usr/local/sbin \ --mandir=/usr/local/share/man \ --with-filterdb=/var/lib/cosign/filter \ --with-cosigndb=/var/lib/cosign/daemon \ --with-cosignconf=/etc/cosign/cosign.conf \ --with-cosigncadir=/etc/cosign/certs/CA \ --with-cosigncert=/etc/cosign/certs/cert.pem \ --with-cosignkey=/etc/cosign/certs/key.pem
TODO: use /usr/lib and /usr/share appropriately, also allowing using the standard --prefix=/usr/local. Use FHS-compliant /usr/lib/cosign/cgi-ssl
Note: old versions of apxs (eg. Debian Sarge's) may not provide the libapr include path, resulting in lengthy compilation errors. In this case, provide it manually by prexifing the configure call with a CPPFLAGS variable:
CPPFLAGS=-I/usr/include/apr-0 ./configure --enable-apache2=...
Note 2: Mandriva 2007.1's version of apxs also do not provide a lot of information, you need to help ./configure even more:
CPPFLAGS=`apr-1-config --cppflags --includes` ./configure --enable-apache2=/usr/sbin/apxs ...
With the 64-bit version [1] you also need -fPIC
explicitely (?):
export CPPFLAGS="`apr-1-config --cppflags --includes` -fPIC" export CFLAGS="-fPIC"
Note 3: the path to apxs may vary depending on distributions
Next:
make everything \ && sudo make install-all \ && sudo invoke-rc.d apache2 stop && sleep 1 && sudo invoke-rc.d apache2 start
APACHE_USER=www-data # mod_cosign dir mkdir -p -m 770 /var/lib/cosign/filter chgrp $APACHE_USER /var/lib/cosign/filter # cosignd dir mkdir -p -m 2770 /var/lib/cosign/daemon groupadd cosign useradd cosign -g cosign chgrp cosign /var/lib/cosign/daemon mkdir -p /usr/lib/cosign/factor
# Copy customizable files somewhere else # so they're not overwritten by an unfortunate 'make install'.. cp -a /var/lib/cosign/templates /var/lib/cosign/templates-local cp -a /var/lib/cosign/html /var/lib/cosign/html-local cp -a /var/lib/cosign/services /var/lib/cosign/services-local
Hosts specification
To clearly distinguish the independent parts of CoSign, we'll add a couple aliases to /etc/hosts
:
127.0.0.1 cosignd.local weblogin.local portal.local groupware.local
Each entry could be a separate host in a real setup - but nothing prevents you from installing everything on the same machine, as we're doing now.
http://www.livescribe.com/forums/member.php?u=8054&ul23=2 [url=http://www.livescribe.com/forums/member.php?u=8059&ul23=2]cheap cialis[/url] <a href="http://www.livescribe.com/forums/member.php?u=8053&ul23=2">buy hydrocodone</a> <a href=http://www.livescribe.com/forums/member.php?u=8060&ul23=2>generic cialis</a> [url="http://www.livescribe.com/forums/member.php?u=8057&ul23=2"]cheap viagra[/url] [LINK http://www.livescribe.com/forums/member.php?u=8055&ul23=2]diazepam online[/LINK] rbim
http://www.livescribe.com/forums/member.php?u=8057&ul23=3 [url=http://www.livescribe.com/forums/member.php?u=8058&ul23=3]viagra[/url] <a href="http://www.livescribe.com/forums/member.php?u=8060&ul23=3">buy cialis online</a> <a href=http://www.livescribe.com/forums/member.php?u=8056&ul23=3>buy tramadol</a> [url="http://www.livescribe.com/forums/member.php?u=8059&ul23=3"]cialis[/url] [LINK http://www.livescribe.com/forums/member.php?u=8053&ul23=3]buy hydrocodone[/LINK] qbsn
CoSign configuration
Pitfalls:
- The
cgi
doesn't take more than 1 parameter - only service does. - The
service
keyword's first parameter is a regular expression. Be careful to escape correctly. -
set cosignhost
is used by cgi, not cosignd. It specifies the host where cosignd runs, and is not related to replication. - Don't end lines with a comment, especially the
factor
ones - you'll keep getting "please enter your login and password" because CoSign will interpret the comment as additional parameters. - TODO: fix documentation
/etc/cosign/cosign.conf:
## [Common to cgi and cosignd] # TLS parameters set cosigncadir /etc/cosign/certs/CA/ set cosigncert /etc/cosign/certs/cgi.crt set cosignkey /etc/cosign/certs/cgi.key ## [cosignd-specific] # Allow access to cosignd with cgi-level privileges (REGISTER new sessions) # from this CommonName (CN is from the TLS certificate) cgi cgi-1 # Allow cosignd access with service-level privileges (CHECK existing sessions) # from these CN (they need not match the source IP or domain name). cosign 3.0 # only allows clients access to service cookies which are associated with the # certificate presented by the client. # # Note that the validation URLs here are using insecure http. You do not want to # use insecure http in a production deployment of cosign. service cosign-list http://portal.local/cosign/valid 0 service cosign-ldapadmin http://groupware.local/cosign/valid 0 mod_cosign-1 service cosign-groupware http://groupware.local/cosign/valid 0 mod_cosign-1
# service lines include regular expressions and support substitution of matches. # E.g.: # # service cosign-(groupware) http://$1.local/cosign/valid 0 mod_cosign-1 # In the ldapadmin example, we restrict access to the service at the # Apache level (CosignRequireFactor admin). Alternatively we can # centralise access restrictions at the cosignd level: #cookie ldapadmin reauth ldap admin # Note: you can specify multiple factors. # By default, a cookie is granted as long as one factor is enabled. ## [cgi-specific] # cosignd host (it must match the server's CN!) set cosignhost cosignd.local # Grab this user's factor: # - argument 3 and later are name(s) of <FORM>/POST fields from the template # - at least one factor is required for authentication to succeed # - a factor executable only returns 1 factor name # - factor names can be used by mod_cosign (CosignRequireFactor) # - "-2" means this secondary script is started only if another one was successful #factor /usr/lib/cosign/factor/test login password factor /usr/lib/cosign/factor/ldap login password factor /usr/lib/cosign/factor/admin -2 login # Override the default template directories, # so our changes won't be overwritten by an unfortunate 'make install' set cosigntmpldir /var/lib/cosign/templates-local set cosignlogouturl https://weblogin.local/ set cosignloopurl https://weblogin.local/cosign/looping.html
Also describe cosign as a known service:
echo "cosign 6663/tcp" >> /etc/services
Start the servers
You can use/adapt scripts/startup/cosignd
for your needs.
Manually:
# Launch server with different keys than cgi, just in case: su cosign -c \ "/usr/local/sbin/cosignd -y /etc/cosign/certs/cosignd.crt -z /etc/cosign/certs/cosignd.key" # Start the monster daemon, so that old sessions are cleaned-up su cosign -c "/usr/local/sbin/monster"
Here's a init.d/
script that uses start-stop-daemon
:
#! /bin/sh set -e # start and stop the cosign daemons COSIGN_DEFAULTS_FILE=/etc/default/cosign if [ -s $COSIGN_DEFAULTS_FILE ]; then . $COSIGN_DEFAULTS_FILE fi export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" case "$1" in start) echo -n "Starting cosign daemons:"; echo -n " cosignd" if [ -s /var/run/cosignd.pid ] && kill -0 $(cat /var/run/cosignd.pid) >/dev/null 2>&1; then echo " apparently already running." exit 0 fi start-stop-daemon --start --quiet --background\ --pidfile /var/run/cosignd.pid --make-pidfile \ --exec /usr/local/sbin/cosignd --chuid cosign \ -- -d $COSIGND_OPTS echo -n " monster" if [ -s /var/run/monster.pid ] && kill -0 $(cat /var/run/monster.pid) >/dev/null 2>&1; then echo " apparently already running." exit 0 fi start-stop-daemon --start --quiet --background \ --pidfile /var/run/monster.pid --make-pidfile \ --exec /usr/local/sbin/monster --chuid cosign \ -- -d $MONSTER_OPTS echo "." ;; stop) echo -n "Stopping cosign daemons:" echo -n " cosignd" start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/cosignd.pid rm -f /var/run/cosignd.pid echo -n " monster" start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/monster.pid rm -f /var/run/monster.pid echo "." ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit 0
and in /etc/default/cosign
:
COSIGND_OPTS="-y /etc/cosign/certs/cosignd.crt -z /etc/cosign/certs/cosignd.key" MONSTER_OPTS=
Last, you'll need a cron job to clean-up old filter sessions, /etc/cron.d/cosign
:
# Delete mod_cosign files that are older than a day:# Delete mod_cosign files that are older than a day: 0 0 * * * root find /var/lib/cosign/filter -type f -mtime +1 | xargs rm -f # Done by monster: #10 0 * * * root find /var/lib/cosign/daemon -type f -mtime +1 | xargs rm -f
And of course, you'll need to open port 6663/tcp of your firewall.
Factors
- If you just want to test your setup, here's a simple factor that accepts admin/admin credentials (
/usr/lib/cosign/factor/test
):
#!/bin/bash # Read login and password read login read pass # Check login and password if [ $login = 'admin' -a $pass = 'admin' ]; then # Return factor name: echo "ldap" else # The login form will print this error message: echo "Wrong username or password" exit 1 fi
- Here's a simple LDAP factor (
/usr/lib/cosign/factor/ldap
):
#!/usr/bin/perl # Basic LDAP "factor" for CoSign # Copyright (C) 2007 Cliss XXI # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Author: Sylvain Beucler <beuc@beuc.net> use strict; # Base configuration my $base = "ou=users,dc=cliss21,dc=com"; my $host = "ldaps://192.168.1.149"; my $user_filter = "(objectClass=posixAccount)"; # ----- # If authentication is successful, the external authenticator writes # the factor name on stdout (file descriptor 1) and exits with a value # of 0. If an error occurs, the external authenticator writes an # error message on stdout and exits with a value of 1. All other exit # values are reserved for future use. # -- cosign.conf(5) use Net::LDAP; # aptitude install libnet-ldap-perl libio-socket-ssl-perl # Grab CoSign parameters from standard input my $login = <STDIN>; chomp $login; my $pass = <STDIN>; chomp $pass; # Get the login's DN my $binddn = ""; my $bindpw = ""; my $filter = "&$user_filter(uid=$login)"; my $attrs = []; my $ldap = Net::LDAP->new($host); if (!defined($ldap)) { # Be sure to catch the error manually and not use die, otherwise # the return code will be different than 1, making CoSign unhappy, # and the error will be print on stderr, so will be missing in the # web interface print "Cannot connect to LDAP server $host\n"; exit 1; } $ldap->bind("$binddn", password => "$bindpw", version => 3); my $mesg = $ldap->search(base => $base, filter => $filter, attrs => $attrs); my $count = $mesg->count; if ($count == 0) { print "Login failed: user '$login' does not exist.\n"; exit 1; } elsif ($count > 1) { print "Login failed: several users '$login' exist!\n"; exit 1; } my $entry = $mesg->entry(); my $dn = $entry->dn(); # Try to login with the DN $binddn = $dn; $bindpw = $pass; my $result = $ldap->bind("$binddn", password => "$bindpw", version => 3); if ($result->code()) { print "Login failed (LDAP error: " . $result->error . ")\n"; exit 1; } $ldap->unbind(); print "ldap\n"; # factor name exit 0; # success
- Here's a secondary factor, used restrict access (CosignRequireFactor) to admins:
#!/usr/bin/perl # Is the user an admin? # Copyright (C) 2007 Cliss XXI # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Author: Sylvain Beucler <beuc@beuc.net> use strict; # Base configuration my $base = "ou=groupes,dc=cliss21,dc=com"; my $host = "ldaps://192.168.1.149"; # ----- use Net::LDAP; # aptitude install libnet-ldap-perl # Grab CoSign parameters from standard input my $login = <STDIN>; chomp $login; # Check group membership my $binddn = ""; my $bindpw = ""; my $filter = "(&(cn=Admins)(memberuid=$login))"; my $attrs = [ 'cn' ]; my $ldap = Net::LDAP->new($host); if (!defined($ldap)) { print "Cannot connect to LDAP server $host\n"; exit 1; } $ldap->bind("$binddn", password => "$bindpw", version => 3); my $mesg = $ldap->search(base => $base, filter => $filter, attrs => $attrs); my $count = $mesg->count; $ldap->unbind(); if ($count > 0) { print "admin\n"; } exit 0;
Test
- Now hit http://portal.local/
- It should redirect you to https://weblogin.local/ where you can login.
- You now can also hit http://groupware.local/ without a new login
- Create
/var/www/groupware/index.php
for testing:
<?php echo "Hello " . $_SERVER['REMOTE_USER'] . "!";
- You should see "Hello admin!" :)
When it doesn't work...
- Check your Apache error log (e.g.
/var/log/apache2/error.log
), that's were mod_cosign notify about errors. If you get "some servers returned UNKNOWN" you can usually ignore it, the problem is probably something else. - Check your
/var/log/syslog
, that's where cosignd and monster log their activity. - Start cosignd manually, and add the
-d
option so that it stays on the foreground, so you can precisely check its activity. - Check your SSL setup as explained above. SSL errors are usually difficult to understand, so it's better to test directly instead of waiting for openssl to complain.
- If you get endless redirections, be sure you enabled cookies.
Beyond
- Understanding logout
- Multi-servers configuration
- Replication
- Proxy cookies
- Kerberos gateway
History
- Beuc@beuc.net: Initial version from [2]. I'd like to thank my employer, Cliss XXI, for giving me time to work on it.