(ve):Secure Apache configuration

  • This page was last modified on April 6, 2012, at 13:06.
The (mt) Community Wiki is a collaborative project. Any (mt) Media Temple customer or employee may contribute. Not all articles and/or content have been tested for accuracy by (mt) Media Temple.

For officially moderated and tested articles, be sure to visit our KnowledgeBase.

From (mt) Community Wiki

Contents


This article provides some best-practice guidelines for the appropriate permissions and ownership to use for different files and folders on your server. This article covers:

  • Your document root and the PHP and HTML files it contains
  • Files and directories that web applications need to write to (for example, an "uploads" folder)
  • Applications that are intended to be public-facing, such as Django and Ruby on Rails applications

All (ve) Server customers are responsible for security on their own servers. The settings here are not guaranteed to keep your server secure. Neither are they guaranteed to work well with all server configurations. For specific assistance with your custom server, consult your system administrator.

Please back up any configuration files before you edit them, and make sure you run chown commands only for the appropriate directory.

This article does not cover security patches or alternate software that you can install to make your server more secure in a top-down sense. The focus is on limiting the damage any one part of your server can cause to the server as a whole, should it become compromised, within a standard LAMP setup.

A word to the wise - in general, tweaking your server setup to make web applications more convenient to use is a step toward insecurity. Some of these suggestions really will increase the security of your server, but others are concessions - "if you must have this functionality, here's the least dangerous way to do it." Each section will have a discussion at the beginning to explain which it is.

Requirements

Install LAMP on your server and set up at least one domain as a Virtual Host. Choose the appropriate article below for your OS:

You must also have a basic understanding of Linux File Permissions.

Document root and web page file permissions

The steps in this section are intended to make your server more secure than it is by default.

A Vanilla Apache installation is fairly secure. Pretty much the only owner you SHOULDN'T use for the files in your document root is apache.

Let me break this down and explain how permissions work in your document root:

  1. By default, Apache processes (like the ones initiated by PHP web pages) run as the user apache. All processes that can be started by the public, by means of interacting with your website, will be running as the apache user.
  2. Your web page files are owned by a user other than apache. If, like me, you've been messing around creating test pages as the root user, they are likely owned by root at the moment. (We'll be changing this shortly.)
  3. Your chosen operating system should, by default, set safe permissions on new HTML or PHP files that you upload to the server. Specifically, only the owner should have "write" access.
  4. Put the previous facts together, and we get a fairly secure setup. Public users over the web can interact with your files only as the apache user, but the apache user doesn't have any special permissions for those files. It is functioning in the "everyone" category, and your OS should have created safe permissions for "everyone" users by default. Apache (and malicious users who are trying to crack your website) can only read or execute the files, not modify them. And when you do need to make legitimate changes to the files, you can log in as their owner and change what you need.

So why worry about file ownership in your document directory?

Web-accessible scripts and directories are the most likely to become infected by a hack attempt. A lot of web applications pass data back to the server in some way, and if something nasty gets past whatever sanitizers you have in place, you want to limit the damage. Say a PHP file gets infected. If it's configured to be run by a cron job, for example, it could end up being run by a user that has access to a lot more important files than apache does. We want to make sure that never happens. The solution is to create a unique user and group for each domain on your server, that have access to only that domain's directories.

Instructions

  1. First, create a new user and group on your server. You can follow the domain user example from this article:
  2. Now we're going to make this new user and group the user and group for your domain's document root and your web page files. "User" and "owner" are synonymous. Make sure your path is correct before you run this command. chown -R is a powerful recursive command.
    
    chown -R web1:webgroup1 /var/www/example.com/html/
    
    • Replace web1:webgroup1 with your own user and group. Keep the : in between the user and group.
    • Replace example.com with your own domain name. The path is the full path to your document root.
    • If you have multiple folders under your domain (a cgi-bin for example), you could make the chown one directory higher (chown -R web1:webgroup1 /var/www/example.com/). Or you may want to keep other directories separate, if they are never written to by files that are in your document root.
  3. Finally, make sure your file and folder permissions match the suggested ones in our File Permissions article.

Now you have all the security benefits of having your public-facing files owned by a completely unique user on your server, with access limited to that domain only. This also happens to be a great user to use for FTP, if you've set that up on your server.

Web applications that need write access

Quite a few common Content Management Systems (CMSs) rely on the ability to make changes to your server from the web. The WordPress image upload feature, for example, is configured to use this server function. Upload scripts, email subscriptions, and other PHP forms may all need to write to the server.

This section is a concession to software. Making either of the changes described below will make your server less secure. However, they are better than giving full permissions (777 permissions) on your files and directories!

So, which method should you choose? It depends on two factors:

  1. How extensively does the web application need to make changes on the server? If it modifies lots of files all over the place, try changing the web server user. If it can be limited to one folder, try changing apache's permissions for just that folder.
  2. How often will you need to manually manipulate the web-modified files through FTP or SSH? If you will need to do this frequently, try changing the web server user to avoid permission errors. If you need to do this only rarely, you may be fine with apache being the group for just one folder.

Changing the web server user

This will change the user and group that Apache uses for web-initiated processes. Instead of running as the very limited apache user, web processes will run as the user for that domain. See the previous section for a discussion of the security benefits you will give up by doing this.

Do not make this change until you have followed the steps in the previous section to set up a separate user just for this domain. We will be using web1 and webgroup1 as examples - replace them with the actual user and group you have set up.

  1. Log into your server with a root or sudo user via SSH.
  2. Open your domain's VirtualHost file for editing. This file is different depending on which OS you have installed. You can check the appropriate LAMP article (links above) if you don't remember where it is. This example is for the domain example.com on a Ubuntu server:
    
    vi /etc/apache2/sites-available/example.com
    

    Add the following line to the file, and save your changes (remember to replace web1 and webgroup1 with your own user and group):

    example.com
    
    <VirtualHost 12.34.56.78:80>
    ...
    SuExecUserGroup web1 webgroup1
    ...
    </VirtualHost>
    
  3. Restart Apache (Ubuntu example):
    /etc/init.d/apache2 reload
    
  4. Running PHP under different users for different domains can make your server slow, so you may want to configure PHP to run as FastCGI while you're at it. Here's a Ubuntu walkthrough (which will also be helpful for other OS's):

Modifying apache permissions in a limited folder

This will change the group of a particular directory (and the files within it) to apache, then grant group write permissions on that directory. This may be a simple solution for an uploads directory that remains isolated from the rest of the server.

Be careful to use the correct path when running recursive commands like the ones shown below. Recursive commands are very powerful.

  1. Log into your server with a root or sudo user via SSH.
  2. Change the group of the desired directory - be sure to replace the path with your own:
    
    chgrp -R apache /var/www/example.com/html/uploads/
    
  3. Add write permissions for the group - again, use your own path:
    
    chmod -R g+w /var/www/example.com/html/uploads/
    
  4. That's it! Apache can now write to that folder and the files within it.

Applications outside of your document root and open_basedir

You may want to use web scripting software such as Django to make projects and applications for your site. These types of applications usually shouldn't be hosted in a web-accessible directory, because they are mostly built in executable languages like Perl, which should stay behind the scenes and inaccessible to the public. However, the end product needs to be able to display over the web and/or interface with your web page scripts.

The best answer for this is to create your project in a completely separate folder, outside of your html directory, and then to configure Apache to be allowed to serve pages in that directory. You'll also need to make a symlink for that project in your HTML directory to the actual project directory. Follow the instructions below to set this up.

Allowing Apache to access files in an additional directory makes your server slightly less secure. However, since this directory will contain only the files for your new application, the amount of damage that could be done if your application is hacked will still be limited.

This example will create a directory for Django projects:

  1. Log into your server with a root or sudo user via SSH.
  2. Create your new project folder. You might want to do this in your home directory, or under the domain but not in the html folder. This example will show how to create the folder var/www/example.com/django/.
    
    mkdir /var/www/example.com/django
    
  3. Go ahead and set up your specific project directory now, if you are planning to make a subfolder for your application. This example assumes that you've generated the folder /var/www/example.com/django/testapp/, which actually contains your project. If you aren't making a subfolder, just leave /testapp off of the path in the examples below.
  4. Open your domain's VirtualHost file for editing. This file is different depending on which OS you have installed. You can check the appropriate LAMP article (links above) if you don't remember where it is. This example is for the domain example.com on a Ubuntu server:
    
    vi /etc/apache2/sites-available/example.com
    

    Add the following lines to the file, and save your changes:

    example.com
    
    <VirtualHost 12.34.56.78:80>
    ...
    <Directory "/var/www/example.com/html">
    php_admin_value open_basedir "/var/www/example.com/html/:/tmp/:/var/www/example.com/django/testapp/"
    php_admin_value include_path "/var/www/example.com/html/:/tmp/:/var/www/example.com/django/testapp/"
    </Directory>
    ...
    </VirtualHost>
    
    • The path shown in the Directory line should be your current document root.
    • The paths shown in the php_admin_value open_basedir line should include ALL the paths that Apache can have access to. This typically includes your document root, the /tmp/ directory, and any additional directories you want to set up on your server (e.g., the one we created in Step 2).
    • The php_admin_value include_path line should include your normal document directories (typically your html directory and /tmp) and the path to your new directory. This line is not necessary if you're not planning to include files (etc.) from this project in other files in your document root. See php.net for more information.

    vi tip: Press "i" to enter "insert mode" so you can type and copy/paste. Use the arrow keys to navigate. Press "Esc" to exit "insert mode" when you are done modifying the file. Type ":wq" to save and quit.

  5. Create a symlink from your document root to the project directory. This example will show you how to create a folder called testapp in your document root, that will link to the project in /var/www/example.com/django/testapp/. The resulting URL for the project will be http://example.com/testapp/.
    
    ln -s /var/www/example.com/django/testapp /var/www/example.com/html/testapp
    

    Remember not to delete the symlink through FTP. FTP will follow the symlink and delete your content as well. Instead, if you want to delete the symlink, run this command:

    
    rm -f /var/www/example.com/testapp
    
  6. Restart Apache (Ubuntu example):
    /etc/init.d/apache2 reload
    
  7. That's it! You should now be able to visit http://example.com/testapp/ in your browser and view the content of your website application.