Skip to content

Apache

Apache is the web server on most Linux images that serve a site. If the README doesn't make the machine a web server, remove it (sudo apt purge apache2). If it does, the defaults leak information and allow more than a site needs.

Where

/etc/apache2/apache2.conf (main), /etc/apache2/conf-available/security.conf (the security settings), /etc/apache2/sites-available/000-default.conf (the default site), /etc/apache2/mods-enabled/ (loaded modules). After any change: sudo apachectl configtest && sudo systemctl restart apache2.

The settings

Setting File Value Why
ServerTokens security.conf Prod The Server: header says "Apache" instead of the exact version and modules
ServerSignature security.conf Off Error pages don't print the version
TraceEnable security.conf Off The TRACE method reflects requests, useful for stealing cookies
Options in <Directory /var/www/> apache2.conf, 000-default.conf remove Indexes (leave FollowSymLinks only if needed) Without an index file, Indexes lists the directory contents to anyone
AllowOverride apache2.conf, 000-default.conf None All lets a .htaccess file uploaded to the site change the server's configuration
<Directory /> apache2.conf Require all denied and Options None The filesystem root isn't served
Header set X-Frame-Options "SAMEORIGIN" site config (needs a2enmod headers) present The site can't be framed by another site (clickjacking)
Header set X-Content-Type-Options "nosniff" same present Browsers don't guess file types
Header always set Strict-Transport-Security "max-age=31536000" HTTPS site present Browsers refuse plain HTTP afterward
SSLProtocol mods-enabled/ssl.conf -all +TLSv1.2 +TLSv1.3 SSLv3, TLS 1.0, and 1.1 are broken
Modules apache2ctl -M disable status, autoindex, cgi, userdir, info unless the site uses them Each is a feature an attacker can use

Apply

Three files, all edited with sudo nano. In /etc/apache2/conf-available/security.conf, find the ServerTokens, ServerSignature, and TraceEnable lines (Ctrl+W) and set them to the table's values. In /etc/apache2/apache2.conf, find the <Directory /var/www/> block and make it read:

<Directory /var/www/>
        Options -Indexes +FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>

Do the same in /etc/apache2/sites-available/000-default.conf if that file has its own Options or AllowOverride lines. Then add the headers in a new small file and enable it, disable the modules the site doesn't use, and check the config before restarting:

sudo a2enmod headers
printf '%s\n' 'Header always set X-Frame-Options "SAMEORIGIN"' 'Header always set X-Content-Type-Options "nosniff"' | sudo tee /etc/apache2/conf-available/headers-hardening.conf
sudo a2enconf headers-hardening
sudo a2dismod autoindex status cgi userdir info
sudo apachectl configtest
sudo systemctl restart apache2

a2dismod complains about a module that isn't enabled; that's fine. configtest prints Syntax OK or the file and line with the problem.

Files and ownership

/var/www/html is owned by root (or a deploy user), readable by www-data, and not writable by it unless the application needs an upload directory. A site the web server can write to is a site an attacker can rewrite.

sudo chown -R root:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 750 {} \;
sudo find /var/www/html -type f -exec chmod 640 {} \;

Look inside /var/www for things that aren't the site: a shell.php, a backup archive, a .git directory, uploaded media the README forbids.

Verify

grep -E '^(ServerTokens|ServerSignature|TraceEnable)' /etc/apache2/conf-available/security.conf
grep -rE 'Options|AllowOverride' /etc/apache2/apache2.conf /etc/apache2/sites-enabled/
curl -sI http://localhost | grep -iE 'server|x-frame'
apache2ctl -M | grep -E 'autoindex|status|cgi'

The curl shows Server: Apache with no version, and the X-Frame-Options header.

Example

curl -I localhost returns Server: Apache/2.4.52 (Ubuntu) (Mint reports its Ubuntu base) and http://localhost/uploads/ shows a directory listing. security.conf has ServerTokens OS; 000-default.conf has Options Indexes FollowSymLinks and AllowOverride All. Fix all three, restart, and check /var/www/html/uploads: it contains cmd.php, which is a web shell. Delete it.

Try it

  1. Turn on Indexes for /var/www/html, remove index.html, load the site. Turn it off.
  2. Run curl -I localhost before and after ServerTokens Prod.

Build it

An apache-check.sh that greps the three files for the directives on this page and runs curl -sI localhost.

Next

nginx