Serving public_html as an iDisk

If you have your own Linux web server running Apache, and if you use Mac OS X as your desktop environment, you can serve up your userdir directory with WebDAV so that you can mount it with your Finder as you would an iDisk. The following Apache 2.x configuration enables this. This is not a solution for everyone, it has a number of limitations, but if you just want to use some of your under-utilized network and disk resources this is a simple way to grab a piece of the cloud.

# On Debian this would go in /etc/apache2/ports.conf
Listen 443
 
#
# This can appear only once in your config files, prior to
# the first SSL virtual host.
#
NameVirtualHost *:443
 
<VirtualHost *:443>
    ServerName idisk.example.com
 
    #
    # Encrypted access only.  We generate the self-signed
    # certificate and key in idisk.pem below.
    #
    SSLEngine On
    SSLCertificateFile /etc/apache2/ssl/idisk.pem
    SSLCertificateKeyFile /etc/apache2/ssl/idisk.pem
 
    #
    # Reject any URL request whose path is not a user dir (PCRE syntax),
    # feeding the browser a web page rather than the file system.
    #
    RedirectMatch permanent ^/(?!~.+)  http://www.example.com
 
    #
    # Shown for completeness, these should be set already,
    # e.g., in userdir.conf on Debian systems.
    #
    UserDir public_html
    UserDir disabled root
 
    <Directory "/home/*/public_html">
        DAV On
        DAVLockDB /var/lock/apache2/DAVLock 
 
        #
        # WebDAV adds to GET, POST and OPTIONS the following request types:
        # COPY, MOVE, LOCK, UNLOCK, DELETE, PROPFIND, PROPPATCH, 
        # and MKCOL.
        #
        <LimitExcept CONNECT PATCH>
            Order Allow,Deny
            Allow from all
        </LimitExcept>
 
        #
        # The Mac OS X Finder uses WebDAVFS 1.3 (10.4), 1.7 (10.5) and 1.8 (10.6).
        # Without this you will have errors, with the log message complaining about
        # a uri mismatch between /directory/path and request-uri /directory/path/.
        #
        BrowserMatch "^WebDAVFS/1.*" redirect-carefully
 
        #
        # We don't want Apache pre-processing server-side scripts such as PHP
        # or Perl files, so treat everything as static content.
        #
        SetHandler default-handler
 
        #
        # Require membership in the idisk group, but leave the group empty.
        # This leaves WebDAV access off until the user overrides the group
        # definitions in their .htaccess file.
        #
        AuthName "iDisk Access"
        AuthType Digest
        AuthUserFile /usr/local/apache/digest.users
        AuthGroupFile /dev/null
 
        <LimitExcept GET POST OPTIONS>
            Require group idisk
        </LimitExcept>
 
        #
        # Make sure the user can modify the above authorization settings
        # in their .htaccess file.
        #
        AllowOverride AuthConfig
 
    </Directory>
 
    # Log WebDAV access separately (optional).
    ErrorLog /var/log/apache2/idisk-error.log
    CustomLog /var/log/apache2/idisk.log
 
</VirtualHost>

The user can then control access to their ~/public_html space by defining their own "idisk" group (membership in which is required by the server configuration above):

joe$ echo "idisk: joe" > ~/idisk.group

and overriding the system definition of the group file for the "iDisk Access" realm in their ~/public_html/.htaccess file:

AuthName "iDisk Access"
AuthDigestDomain /
AuthGroupFile /home/joe/idisk.group

Or more likely than not, you will do that for your users, giving each account an idisk.group file that includes only the account owner in the group. You can create and populate the user digest file /usr/local/apache/digest.users with htdigest:

root# htdigest -c /usr/local/apache/digest.users "iDisk Access" joe

adding subsequent entries by omitting the -c flag. Note that the realm argument to htdigest, "iDisk Access", must match exactly the AuthName specified in the configuration file (and the per-user .htaccess file). Make sure the Apache process has read access to the system-wide user digest, /usr/local/apache/digest.users, and the per-user "idisk" group definitions, ~/idisk.group.

Notice that the .htaccess settings above do not restrict regular web-browser access to the contents of ~/public_html through the URL http://www.example.com/~joe. The Require group idisk constraint applies only to access through the URL http://idisk.example.com/~joe.

The above example assumes you have an SSL certificate and key installed in /etc/apache2/ssl/idisk.pem. You can create your own self-signed certificate:

root# openssl req -new -x509 -days 365 -nodes -out idisk.pem -keyout idisk.pem
root# chmod 0600 idisk.pem
root# mv idisk.pem /etc/apache2/ssl

Make sure it cannot be read by just anyone. Either that or require that a key be provided to read the certificate, but be aware that Apache will not be able to restart unattended. Note that client browsers (i.e., the FInder) will/should complain about the security of your certificate, but presumably you are only using this yourself to access your own files. You can tell Mac OS X to trust the certificate the first time you connect with your Finder. Note also that the key generated above will expire in 365 days, so you will have to repeat the exercise in a year.

In addition to installing an SSL certificate you must activate the following Apache modules (i.e., using a2enmod on Debian systems):

  • userdir
  • ssl
  • auth_digest
  • dav
  • davfs

The Debian configuration file for the dav_fs module, dav_fs.conf, already includes the DAVLockDB /var/lock/apache2/DAVLock setting shown in the configuration file example above. And while the Debian setenvif.conf file contains the line, "^WebDAVFS/1.[012]" redirect-carefully, but this is insufficient for new Mac OS X FInders.

Finally, the Apache process requires read/write access to ~/public_html directories. The simplest thing to do, assuming ~/public_html starts out empty, is just change the group on ~/public_html to that of the Apache process, in this example apache:

root# chown :apache ~joe/public_html
root# chmod g+w ~joe/public_html

The user can add content to ~/public_html from their Linux account as the directory owner, specifically an .htaccess file. Apache can add content as a member of the apache group. Unfortunately, problems arise when adding new subdirectories (see the discussion below). But once the .htaccess file is in place the user has little need to add content to that directory other than via WebDAV.

Having all the modules enabled and the configuration settings in place, remember to restart the Apache daemon.

What's Wrong WIth This?

You cannot use SSL with name-based virtual hosts, not really. See the Apache FAQ for the explanation. Unless your host name idisk.example.com is the only name by which you access your host using SSL, and unless your SSL certificate is generated for that host name, and unless you purchased your certificate from a recognized signing authority, you will always get complaints about how trustworthy your connection to your server is from the Mac OS X Finder. That said, my whole premise in this discussion is that this is something you are doing for yourself, or you and a handful of your closest friends, granting access to your own server to your own Mac OS X desktop. Tell Mac OS X to trust the key and move on.

Keeping permissions straight in ~/public_html can be problematic if users are able to log into their Linux account and change things in their ~/public_html directory while simultaneously manipulating its contents via WebDAV. The contents of ~/public_html can be deleted by either the user, because they own the directory, or the apache process, because the directory is group-writeable. But unless you set the SGID sticky bit on ~/public_html and the umask for both the user and the Apache process is 002, files in subdirectories added to ~/public_html can only be deleted by the process that owns them. Unfortunately you cannot set the umask for a directory, only for an account. But once the .htaccess file is in place you may never want to change the contents of ~/public_html by any means except via WebDAV clients.

If you intend to support more than a handful of users you may prefer to use a different authentication scheme from the flat-file digest. Parsing the full file repeatedly can slow down your Apache server if you have a large number of users. You may want to implement some mechanism by which the users can change their account passwords themselves, too.

That said, if you are already paying for Internet service for a fixed-IP server, and you don't want to shell out extra bucks for a .Mac account just to have a simple networked file repository, the above approach is a simple way to give an iDisk-like file store for yourself and a few of your closest friends.