4

My question concerns Apache and the different ways it can operate. For this particular machine I am the only user, and I will be using the box mainly to run WordPress on a LAMP Stack with Ubuntu 12.04.3 LTS. I have Apache installed and it is running as the www-data user. For the purposes of this example, lets call my user foo.

If I just set up a base configuration of WordPress, the system won't be able to write to the directories, for reasons I still don't quite understand, because www-data is the Apache user, and isn't foo, the owner of the files.

From what I understand, I don't want to make my files owned by www-data as this can be very dangerous and insecure. However, might it be a good idea to make my files group writable, or is that not the best option either?

If someone could shed a little light on the workings of Apache, that would mean a lot, as well as the best configuration to put my server in so that the files are writable by my user but can be accessed by applications such as WordPress.

  • This: "the system won't be able to write", is too vague. What user/process on the "system" are you talking about? – Totor Dec 21 '13 at 11:27
  • @Totor, when I say that the system won't be able to write, I mean that www-data can't write to the files because it doesn't own them. – Noel Forte Dec 21 '13 at 18:53
4

Noel, www-data user is the user, from whose behalf Apache runs your WordPress code (and any other code, generating Web pages for your users, e.g. Django code - python web-site engine).

www-data user is created to have minimal permissions possible, because it can possibly execute malicious code and take as much control over your system, as it is allowed to take. Suppose, that WordPress engine contains a vulnerability. Say, it allows the user to convert an image file from .jpg to .gif format by running convert from Imagemagick. The vulnerability is that it doesn't check that the filename contains the filename and only filename.

If a malevolent cracker supplies "image.png; ldd image.png", and WordPress executes convert image.png; ldd image.png in the shell without filtering out "; ldd image.png" part (this part was added to filename by the cracker in order to be exectued in the shell), your apache will run ldd image.png in addition to converting image. If image.png is in fact an executable file, named image.png, which the cracker supplied to you (if you allow other people to publish on your site, using WordPress engine), ldd image.png can result in arbitrary code execution, using 'ldd' vulnerability as described here: http://www.catonmat.net/blog/ldd-arbitrary-code-execution/.

Obviously, if that code is run as root user, it can infect all programs in your system and take total control of it. Then you're screwed (your virtual hosting can start sending spam, trying to infect everyone with viruses, eat up all your hosting budget etc.).

Thus, WordPress should be run with minimal privileges possible, in order to minimize damage from a potential vulnerability. Thus, any file, that www-data can write to, should be treated as possibly compromised.

Why don't you run WordPress as your foo user? Suppose, you've got a per-user installation of programs (e.g. in /home/foo/bin), and run WordPress as foo user. Then vulnerability in WordPress can infect those programs. If you later run one of those programs with sudo, you're screwed - it will take total control over the system. If you store any password or private key and foo user can read it, then cracker, who hacked your WordPress will be able to read it, too.


As for the overall mechanism of Apache functioning, here is a summary:

enter image description here

1) On your VPS computer there's a single Apache2 process, that runs as a root. It has to run as the root, cause it needs root privileges to ask Linux kernel to create a socket on TCP port 80.

Socket (see Berkley Sockets) is an Operating Systems Programming abstraction, used by modern Operating Systems (OS) kernels to represent network connections to applications. WordPress developers can think of a socket as of a file. When 2 programs, client and server, on 2 different computers speak to each other over the network, using TCP/IP protocol, OS kernels handle the TCP/IP details by themselves and the programs just think, that they have a file-like object - socket. When Client program (e.g. Mozilla) writes something to its socket, kernel of the client computer's OS delivers that data to the kernel of server computer's OS, using TCP/IP protocol. Then Server program (Apache2 on behalf of WordPress) can read those data from its socket.

How does client find the server and how server distinguishes between clients? Both server and client are identified by a pair (IP address, TCP port number). There are well-known ports for well-known protocols, such as 80 for http, 443 for https, 22 for ssh etc. Well-known ports are used by server computers to expect connections on them. IMPORTANTLY, only root user can create sockets on well-known ports. That's why the first instance of Apache2 is run as root.

When a server (Apache2) program wants to start listening to a port, it creates a so-called passive socket on port 80 with several system calls (socket(), bind(), listen() and accept()). System call is a request from a program to its OS kernel. To read about system calls, use e.g. man 2 socket (here 2 means the section 2 of man pages - system calls, see man man for section numbers). Passive socket can't really transfer data. The only thing it does is establish the connection with client - Mozilla's tab.

2) Client (Mozilla tab) wants to establish a TCP/IP connection to your server. It creates a socket on NON-WELL KNOWN port 14369, which doesn't need root privileges. Then it exchanges with 3 messages with Apache through the passive socket on your server computer's 80th port.This process (establishing the TCP/IP connection with 3 messages) is called 3-way handshake, see:

enter image description here

3) When TCP/IP connection is successfully established, Apache2 (run as root) invokes accept() system call and Linux kernel creates an active socket on server's 80th port, corresponding to connection with Mozilla's tab. Through this active socket will your WordPress application talk to the client.

4) Apache2 (run as root) forks another instance of Apache2 to run the WordPress code with lower privileges. That instance will run your WordPress code as a www-data user.

5) Mozilla and Apache2, running WordPress code as www-data user start exchanging http data over the established connection, writing and reading to their respective sockets via send()/recv() system calls.

Basically, WordPress is just a program, whose output is an html-page, so Apache2, running as a www-data just runs that program and writes its output (html-page) to the active socket and Mozilla on the client side receives that page and shows it.

  • thank you so much for this explanation! When you say that any directory that www-data can write to could potentially be compromised, is there a way around this? Some directories need to be server writable, such as themes and uploads. Would it make sense to make these group writable? You also mention that it might be better to run WordPress as the foo user, making all WordPress files owned by foo, but then apache won't be able to write, since permissions would be set at 755. – Noel Forte Dec 21 '13 at 19:02
  • @NoelForte Excuse me, I can't understand the idea about group writability. You can configure apache to run under users, other than www-data with User instruction (or other instruction, specific for mod you're using, e.g. for mod-wsgi there's a special WSGIProcessGroup instruction, allowing to set user). You decided to create a separate user foo, dedicated to running WordPress and nothing else, so that if you run multiple engines on your machine, WordPress is under foo and others are under e.g. www-data? Ok. You can store all the WordPress content in a folder, owned by foo. – Boris Burkov Dec 21 '13 at 20:36
  • @NoelForte Also, see unix.stackexchange.com/questions/30879/… – Boris Burkov Dec 21 '13 at 20:36
  • @NoelForte Example: I run a python wiki engine under a separate user wiki, who owns /home/wiki folder. All the content, generated by my wiki users, is stored in subdirectories of /home/wiki, which is 755. The engine itself is stored in /usr/share/pyshared. If the engine is compromised (and it was once, right at "happy new year-2013" :)), the cracker would get full control of /home/wiki, will know the passwords of users of wiki, stored there, would be able to edit all wiki pages, but won't be able to touch anything in the system itself. I lose wiki, but don't lose the system. – Boris Burkov Dec 21 '13 at 20:44
  • My ldd on Debian Wheezy will not execute the program if it is not recognized by ld-linux.so.2, the function used then is: nonelf(){return 1;}. Also, the main apache process does not need to bu run as root, it just needs the CAP_NET_ADMIN capability. I even wonder if it can drop that privilege once the listening socket has been set up. – Totor Dec 22 '13 at 1:55
1

The webserver is just like a normal user (here, the www-data user):

  • If you give it ownership on some directories/files, it can do almost whatever it wants with it,
  • If you give it write permissions on directories/files that it does not possess, it can modify them, empty them, etc.

If you want a more "secure" setup, in case your webserver (or php, or wordpress) is attacked, you must identify what parts of your web tree are to be read-only, and ensure the webserver does not own them, nor can write to them.

To know that, you should read this wordpress documentation : http://codex.wordpress.org/Changing_File_Permissions

You can also have a look at this answer.

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.