I'm running an experimental just-for-fun Apache web server. Part of the idea behind this server is that it should be unusually open to the public; for example, the root filesystem should be open for anyone to browse. (Indeed, here it is: http://sylvester.s.zbasu.net/rootfs/) As a consequence, security is going to take a back seat.

That said, there are things which Apache should be able to access, but the public should not. The example which I'm running into is a Django site. The file settings.py must be readable by Apache, or else Django won't work. But settings.py must not be readable by the public, since it contains a secret key. So the file should be owned by www-data, but Apache should nevertheless refuse to serve it.

One possible solution (thanks to ellipsis753 on Freenode) is to create a special directive, perhaps in an .htaccess file, telling Apache not to serve this file. However, I figure that if a file isn't readable by all users, it probably shouldn't be served by Apache, either.

Can I tell Apache that if a file isn't world-readable, then it shouldn't be served?


If you run your Django application under FastCGI or in mod_wsgi's Daemon mode, then you can run it as a different user than the one Apache is running under. Then, you can completely remove Apache's and World's permission to read any file that you do not want to serve.

For example, note that your password file /etc/shadow is already not accessible because Apache does not have permissions on it and it is not world-readable. If you create a new user, say web-apps for example, and add WSGIDaemonProcess myapp user=web-apps ... to the Apache configuration, then you can have the Django application be owned by the web-apps user, with its configuration file not world-readable, like the shadow file already is.

  • Yup, that works. Of course, I needed to add a WSGIProcessGroup directive as well. For some reason, I also had to edit my wsgi.py to append the project directory to sys.path, as described in this StackOverflow answer: stackoverflow.com/a/4750766/1108505 I don't know why this was necessary when using WSGIDaemonProcess but not necessary otherwise. Mar 4 '14 at 3:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.