A Day in the Life of #Apache
Securely Edit Your Website Content in WebDAV
by Rich Bowen, coauthor of
Apache Cookbook
03/24/2005
Editor's note: Rich Bowen is back with another installment of his #apache column, where he provides solutions to problems Apache users regularly encounter. If you want to bend his ear with a problem you have, you can almost always find him haunting the IRC channel #apache, under the handle "DrBacchus." Rich is also a coauthor of O'Reilly's Apache Cookbook.
Day Eleven
#apache is an IRC channel that runs on the irc.freenode.net
IRC network. To join this channel, you need to install an IRC client (XChat,
mIRC, and bitchx are several popular clients, although there are roughly 3
bazillion other ones, too) and enter the following commands:
/server
irc.freenode.net
/join #apache
A couple of years ago, I became very fond of WebDAV. I replaced all of my FTP
servers with DAV. I began managing the content on all of my websites via DAV. I
even replaced most of my network file systems with DAV.
Please note that this is not a tutorial on setting up DAV, using DAV, or even
telling you what DAV is. For that, you should probably start here.
Today I'll be talking about a small problem that you might have managing your
website with DAV, and what I do to get around it.
Once upon a time, on #apache ...
<Yogi> Should I make all the files on my web server owned by
the nobody user?
<DrBacchus> No, you generally don't
want to have any files owned by the user that Apache is running as. That tends
to be a security problem.
That is, the user that you set in the User directive, is usually
nobody or www-data. If that user owns content, then
any simple CGI exploit or carelessly written PHP script would permit random
hoodlums to modify content on your website. Clearly a bad thing.
Then, later on ...
<Booboo> When I attempt to edit content on my DAV-enabled
server, I keep getting a 403 Forbidden when I try to save the
file.
<DrBacchus> All of the content needs to be owned by the Apache
user, so that DAV can modify that content.
Unfortunately, Yogi, who is smarter than the average bear, is still paying
attention, and chimes in here.
<Yogi> Wait a second. You just told me that you shouldn't
have web content owned by the Apache user. What's up with
that?
<DrBacchus> Um ...
You see, here's the problem. DAV runs within the Apache framework, giving you
a way to edit content stored on that server. Since Apache runs as whatever
user you set in the User directive, those files need to be owned by
that user in order for DAV to edit them.
But, the fun doesn't stop there.
If you're using DAV to edit dynamic content--like, say, PHP files--then
you'll notice that you're not getting the raw PHP file, but you're getting the
post-processed stuff. That is, instead of seeing the PHP code, you're seeing the
executed results of the PHP code.
That's not particularly useful.
So, all in all, DAV appears to be moderately worthless for editing real
websites, right? Well, not quite. I have a proposal that solves both problems,
as well as, possibly, others I haven't thought of yet.
<Yogi> So, how do you resolve that little
contradiction?
<DrBacchus> Well, what *I* do is to run different
Apache daemons on different ports, one with DAV, and one without.
Yes, that's what I do, in the real world. This solves the permissions
problem, and it solves the problem of needing to edit PHP files, SSI files, and
other dynamic files.
Your main web server, for example, might be configured like this:
User apache
Group apache
Listen 80
DocumentRoot /usr/local/apache/htdocs
While the second server would be something like:
User dav
Group dav
Listen 90
DocumentRoot /usr/local/apache/htdocs
<Directory /usr/local/apache/htdocs>
Dav On
</Directory>
The second Apache server is built with a minimal number of modules.
Obviously, it needs mod_dav and mod_dav_fs. But it
doesn't need mod_php, mod_cgi, and a half-dozen other
modules that you may be using on your main web server.
<Yogi> What do you consider to be the minimal module load
for the DAV server?
<DrBacchus> Here's what mine looks like:
rbowen@buglet:/usr/local/apache2% ./bin/httpd -l
Compiled in modules:
core.c
mod_access.c
mod_auth_digest.c
mod_log_config.c
mod_env.c
worker.c
http_core.c
mod_mime.c
mod_autoindex.c
mod_dav.c
mod_dav_fs.c
mod_dir.c
mod_alias.c
mod_so.c
And all of the content on the server needs to be owned by the user
dav, and writeable by that user.
Additionally, since the number of people using DAV to edit your content is
(probably) much smaller than the number of people viewing the website, you can
have a much smaller number of active child processes. Or threads, if it's a
threaded MPM.
For a worker MPM, this might look like:
StartServers 1
MaxClients 10
MinSpareThreads 2
MaxSpareThreads 4
ThreadsPerChild 5
Or, for prefork:
StartServers 2
MaxClients 10
MinSpareServers 1
MaxSpareServers 5
These numbers are just suggestions, of course. There's nothing magical about
them. The goal is simply to keep this server extremely lightweight.
Finally, you want to make sure that access to the DAV-enabled server is
locked down as tightly as possible. Exactly what that means, of course,
varies from one installation to another. I recommend that you at least have access
password protected, using mod_auth_digest, or perhaps
mod_auth, if you prefer. If you're able to do so, you can also
restrict access to the server by IP address:
<Directory /usr/local/apache/htdocs>
order deny,allow
deny from all
allow from 192.168.2
</Directory>
And some DAV clients (not all of them) will also permit you to run SSL on the
DAV-enabled server. You'll need to experiment with your particular scenario to
find out if this will work for you.
Not all file permissions problems on Apache have such simple, and effective,
solutions. But this one is very effective, and very simple to set up. And it's
more secure than running DAV access as the same user that runs your CGI and PHP
code. Until we have the metux MPM, this is about as good as we can
do. (Note: If you haven't heard about the he metux MPM, it's a new MPM that will, if
and when it is completed, allow different Apache child processes to run as different User IDs.
This will allow for a better (more secure) implementation of virtual hosts, and
also will make the technique described in this article completely
unnecessary.)
See you on #apache.
Rich Bowen
is a member of the Apache Software Foundation, working primarily on the documentation for the Apache Web Server. DrBacchus, Rich's handle on IRC, can be found on the web at www.drbacchus.com/journal.
Return to the Apache DevCenter.