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¶
- Turn on
Indexesfor/var/www/html, removeindex.html, load the site. Turn it off. - Run
curl -I localhostbefore and afterServerTokens Prod.
Build it¶
An apache-check.sh that greps the three files for the directives on this page and runs curl -sI localhost.