Secure iDisk with WebDAV+SSL+PAM on Debian/Apache2

I’ve been putting together a new file server for personal use that I plan on hosting on my DSL at home (7mbit/896kbit). I have Gig-E inside my condo and just shy of 1mbit from outside my condo over a static IP address. More than enough bandwidth to serve my personal email, my website along with a few friends’ sites and email. The next question, of course, is what to do with the hundreds of gigabytes laying vacant on the server.

Being that I run OS X 10.4 and so do my other friends the obvious solution was WebDAV over SSL. I wanted to be able to mount my $HOME/public_html over SSL using PAM for authentication. Surprisingly, this actually works with a few hacks.

Warning

The rest of this article includes a few hacks that mess with permissions in a way that some people will scoff at. I understand this fully and am using this little space to warn you ahead of time that doing this will give Apache access to your /etc/shadow file.

List of Ingredients

  1. An installation of Debian GNU/Linux running Apache2 (specifically apache2, apache2-common, apache2-utils, and libapache2-mod-auth-pam)
  2. Everyone’s favorite scheduler, cron
  3. A text editor

Enabling/Disabling the appropriate Apache2 modules

Using the script a2enmod you’ll want to enable auth_pam, dav_fs, dav and ssl. These are the basic modules required to get this setup going. You might also be interested in installing the php5 module, etc. I won’t be covering that in this section. You will actually want to disable the userdir module. I did this mainly to disable WebDAV from working under the non-SSL Apache2 instances. I now include these files directly from my SSL <VirtualHost> configuration.

Setting up the SSL <VirtualHost> in /etc/apache2/sites-available/default


NameVirtualHost *:443
<VirtualHost *:443>
    SSLEngine On
    SSLCertificateFile /etc/apache2/ssl/apache.pem
    DocumentRoot /var/www/
    Include /etc/apache2/mods-available/userdir.load
    Include /etc/apache2/mods-available/userdir.conf
</VirtualHost>

Setting up the WebDAV in /etc/apache2/mods-available/userdir.conf


<IfModule mod_userdir.c>
    UserDir public_html
    UserDir disabled root

    # Make sure to chown www-data:www-data this file
    DAVLockDB /var/lib/apache2/DAVLockDB
    <Directory /home/*/public_html>
        AllowOverride FileInfo AuthConfig Limit
        Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
        DAV On

        AuthPAM_Enabled On
        AuthPAM_FallThrough Off

        # This is so when you edit files over DAV they
        # aren't ran through pre-processors (ie. PHP)
        ForceType text/plain
    </Directory>
</IfModule>

Allow www-data to view /etc/shadow

By default only root and those in the group shadow can view /etc/shadow. Add the user www-data to the group shadow. Now is probably a good time to restart apache using /etc/init.d/apache2 force-reload if you haven’t already.

Setting up the $HOME/public_html

In your $HOME you’re going to want to create public_html and chown $USER:www-data public_html along with chmod 775 public_html. This allows both $USER and www-data to modify the contents of public_html.

Editing $HOME/public_html/.htaccess

After this cd into public_html and open up .htaccess and add the following lines to it (replace $USER with whomever’s $HOME you’re putting this in).


AuthPAM_Enabled on
AuthType Basic
AuthName "PAM"

# If the user you're creating this for is /home/jstump then
# replace $USER with jstump
require user $USER

This is pretty key as it allows you to keep authentication for your WebDAV and SSH tied together. It also specifies which user can log into this particular WebDAV share. If you don’t put require user $USER in there then anyone can log into anyone else’s share. That’s not good.

Fixing permissions

The problem with this setup as of now is that if you create a file from the mounted WebDAV folder in OS X it’s created as www-data and vice versus if you’re logged in via SSH.

Warning

The following is an ugly hack, but it works. It should be used with caution and not trusted on production servers you truly care about.


#!/bin/sh

# Loop through all users and chmod/chown files and directories in $HOME/public_html
# I'm sure there is a better way of doing this.
for i in `ls /home`
do
    find /home/$i/public_html -type d -print -exec chown $i:www-data {} ;
    find /home/$i/public_html -type d -print -exec chmod 775 {} ;
    find /home/$i/public_html -type f -print -exec chown $i:www-data {} ;
    find /home/$i/public_html -type f -print -exec chmod 664 {} ;

    # I did this to keep users from editing their .htaccess
    chown root:root /home/$i/public_html/.htaccess
    chmod 644 /home/$i/public_html/.htaccess
done

Set this up to run in root‘s cron every minute. This will fix permission problems so that, after sixty or so seconds, you can edit files via SSH or your WebDAV mount.

Connecting to your WebDAV share from OS X

  1. Open a Finder window
  2. Hit CMD+K
  3. Type in https://my.server.com/~username for the location
  4. Click “Connect”
  5. Click “Continue” when it asks about the boned SSL certificate (install a valid SSL certificate to avoid this annoyance)
  6. Enter your username/password when prompted

Known Issues/Problems

  1. Apache can read/write to all files in $HOME/public_html
  2. Apache can read /etc/shadow
  3. Requires a cron job to fix permissions
  4. You lose the ability to have publicly accessible http://www.mysite.com/~username URLs

Conclusion

I’ve added $HOME/www/www.joestump.net along with my other sites and can now edit them through Finder or Term from my Macs at work and home. It’s all done over SSL and authentication is done via PAM, which means it’s fairly secure and easy to use. Personally, the few sacrifices are worth it to me to have this kind of setup. It also allows me to, say, save media files from work to home and vice versus in a pinch. I could also use various backup software, such as rsync, to sync and back up my various applications and data from computer to computer. Overall, I’m pleased with the outcome.