Auth External: the Swiss Army Knife of Apache Auth

When you need to deploy a custom, weird or non typical Auth schema with Apache, knowing about the Auth External module can save you tons of time.

It is is commonly deployed along with pwauth for allowing unix users to authenticate against Apache, but this only one case use. Actually it can be used for almost any Auth setup that you can imagine.

The main idea behind it is very simple and powerful, it delegates Apache authentication on any program or script that you want. Simply it will feed your program with the user/password variables along other interesting variables like IP, cookies, URI, etc. and your program must return zero if the user is allowed to access or non-zero otherwise.

I will show you a simple example.

” I have my home server where I run an LDAP directory with some users and I also have a remote server in a hosting company where I want to allow the users of my LDAP directory to access some https directory protected by the Apache authentication.

Accessing the LDAP directory from the remote server is not an option because I have a firewall protecting it and I can’t/don’t want to do such a thing. And configuring an slave LDAP server on the remote server is even a worse option.”

So here is when Auth external comes to rescue.

On my home server I configure a dummy https virtual host that authenticates users via the local LDAP

<VirtualHost *:443>
    
    SSLEngine on
    
    ServerName   dummy-https.homeserver.com
    ServerAdmin  clopez@igalia.com
    
    TransferLog  /var/log/apache2/dummy-https-access.log
    ErrorLog     /var/log/apache2/dummy-https-error.log
        
    <Directory /var/www/empty>
        AuthName Auth
        AuthType Basic
        AuthBasicProvider ldap
        AuthzLDAPAuthoritative On
        AuthLDAPURL "ldap://localhost/dc=homeserver,dc=com?uid"
        AuthLDAPGroupAttribute uniqueMember
        AuthLDAPGroupAttributeIsDN On
        Require valid-user
        Order allow,deny
        Allow from all
    </Directory>

</VirtualHost>

And on the remote server I just implement a very simple script that will read from stdin an user and password strings and will try to establish an https connection with my apache home server using the supplied credentials. It will return zero if it can get the connection, otherwise will return 1

#! /bin/sh
read user
read password
/usr/bin/curl -f -u "$user":"$password" https://dummy-https.homeserver.com >/dev/null 2>&1 || exit 1
exit 0

I saved this script as /usr/local/bin/home-ssl.sh and now I will install the auth external module and will enable it

apt-get install libapache2-mod-authnz-external
a2enmod authnz_external

Note: for Debian Lenny grab the backport’s package

And now I will configure the Apache virtual host with the auth external authentication:

<VirtualHost *:443>
    
    SSLEngine on
    
    ServerName   securearea.hostingprovider.com
    ServerAdmin  clopez@igalia.com
    
    TransferLog  /var/log/apache2/securearea.hostingprovider-access.log
    ErrorLog     /var/log/apache2/securearea.hostingprovider-error.log
      
    DocumentRoot /var/www/securearea
        
    <Directory /var/www/securearea>
        AuthType Basic
        AuthName "Restricted"
        AuthBasicProvider external
        AuthExternal home-ssl
        require valid-user
    </Directory>

    AddExternalAuth home-ssl /usr/local/bin/home-ssl.sh
    SetExternalAuthMethod home-ssl pipe

</VirtualHost>

In summary:

  • User access https://securearea.hostingprovider.com/
  • Apache@hostingprovider ask user for credentials
  • Apache@hostingprovider calls /usr/local/bin/home-ssl.sh and feed it with user credentials
  • /usr/local/bin/home-ssl.sh calls Apache@homeserver at https://dummy-https.homeserver.com
  • Apache@homeserver ask for user credentials to local LDAP database
  • If credentials are correct Apache@homeserver will allow /usr/local/bin/home-ssl.sh to access making it to return zero so the user will be allowed to access securearea at Apache@hostingprovider

Want to write an external authenticator? Here you have a quick howto Enjoy !

Workaround for the time drift issue on Xen: keep your guests synced

Suppose that you want to keep the clock of one or more Xen guests synchronized with a NTP server and the Xen Host has the clock desynchronized. Also to screw things more you don’t has access to the Xen host so you can’t simply fix the clock of the Host. What can you do?

In order to be able to change the clock time of your guest you need to activate the independent_wallclock bit , and then you will be able to sync it.

echo 1 > /proc/sys/xen/independent_wallclock

But if you left this bit enabled soon you will notice some weird problems:

# ping google.es
PING google.es (173.194.37.104) 56(84) bytes of data.
Warning: time of day goes back (-21us), taking countermeasures.
Warning: time of day goes back (-23us), taking countermeasures.
64 bytes from lhr14s02-in-f104.1e100.net (173.194.37.104): icmp_seq=1 ttl=47 time=0.000 ms
Warning: time of day goes back (-21us), taking countermeasures.
64 bytes from lhr14s02-in-f104.1e100.net (173.194.37.104): icmp_seq=2 ttl=47 time=0.000 ms
Warning: time of day goes back (-21us), taking countermeasures.

# date; date; date; date; date
Wed Sep 29 19:04:06 CEST 2010
Wed Sep 29 19:04:05 CEST 2010
Wed Sep 29 19:04:06 CEST 2010
Wed Sep 29 19:04:06 CEST 2010
Wed Sep 29 19:04:05 CEST 2010

Amazing huh?? looks like the Xen project is developing in secret the time travel algorithm.

The trick is that you must disable the bit independent_wallclock as soon as you has your clock synchronized and everything will work as expected.

echo 0 > /proc/sys/xen/independent_wallclock

Obviously this issue will prevent you to use a NTP daemon like ntpd / openntpd. So the simplest solution is to deploy a cron job that will sync your clock with ntpdate.

So, here is my cron.daily script to keep in sync the clock of the xen guests:

#! /bin/bash
# This is a DIRTY hack to allow have time settings correctly on Xen guests
# clopez@igalia.com
echo 1 > /proc/sys/xen/independent_wallclock
ntpdate -b pool.ntp.org 0.debian.pool.ntp.org hora.roa.es
echo 0 > /proc/sys/xen/independent_wallclock

If your Xen guest is proxied and don’t has direct access to Internet then you can use htpdate

#! /bin/bash
# This is another DIRTY hack to allow have time settings correctly on proxied Xen guests
# clopez@igalia.com
echo 1 > /proc/sys/xen/independent_wallclock
htpdate -s -P IP.ADDRESS.OF.PROXY:PORT www.linux.org www.google.com www.debian.org www.redhat.com
echo 0 > /proc/sys/xen/independent_wallclock

Hope this help you and you don’t have to waste your time thinking about how to fix the time as I did 😉

CompCache (ramzswap) for MeeGo 1.0

My girlfriend has one of the first netbooks that were launched long ago. It is the Acer Aspire One A110 model that ships with 512MB RAM and an 8 GB SSD disk (an Intel Z-P230). This SSD has been criticized for its slow read and write speed. Intel lists the drive’s maximum speeds as 38 MB/s read and 10 MB/s write. But I can sure that you will not get more than 5MB/s writing.

So imagine, with 512 of RAM and a disc that seems rather an SD card, having any modern operating system running smoothly can be quite painful.

So I decided to give a try to MeeGo on this machine and I liked the user interface and also I was surprised that it is running more smoothly than the previous Ubuntu NBR installation.

This notebook has only 512 RAM so without a swap device you can just open only a little more than the browser and a shell. But trying to put a swap on this disk would be like shooting yourself in the head.

So here is when the great project compcache comes to rescue. Unfortunately the kernel that comes with MeeGo does not include compcache nor is there any package available in the repositories, so if you are looking to enable compcache in MeeGo this is your lucky day.

I have compiled all the necessary bits to run compcache under MeeGo and I packaged it in an rpm file.  This package includes the ramzswap module and the lzo_compress module compiled to match the MeeGo 1.0 kernel (2.6.33.3-11.1-netbook), also it includes the rzscontrol utility and an init script to load the service at startup. You can download it from here and then just install it:

wget http://people.igalia.com/clopez/kmod-compcache-2.6.33.3-11.1.i586.rpm
sudo rpm -ivh kmod-compcache-2.6.33.3-11.1.i586.rpm

I have configured it to use the 75% of the total RAM available on the system for the RAM swap device. I have done different tests and with this configuration I was getting the best of this machine, nevertheless you can change this easily. After installing the package edit the file /etc/init.d/compcache and change the variable ratio=75 at the beginning of the file to what you want and restart the service.

Procmailgen : Easily classifying mailing lists in folders with procmail

Procmail is a program for filtering electronic mail. It is very useful for pre-sorting and pre-processing large amounts of incoming mail. You can use it to sort out mail from mailing lists, to dispose of junk mail, to send automatic replies, or even to run a mailing list.

I am using it to classify incoming mail from the mailing lists that I am subscribed into folders, and when you are subscribed to a large amount of mailing lists it can be painful to write all the rules and you might end with a copy-paste-monkey-complex. So I wrote an small program in Python that will generate a .procmailrc file for your convenience. You must feed the program with your email address and the path to a file containing the mailing lists that you are subscribed to and the folder you want them to be delivered.

The file has the following format:

[folder1]
list1@example.com
list2@example.com

[folder2]
list3@example.com
list4@example.com

A real example:

[debian-security]
debian-security-announce@lists.debian.org
debian-security@lists.debian.org

[networking]
debian-isp@lists.debian.org
debian-firewall@lists.debian.org
debian-ipv6@lists.debian.org
linux-net@vger.kernel.org
netdev@vger.kernel.org
netfilter@vger.kernel.org
netfilter-devel@vger.kernel.org

[wireless]
hostap@lists.shmoo.com
linux-wireless@vger.kernel.org

[filesystems]
linux-btrfs@vger.kernel.org
linux-raid@vger.kernel.org

And the program will generate a .procmailrc from the templates that are defined within it and output the file to stdout.

The current templates are optimised for Dovecot mailboxes and SpamAssassin filter but you can easily change it to feet your needs by editing them within the program file.

But this way I keep my subscriptions in easy-to-read-and-edit file and each time I change them I simply re-run procmailgen against it:

./procmailgen.py mailinglist-folders my@email.com >~/.procmailrc 

You can download the code here. Hope that you will find it useful. Don’t forget to create the mail folders with your email client.

UPDATE 01-2011: Moved the code to a repository at github and added support for managing RSS Feeds with rss2email

Review of X7SPA-HF : Loving IPMI and KVM over LAN

I am building a silent and eco-friendly (also electricitybill-friendly) Linux powered RAID5 NAS.  And in order to choose the CPU I read about the different low power CPU solutions and two different ones come to mind: Intel Atom and Via Nano. My first choice was Via Nano since it features 64-bit support and the wonderful PadLock engine that would allow me to get good transfer rates with crypted drives, but unfortunately, I could not find any fanless Via Nano motherboard with 4 SATA ports.

So I looked through Intel Atom D510 dual core 64-bit solutions and I found some motherboards with the specs I wanted, but one of them stood out especially on the other because it was designed by Supermicro (a server and high-end workstation manufacturer) and it has two Gigabit adapters so I can also use the NAS as a nice router/firewall.

There was two models of this board. The  X7SPA-HF is the same that the X7SPA-H but featuring IPMI with KVM-over-LAN for only 20 bucks more. I never heard of the IPMI technology so I read a little about it and finally I decided to give it a try.

And I really can tell you that it is very cool. You can remotely via network see the status of each sensor (temperature, voltage..), you can reset and power on/off the computer, and also you can control your computer remotely with a VNC-like interface with the IPMIView utility that works very good. You can also access the IPMI server via web interface.

At this point you must be thinking that it is nothing new under the sun that I cant do with an expensive IP-KVM, but its not true. The really socking feature that made me say WoW! is that I can attach a drive via the network.  Yes, I can attach any ISO or floppy image to the virtual drive with IPMI, and the Supermicro motherboard will see the drive as it really was a physical drive. It will appear in the BIOS and the OS will detect it as a standard SATA drive and will boot from it or use it as the rest of drives. For the records: I have just installed Debian on it by attaching the ISO image to the virtual cdrom ;).

This feature is very useful. I can boot any ISO image without burning a CD/DVD or even without writing it to an USB stick. I simply download it on my laptop, attach it to the virtual cdrom/dvdrom with IPMIView and voila! Magically I have the cdrom in the Supermicro board. Also an image of a floppy can be uploaded and the motherboard will detect it as an USB floppy, this can be tricky for managing disasters.

How it works?

The IPMI lives in the BMC so its OS/CPU independent, even if your OS crashes and you get fatal kernel panic, IPMI will still work and you could connect to the machine remotely and reset it. This board has two Gigabit NICs, one is a standard Gigabit NIC and the other is the IPMI one.

The IPMI NIC has two MAC address, one of this MAC address is only accessible for the BMC and the other is only accessible by the CPU, so the host OS is unaware of the BMC MAC and it will only see his own MAC (the CPU one).  Then this NIC will have two IPs, the OS one and the IPMI one.

You can configure the IPMI network in the BIOS of the board to get it via DHCP or assign an static one. The first time that you power up the motherboard it will took near 2 minutes for the BMC to start up IPMI, that will not happen again if you reboot, or next time you power up as long as you don’t power cut the PSU because the IPMI code is kept running in the BMC also if the board is powered off. This is handy because it allows you to power up the board remotely via IPMI.

How secure is it?

For accessing the IPMI server you must know the password, and it supports three limited class privileged accounts (admin, operator and user). There can be various users at the same time connected to the IPMI Server and you can see who is connected at this moment and also a log is keept. Also it supports email notifications and  LDAP and RADIUS authentication. Also the traffic can be encrypted at hardware level using AES / SSL and you can upload a new SSL certificate. So I think its very secure, nevertheless is a good practice to put the IPMI IPs on a different network than the rest of your network and secure it with a firewall.

The BIOS of this board is also very complete and has a lot of options for tweaking parameters. Also includes a configurable watchdog that will automatically reset your computer if it is not responding.

So, if you are looking for a fanless eco-friendly and reliable Atom board for a home server, this one worths every penny. I am sure that you will love the IPMI KVM and the virtual disk/cdrom features. Here you have a short PPT slide show from Supermicro about IPMI.

War Games

I have discovered a funny and didactic online game where you can test and improve your hacking skills. The objective of the game is to hack a Linux server and scale user privileges.  You start with user level1 and you must exploit several bugs on the system to get access to the highest levelX that you can achieve.

There are various game servers each one with different bugs that you can exploit to level up. When you get access to a level you can leave your firm on the server.

For example you can try the game blowfish that I love (currently I am stuck at level5 )

Telnet to blowfish.smashthestack.org port 6666 to recieve an encrypted passwd.
#decrypt it and log in to level2 (If you are too lazy to decrypt it google can help you)
ssh level2@blowfish.smashthestack.org -p 2222
#follow the hints and try to get access to level13

Your mission is not to get root (but if you do you would win the medal of honor 😉