A better approach is to give each user a dedicated web server, still running on the same machine.

Now each server can run under its owners' permissions, thus protecting users from each other. Unfortunately, this doesn't address the other considerations raised in the previous setup approach. In Chapter 14 we discussed various techniques of limiting resource usage, but users will be able to override those limitations from within their code and you will have to trust your users not to do that.

Also, this scenario introduces a new problem. If an ISP uses named virtual hosts (all using the same IP address), what differs between users is the port to which their servers listen. The main frontend server will dispatch the requests to the various users' backend servers based on the port given to each user. If users are allowed to modify their parts of the server's httpd.conf file, it's possible that user A could adjust the server configuration to listen to the same port that user B's server is supposed to be listening to. User A's Apache server cannot bind to the same port while user B's server is running, but if the machine is rebooted at some point, it's possible that user A could take over the port allocated to user B. Now all the traffic that was supposed to go to user B will go to user A's server instead. User B's server will fail to start at all. Of course, ugly things like this will quickly be discovered, but not before some damage has been done.

If you have chosen this server-sharing technique, you must provide your clients with:

  • Shutdown and startup scripts installed together with the rest of your daemon startup scripts (e.g., /etc/rc.d directory), so that when you reboot your machine the users' servers will be properly shut down and restarted. Of course, you should make sure that the server will start under the UID of the user to whom it belongs.

  • Rewrite rules in the frontend server. Since users cannot bind to port 80 in this scenario, they must bind to ports above 1024. The frontend server should rewrite each request to the correct backend server.

  • Dedicated ports for each user. You must also ensure that users will use only the ports they are given. You can either trust your users or use special tools that ensure that. One such tool is called cbs; its documentation can be found at http://www.epita.fr/~flav/cbs/doc/html.