Thursday, April 14, 2011

Gotcha of the Day: Uploading .htaccess files over Webdav

I've found that webdav can be a really handy way to publish file to a server. With a modern version of Apache I usually find that webdav is just waiting for me to turn it on. That means I can enable publishing just by tweaking my Apache config, and not having to bother with setting up an FTP server (with the firewall rule and unix accounts backing it up).

It all Just Works. That is, with one itty bitty exception: by default attempts to upload a .htaccess file fail with a 403 error code. Inside the Apache log, I find:

[Thu Apr 14 06:06:00 2011] [error] [client xx.xx.xx.xx] client denied by server configuration: /var/www/vhosts/yyyyyyy/.htaccess

This is actually quite explainable, as there's the following standard configuration in /etc/httpd/conf/httpd.conf:

#
# The following lines prevent .htaccess and .htpasswd files from being 
# viewed by Web clients. 
#
<Files ~ "^\.ht">
    Order allow,deny
    Deny from all
</Files>

I knew I didn't want to simply yank out these lines, as that would leave a gaping security whole. Instead, after much poking and prodding I came up with the following recipe:

<VirtualHost xxxx>
  ServerName xxxxxxxxxxxx
  DocumentRoot /var/www/vhosts/yyyyyyyy

  ...

  <Location />
      DAV on
      AuthType Basic
      AuthName "Private"
      AuthUserFile zzzzzzzzzz
      <LimitExcept POST GET>
          Require valid-user
     </LimitExcept>
  </Location>

  <Files ~ "^\.ht">
    Require valid-user
    Satisfy any
  </Files>

</VirtualHost>

For the most part, the above is the standard virtual host setup for using webdav. For GET and POST requests you allow any user to access the URL, and for other types of requests (which include webdav requests), you require a user.

The funky part happens within the Files block. The Require statement is fairly obvious - it insists that any user who wishes to access a .htaccess file must be logged in (which is a requirement for using webdav). The Satisfy directive took a little longer to figure out. Without it, the original rule in httpd.conf was still taking effect, which always denied access. With that Satisfy directive, I'm saying that you can *either* be a logged in user, or be denied.

Slowly but surely, I'm understanding Apache's configuration rules enough that I can actually use them to my benefit. And I suppose that's another bonus you get for using webdav - you have one powerful set of configuration rules to control access for both web viewers as well as publishers, versus needing two different systems (say, Apache for web viewing and an FTP server for publishing).

1 comment: