Just as we’ve been offering tips and advice on other IT issues in a recent series of blogs (for example, 25 Linux Server Hardening Tips), Monitis has put together a checklist of 101 actions you can take to maximize security around LAMP.
Recently, we talked about Linux operating system tips (20 Linux Server Performance Tips – Part 1, 20 Linux Server Performance Tips – Part 2). Now, let’s chat a bit about tips for Apache. It’s our hope that presenting this information will give you some new ideas on how to make administering your system an easier job!
21 Tips for Apache
Hide your Apache version number
- Your website visitors don’t care about the version of Apache that you run. So, hide it by instructing Apache not to emit it in the HTTP Server header. Unfortunately Apache will still identify itself as Apache, but at least not as Apache 2.0 on Debian.
Use custom error pages
- The default error pages that Apache displays also show your Apache version. If you use custom error pages, you can prevent this. In most cases, you can create a simple HTML file and tell Apache to use it for all error pages. You might want to create separate error pages for “404” (“page not found”) errors and others like it.
- Enabling syslog doesn’t help if none of your software sends its logs to the syslog server. Configure Apache to use either syslog on the local host, or a remote syslog daemon. Make sure you log the correct error levels, which may or may not include NOTICE-level messages
- Overrides are those directives that you see in “.htaccess” files. Using overrides, you can create very flexible configurations, but they can also be a security issue. Set “AllowOverride None” as a default-deny rule, and then move on from there by enabling the overrides that you actually need.
- You are probably not using SSI (“server-side includes”). SSI is an older technology that isn’t really commonplace anymore. Unless you really need it, disable SSI. The problem with SSI is that it allows arbitrary command execution on a server as the server user, and that’s never a good idea.
- CGI, “common gateway interface”, is a protocol for dynamic websites. You may or may not be using CGI, so find out! It’s possible that you’re running PHP in CGI mode, in which case disabling CGI altogether would be a bad idea. In this case, or in case you are using any other CGI scripts, restrict CGI script execution to the bare minimum. Be sure to use a default-deny policy and then individually allow every authorized script to run.
Don’t use “/cgi-bin/”
- As with moving SSH to a non-default port, you want to move your CGI script directory to a non-default location. The default is “/cgi-bin/”, and you should change that default to something else — ideally something unique to your server or company, but otherwise simply to “/scripts/”, “/dynamic/”, or something along those lines.
Run Apache as a separate user
- It is customary to run Apache under a user account dedicated only to Apache. This user is often called “www-data”, “httpd”, or “apache”. Feel free to make up your own name…Marilyn, Dean, Elvis…whatever. Remember, non-default names and numbers often aid security. Make sure the account is dedicated solely to Apache. Don’t use the “nobody” account, and don’t run Apache as root!
Disable modules that aren’t used
- You don’t need every module that Apache comes with by default. Check the list of enabled modules and disable each and every module that you don’t use. It’s as simple as “a2dismod <module>” for Apache 2, so there’s no excuse not to do this. The reasoning behind this is the same as that for disabling unused services: You are reducing the surface area that an attacker can use to penetrate your system.
Disable mod_info, mod_status
- These two modules are especially important. If you do not disable these modules, you might as well undo all the work you’ve done to hide your Apache version number — the mod_info and mod_status modules allow an attacker to see not only your Apache version number, but also your operating system down to the specific Linux distribution, the version of PHP you use, and other modules that are enabled. Yikes!
Disable apache docs
- As a simple measure to obscure the fact that you’re running Apache, and which version you are running, disable Apache’s built-in manual that is by default served as if it were a normal website.
Disable sites that you don’t need
- “a2dissite <site>” is the Apache 2 command to disable a site. It’s not very difficult, so use it. This is analogous to disabling modules that you don’t use: You are again reducing the surface area that an attacker can use for system penetration, and again this task does not take much effort to complete. You also get the bonus of documenting your configuration in case you ever need to recover from a disaster.
Disable directory indexing
- In its default configuration, Apache will happily allow an outsider to browse through your file-system. This “feature” is called directory listing and can be very useful. Just make sure that you’ve disabled it where it isn’t needed. Again, a default-deny policy is probably a good idea, and you can always enable a listing for individual directories using an “.htaccess” file.
Use HTTP authentication
- For internal sites, such as a web application for bug tracking, there is usually some built-in authentication, often enough using user names and passwords. But don’t rely on such an authentication mechanism if the entire site is meant to be internal. You don’t need to tell outsiders what bug tracker you use internally, so don’t! HTTP authentication is very easy to set up and offers great security benefits — besides some properties of SSO (single sign-on). Make life easier for yourself and your users, and use HTTP authentication on internal sites.
Minimize script file extensions
- How many versions of PHP have you installed on your web server? How many versions do you actually care about? If you don’t need PHP 3, 4, and 5, then why are you executing “.php3”, “.php4”, and “.php5” files? Restrict script extensions to “.php” if you only use that, and otherwise find out what you use. Remember that you can apply these restrictions per directory. If you don’t use it, lose it!
Hide hidden files
- It sounds awkward to be told to hide “hidden files”, but interestingly enough all sorts of files are hidden from while they are entirely accessible to attackers. These hidden files are called “dot-files”, a name that stems from the convention for hidden files on Linux. These are files and folders whose name begins with a dot (“.”), such as “.htaccess” or “.svn”. You don’t see these files with a plain “ls” command, but an attacker can easily access these files by simply requesting them from your web server. If you find that strange enough — and you’re definitely not alone! — then tell Apache not to serve any files whose name starts with a dot.
Serve only files with known extensions
- Taking that last step a bit further, you can choose to serve only files with known extensions. This follows the “white-listing” paradigm and uses a default-deny policy. Simply tell Apache not to serve any files that you didn’t explicitly allow, and then tell Apache what kind of files it may serve: “.png”, “.js”, “.css”, “.jpg”, etc. The problem here is that it will be difficult for you to create an exhaustive list. The file “mime.types” is definitely a good start, but, in any case, you should work out your specific requirements before you make any changes.
Check the referrer
- Nobody likes bandwidth thieves. Did you know that, unless you’ve taken specific counter-measures, anyone can hot-link the images on your site and eat up your bandwidth for their private gains? A common way to prevent this is to check the HTTP Referrer header, in which the browser tells you which site it came from when requesting a file. If the browser comes in from another site and is requesting image files or other static content, you should tread carefully. Where applicable, tell Apache to refuse these requests.
Restrict the list of script files
- You already know that you should carefully control the list of file extensions that Apache interprets as script files. In most cases, you can also control the exact list of files that Apache will run as script files, without adverse effects. For instance, a Drupal installation will need to directly run only “index.php”, “cron.php”, and a handful of other script files. While there are many PHP files in the Drupal installation, most of these don’t need to be called directly. So, tell Apache not to. Easy as that.
- Login pages should be restricted to SSL/TLS-enabled HTTP (i.e. HTTPS) and should not be accessible via standard HTTP. In fact, you should use HTTPS whenever possible, though it is reasonable from a resource standpoint to only use HTTPS on login pages and other “private” parts of your web application. In any case, you should not save on the cost of a certificate — those now go for around $15 and are only bound to get lower in cost.
Disable TRACE requests
- TRACE requests are yet another debugging tool like ICMP echo requests. In most cases, you don’t need to use TRACE requests, so you should disable these in Apache.
Hope you enjoyed these LAMP security tips especially for Apache. Remember, though, the ultimate in security is having your server monitored 24/7 via the cloud by Monitis. You can even monitor for free! Check out these testimonials from those who have tried and benefited.