Do you work on a shared system where you are one of several people who needs to edit content in a shared directory? Or maybe you work on a Linux system where the static web content is in a shared directory owned by a system users (who's not you.) This latter case is the default for Apache or Lighttpd on Ubuntu. You may have encountered permissions problems when trying to edit files in these directories. This page describes a simple technique for changing permissions of a shared directories so a list of authorized users can edit its contents. As security boffins will tell you, this is preferred to making the directory "world writable" -- the last thing you need is a random internet troll defacing your web site.
Simply put, there's an easy, safer way to make a directory (and its sub-directories) writable by a subset of system users.
While you should have a system in place to store your content in a version control system and then deploy that content to a real server somewhere on the internet, sometimes the world doesn't work that way. For instance, I sometimes want to test the behaviour of a browser locally on my Linux laptop or in a Linux virtual machine. I don't want to check a file into version control after every minor change and wait for it to be deployed. In this case I want to edit files directly in the web server's static content directory hierarchy.
But the default configuration for Ubuntu and Debian is to not allow this.
The steps below describe how to fix this.
If you follow these steps, you won't have to
sudo
to root to edit a file. Any
tool you happen to use to create web-pages,
whether it's a WYSIWYG tool like FirstPage or a
text editor like Emacs, it should just work.
Unix, Linux, Darwin, BSD -- all modern Unixes -- only allow you to write a new file to a directory if:
It's generally considered a bad idea to let anyone write content to a particular directory, so we should probably forget about that last item.
And we're not really interested in the first case because we're explicitly talking about shared directories; directories where multiple people can read and write files.
That leaves us with item number two: group ownership of files.
Debian (and it's commercial derivative Ubuntu)
come pre-configured with a group called
www-data
. By default, new users
aren't added to this group. When you install a
web server like Apache or Lighttpd, you can
change the group owner of it's static content
directory to allow group writes. Then you just
add yourself to www-data group, and change the
group permissions on the shared directory and
viola! you can write to the shared directory!
This example assumes your static web content is
in the directory /var/www/html
,
which is where you find it on recent Ubuntu
systems.
$ sudo addgroup `whoami` www-data $ sudo chgrp -R www-data /var/www/html $ sudo find /var/www/html -type d -exec chmod 2775 {} \; $ sudo find /var/www/html -type f -exec chmod 0775 {} \;
Except it's not exactly that easy. Because of
the way group permissions work in Linux, you
have to log out and log back in. You could type
the command su - `whoami`
to test
that it works, but that will give you a
sub-shell that doesn't have the DISPLAY
environment variable set, which could be a
problem if you're using an X/Windows based
editor.
After relogging-in, you can test that it works with the following commands:
$ touch /var/www/html/foo $ ls -ld /var/www/html drwxrwsr-x 2 root www-data 4096 Mar 26 13:06 /var/www/html/ $ ls -l /var/www/html/foo -rw-rw-r-- 1 you www-data 0 Mar 26 13:06 /var/www/html/foo
If you don't see -rw-rw-r--
in
the last line of output above (specifically,
if you see -rw-r--r--
) make sure
you're not issuing the touch command as the
root user. Debian is supposed to default to a
0002 umask for normal users and 0022 for
root. But you may need to manually change the
file mode creation mask (umask) to 0002, like
this:
$ umask 022
The default umask used to be set in
~/.profile
or
/etc/profile
and was easy to
change. Unfortunately, there are a number of
different places where the default umask is
now set in Ubuntu, so your mileage may vary,
but the command above will always work when
issued from the command line.
Once you set this up, anyone in the
www-data
group will have
permission to read, write and delete files in
the shared directory, even if that directory
is owned by the root user.
The real magic here is when we recursively set
the SetGID bit on the shared directory and it's
sub-directories. This is what the sudo find
/var/www/html -type d -exec chmod 2775 {} \;
command did. The SetGID bit tells the system to
inherit the group owner of new files from the
group owner of the directory it's created in. By
setting the Write and SetGID bits, authorized
users can edit files in this directory and
permission to edit these files are automagically
given to other members of the www-data group.
But remember, it's probably bad practice to log into web servers and edit files on the fly. Sure, sometimes you may have to do this in an emergency, but your process should involve storing changes in a version control system, having team-mates review the changes, and then have the changes deployed to your production systems with a continuous deployment system. The process described here should work fine on a development machine, however.