Debian Administration
System Administration Tips and Resources
WebDAV on Apache2
Posted by simonw on Fri 4 Nov 2005 at 12:11
Setting up WebDAV (Web based Distributed Authoring and Versioning) was covered briefly previously in an article on SVN. But this didn't stop a plea from a member of DCGLUG for an idiots guide.
WebDAV is a way of making parts of your webserver writable to certain clients. There are obvious reasons why you might want to do this, such as making it easy to update a website, and less obvious reasons, such as sharing Calendar data, or sychronising your bookmarks in Firefox, or to supply a small amount of password protected web space for people to share documents.
Whilst it is called "Authoring and Versioning" it seems the versioning is still arriving in the Apache2 mod-dav. The "Authoring" in this context replaces FTP, and effectively adds some basic file system type behaviour, such as locking. The main reasons to use it are; firewall evasion (port 80 is nearly always open), avoiding the complexities of FTP, or because it makes sense over other solutions for some purpose. As such it is an enabling technology, WebDAV doesn't of itself do much that is new or exciting, but it will. One strong point is the easy integration with Apache 2, which means you can use other Apache directives to set up neat solutions, such as editing scripts on a website.
The example will create a WebDAV enabled directory, on the "www.example.com" website, referenced by "http://www.example.com/webdav/". The example was worked through on Debian Sid, but works "as is" under Debian Sarge.
First make sure Apache 2 is installed and the optional DAV related modules enabled;
apt-get install apache2 a2enmod dav_fs a2enmod dav
If a2enmod or a2ensite are new to you, read Chris's introduction.
Then you need to rustle up a virtual host if you don't already have one, I created a vanilla virtual host by copying "/etc/apache2/sites-available/default" and editting it down till it reads as follows;
cat /etc/apache2/sites-available/example.com
<VirtualHost *>
ServerAdmin webmaster@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /home/srw/example.com
<Directory /home/srw/example.com>
Options Indexes MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
</VirtualHost>
Then remember to create the directory, and give ownership to the Apache user. Note editting sites outside of WebDAV may alter file ownership and thus break access via WebDAV.
mkdir /home/srw/example.com chown www-data /home/srw/example.com a2ensite example.com apache2ctl configtest /etc/init.d/apache2 reload
And a quick check using a browser or wget showed my empty directory index at "http://www.example.com/".
Now we need to set up an authentication scheme, because we don't want just anyone editting our website. I will use "Digest Authentication", which may muddle some old clients but ensure passwords aren't sent in plain text across the network, the alternative "Basic Authentication" is explained in detail in the Apache documentation.
Enable the module, and create a password file.
a2enmod auth_digest htdigest -c /home/srw/digest-password webdav-example myuser
After the "htdigest" you'; be prompted to enter myuser's password.
Now we add the "WebDAV" section to the virtual host.
cat /etc/apache2/sites-available/example.com
<VirtualHost *>
ServerAdmin webmaster@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /home/srw/example.com
<Directory /home/srw/example.com>
Options Indexes MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
# Note Alias goes to our DocumentRoot.
Alias /webdav /home/srw/example.com
# But we apply different settings
<Location /webdav>
DAV On
AuthType Digest
AuthName "webdav-example"
AuthDigestFile /home/srw/digest-password
Require valid-user
</Location>
</VirtualHost>
apache2ctl configtest
(NB: apache2ctl is quite capable of accepting very broken authentication settings, such as if you have "AuthUserFile" instead of "AuthDigestFile". It is also quite capable of ignoring errors in other extensions to the core of Apache, like mod-perl, but that is for another article).
/etc/init.d/apache2 reload
Now in principal we can edit "example.com" using WebDAV, but do we have a client? Debian has "cadaver" which is a simple(?) command line WebDAV client, which is very handy for testing things.
apt-get install cadaver cadaver http://www.example.com/webdav/
Once in you can use a selection of fairly normal shell commands, and even "tab completion" of file names, whilst "edit filename" will invoke your editor of choice.
We could have made a simpler configuration, by using a "<Directory>" instead of a "<Location>" directive, without the Alias, and created a simple filestore for one or more users.
I'm still uncovering the mysteries of cadaver and WebDAV, and have yet to deploy it in anger, although I use it to sync my bookmarks, and we are experimenting at work.
Other patterns of configuration can be applied, as you can use "<Limit>" to only allow certain WebDAV operations against a directory, this means you don't always need two ways to refer to the same directory. Although this is needed if in one view the files are handled differently, such as scripts which are usually executed, then you have to override that handler in the WebDAV view.
I also found that the Indexes (such as index.html) may have a default lock against them. Try something like this if it happens to you;
cadaver http://www.example.com/webdav/ Authentication required for webdav-example on server `www.example.com': Username: myuser Password: dav:/webdav/> edit index.html Locking `index.html': failed: 423 Locked dav:/webdav/> discover index.html Discovering locks on `index.html': Lock token <opaquelocktoken:28cfc4e4-9c04-0410-bed0-c546ac2f7a25>: Depth 0 on `http://www.example.com/webdav/index.html' Scope: exclusive Type: write Timeout: infinite Owner: (none) dav:/webdav/> unlock index.html Unlocking `index.html':Enter locktoken: opaquelocktoken:28cfc4e4-9c04-0410-bed0-c546ac2f7a25 succeeded. dav:/webdav/> edit html
The desirable client, at least for those who find FTP challenging, is a filesystem client. But as you'll see from my question earlier, getting some of these clients to work nicely can be more challenging than perhaps is immediately desirable. Although there are fairly simple workarounds for most of these issues. More on the Debian WebDAV clients when I get more time to play.
[ Parent | Reply to this comment ]
The mod_dav FAQ at http://www.webdav.org/mod_dav/faq/#03-01 suggests using something like a CGI with suexec, but unfortunately doesn't give any pointers to anything which can do such a thing or any more info on such. :)
[ Parent | Reply to this comment ]
The Plone site has some interesting comments on clients, but I suspect, scratch that - I know, Plone itself is overkill for what you are trying to do.
http://plone.org/documentation/how-to/webdav
Isn't Plone overkill for everything ;-)
A friend commented that the Novell WebDAV client for Windows, mentioned on the Plone site, has moved, but that he has the original download file. Somehow I doubt he has rights to redistribute it though, I mean it isn't Debian.
[ Parent | Reply to this comment ]
> A friend commented that the Novell WebDAV client for Windows, mentioned on the > Plone site, has moved, but that he has the original download file.Haven't tested it, but on the plone page you mentioned, there's an alternative link to the Novell WebDAV client: --> http://d321.k12.id.us/Support/Docs/NOVELL/NetDrive4.1/ndint.exe
[ Parent | Reply to this comment ]
Apache SuExec is only for CGI. Everything else runs as a single user.
It's a *nix problem really. Any solution requires that you run Apache as root. Apparently there was a version of apache which would fork children running as different users (so main server has to run as root) but it was abandoned.
I have thought of a workaround. It is quite straightforward to write an AuthN/AuthZ pair (you can find examples in perl on the net). The AuthN module
can call a hook that you write. In that script make a system call using 'sudo'
to chown your webdav-accessible files to the apache user. You need to add a logout script somewhere (a CGI with a button on a web page) which runs another
'sudo' call to chown everything back to you. Set up 'sudoers' to allow these
scripts to be run by the webuser without a password.
Ugly but ...
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
DAV On
Order Deny,Allow
Deny from all
Allow from 127.0.0.1
Allow from 10.1.1.0/24
Allow from 10.1.1.42
I am restricting by IP, but in a similar way, you can restrict things by user name or something else. You are off the edge of the map, mate. Here there be monsters!
[ Parent | Reply to this comment ]
You are off the edge of the map, mate. Here there be monsters!
[ Parent | Reply to this comment ]
Although note that it is a pig when posting articles to get this right inside "pre" tags as preview seems to handle it different to post, as it got muddled, Steve is working on that. Kupu anyone?!
[ Parent | Reply to this comment ]
That damned Grue. It is very dark here.
You are off the edge of the map, mate. Here there be monsters!
[ Parent | Reply to this comment ]
Sadly the code is ... intricate ... so currently you have to escape them to preview, then re-escape them to confirm.
I will have it fixed shortly I hope. The problem here is coming from the way that the HTML::Scrubber module normalises input text on each step - and I use that to sanitize potentially hostile code as input by users.
Steve
--
[ Parent | Reply to this comment ]
The most common cases of using markup in plain-text comments should now be working correctly - although this is just a quick hack.
Times like this I think I should just use plain text always, or maybe bbcode!
Steve
--
[ Parent | Reply to this comment ]
In the meantime, I have something which definitely does not scale well, as you need to edit apache.conf for every user; if you use Apache's "Include" directive, with something like "Include conf/davusers/*.dvu" then you can make it a little more scalable. The layout I use lets me have a WebDAV area where all users with WebDAV accounts can read anything, but writing is limited to the owner of each sub-area.
Instead of using Apache directives to limit writing outside the sub-areas, I limit the ability of an Apache security bug to let someone move things around; the top-level webdav area is owned by root:web-runtime-group mode 0750 and each sub-area is owned web-runtime-user:web-runtime-group mode 0750. I should probably put in some restrictions at the top level too, so that clients have their attempts to write be rejected, instead of failing.
<ifmodule mod_dav.c>
<directory /path/to/webdav/>
allow from 127.0.0.1 ::1
allow from 192.0.2.1
# other allowed clients
Dav on
AuthType Basic
AuthName "MySystemName WebDAV Storage"
AuthUserFile /path/to/web/etc/passwd.dav
Require valid-user
# These are the HTTP methods used in DAV, beyond the usual GET/HEAD/OPTIONS
# <limit put post delete propfind proppatch mkcol copy move lock unlock>
# </limit>
</directory>
<directory /path/to/webdav/fred/>
<limitexcept get options propfind>
Require user fred
</limitexcept>
</directory>
<directory /path/to/webdav/barney/>
<limitexcept get options propfind>
Require user barney
</limitexcept>
</directory>
<directory /path/to/webdav/wilma/>
<limitexcept get options propfind>
Require user wilma
</limitexcept>
</directory>
</ifmodule>
Note that there are even more methods once you get into fancier stuff; my comments in my subversion area say something about REPORT, for instance.
Hope this provides some useful ideas to people.
[ Parent | Reply to this comment ]
The "Require valid-user" isn't being inherited by the sub-directories. :-(
Suggestions for a fix welcome.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
As I was following these instructions I found them very user-friendly and I think I know now much more about WebDAV then some hours ago, but unlikely I got an error I can't fix. So here's my listing:
root@aither:/etc/apache2/sites-available# cadaver http://www.example.com/webdav/ Could not access /webdav/ (not WebDAV-enabled?): 405 Method Not Allowed Connection to `www.example.com' closed. dav:!>
I'm sure I got everything to work until this point like this idiots guide said. Perhaps someone has any comments/suggestions/solves to my problem?
Thanks.
Martl
[ Parent | Reply to this comment ]
Failure to restart Apache?
Probably best asked of your local {G}LUG.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
/var/lock/apache2# cadaver http://192.168.0.2/calendar/
Could not access /calendar/ (not WebDAV-enabled?):
405 Method Not Allowed
Connection to `192.168.0.2' closed.
dav:!>
Here is my virtual host:
ServerAdmin webmaster@servebeer.com
ServerName dnsName/calendar
ServerAlias 192.168.0.2/calendar
DocumentRoot /var/www/calendar
Options Indexes MultiViews
AllowOverride All
Order allow,deny
allow from all
# Note Alias goes to our DocumentRoot.
Alias /calendar /var/www/calendar
# But we apply different settings
DAV On
AuthType Digest
AuthName "webdav-example"
AuthDigestFile /var/www/digest-password
Require valid-user
[ Parent | Reply to this comment ]
# But we apply different settings
DAV On
AuthType Digest
AuthName "webdav-example"
AuthDigestFile /home/srw/digest-password
Require valid-user
we can not user capital "DAV On" we have to use small "dav on".
Thanking you .
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]