
When configuring a VirtualHost on Apache or a Server Block on Nginx (two of the most commonly used web servers), there are several security options that you can consider.
Here are some of them, although the specific details depend on the type of web server you are using and the security requirements specific to your application.
Contents
Configuring HTTPS with Certbot
Upgrading to the HTTP/2 and HTTP/3 versions
Disabling the sending of version information
Configuring HTTP security headers
Disabling unused HTTP methods
Enabling denial-of-service protection
Configuring HTTPS
This is the first and most important step. HTTPS encrypts the traffic between the client and the server, making it much more difficult to intercept and read. You will need an SSL certificate for this, which can be obtained for free via Let's Encrypt or purchased from various providers. Once you have a certificate, you can configure your server to use it.
Make sure to replace "exemple.com" and "www.exemple.com" with your domain.
< w/ Nginx >
Here is how you can install Certbot and obtain an SSL certificate for Nginx on a Debian-based Linux system (such as Ubuntu):
Install the Certbot software and the Nginx plugin by running the following command:
sudo apt-get install certbot python3-certbot-nginx
Then, use Certbot to obtain an SSL certificate and configure Nginx:
sudo certbot --nginx -d exemple.com -d www.exemple.com
Follow the on-screen instructions. Certbot will automatically modify the Nginx configuration to apply the SSL certificate.
< w/ Apache >
Here is how you can install Certbot and obtain an SSL certificate for Apache on a Debian-based Linux system (such as Ubuntu):
Install the Certbot software and the Apache plugin by running the following command:
sudo apt-get install certbot python3-certbot-apache
Then, use Certbot to obtain an SSL certificate and configure Apache:
sudo certbot --apache -d exemple.com -d www.exemple.com
Follow the on-screen instructions. Certbot will automatically modify the Apache configuration to use the SSL certificate.
Certbot will also attempt to automatically renew your certificates before they expire. You can test the automatic renewal process with the following command:
sudo certbot renew --dry-run
Enabling version 2 of HTTP
HTTP/2 is the second major version of the HTTP protocol and brings many performance improvements compared to HTTP/1.1, in particular thanks to request multiplexing, which makes it possible to send several requests in parallel over a single connection.
< w/ Nginx >
To enable HTTP/2 in Nginx, you simply need to add the http2 parameter to your listen directives in your server configuration.
Open the Nginx configuration file for your site. It is usually located in /etc/nginx/ or /etc/nginx/sites-available/.
Add http2 to the listen directive for SSL connections, as follows:
server {
listen 443 ssl http2;
...
}
< w/ Apache>
For Apache, enabling HTTP/2 requires the use of the mod_http2 module.
Make sure that the mod_http2 module is enabled. You can enable it by running the following command:
sudo a2enmod http2
Then, open the configuration file for your Apache site. This is usually found in the /etc/apache2/sites-available/ directory.
Add the Protocols directive to enable HTTP/2:
<VirtualHost *:443>
Protocols h2 http/1.1
...
</VirtualHost>
This will enable HTTP/2 for your website. Note that HTTP/2 is generally used with HTTPS, so make sure your site is secured with it.
Disabling the server version information
By default, your server may include version information in its responses via the HTTP headers, which can help attackers identify potential vulnerabilities. Although this can be useful for debugging purposes, it can also provide valuable information to a potential attacker. For example, if your server uses a software version known to have security flaws, an attacker can exploit these flaws to attack your server.
It is therefore preferable to disable this version information. Here is how you can do it:
< w/ Nginx >
In Nginx you can modify the base configuration which is located in /etc/nginx/nginx.conf and use the server_tokens directive to control whether the server version information is sent.
Modify the default configuration file:
sudo nano /etc/nginx/nginx.conf
Then uncomment the following line (delete the #), if it is present, or add it.
server_tokens off;
server_tokens off; tells Nginx not to include the version information in the HTTP headers.
This directive can also be placed in a server block of an Nginx configuration file if you do not want it to apply generally.
< w/ Apache >
In the base Apache configuration, you need to modify the main configuration file. The exact name and location of this file may vary depending on your operating system and your installation method, but it is often called apache2.conf or httpd.conf and is generally found in a directory such as /etc/apache2/ or /etc/httpd/.
Modify the default configuration file:
sudo nano /etc/apache2/apache2.conf
Look for the ServerTokens and ServerSignature directives and modify or add them like this:
ServerTokens Prod
ServerSignature Off
ServerTokens Prod tells Apache to return only the product name (that is to say "Apache") without any version information. ServerSignature Off disables the inclusion of the server version information in the error pages generated by the server.
These directives can be placed anywhere at the root of the configuration file, outside of any <VirtualHost> or <Directory> block.
Configuring HTTP security headers
There are several HTTP headers that can improve the security of your website, such as X-Content-Type-Options: nosniff (which prevents the browser from "guessing" the content type) and Content-Security-Policy (which limits where content can be loaded from).
< w/ Nginx >
In Nginx, security headers can be added using the add_header directive inside a server or location block in the configuration file (usually located at /etc/nginx/nginx.conf or /etc/nginx/sites-available/default).
For example:
server {
...
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'";
...
}
< w/ Apache >
In Apache, you can use the mod_headers module to add security headers. You can add them inside a Directory, Location, or Files block in the Apache configuration file (usually located in /etc/apache2/sites-available/000-default.conf or /etc/httpd/conf/httpd.conf).
For example:
<Directory /var/www/html>
...
Header always set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options "nosniff"
Header set Content-Security-Policy "default-src 'self'"
...
</Directory>
After adding these directives, do not forget to restart or reload your web server for the changes to take effect.
These header directives have the same meaning whether for Nginx or Apache.
Explanations:
- X-Frame-Options: SAMEORIGIN : Prevents your site from being embedded in an iframe, which can help prevent "clickjacking" attacks. SAMEORIGIN means that the page can only be displayed in a frame on the same origin as the page itself.
- X-XSS-Protection: 1; mode=block : This header enables the cross-site scripting (XSS) filter built into web browsers. In block mode, it prevents the rendering of the page if an attack is detected.
- X-Content-Type-Options: nosniff : Prevents the browser from doing what is called "MIME-type sniffing", or in other words trying to guess the MIME type of responses. If the MIME type is not valid, the browser should not try to guess, it should simply reject the data.
- Content-Security-Policy: default-src 'self' : This header makes it possible to control the resources that the browser is allowed to load for a page. With default-src 'self', you only allow sources from the same domain.
Disabling unused HTTP methods
When you use a browser to access a website, it sends what is called an HTTP request to the server. This request can be of different types, or "methods". The two most common methods are "GET" (to request data, such as a web page) and "POST" (to send data, such as when you fill in a form).
However, there are other HTTP methods, such as "PUT", "DELETE", "OPTIONS", etc. In many cases, a website does not need all of these methods, and some can present security risks if they are not correctly controlled.
Disabling unused HTTP methods means telling the server not to accept requests of types that you do not need. This reduces the means that an attacker could use to cause damage.
< w/ Nginx >
In Nginx, you can use the limit_except directive to limit the allowed methods.
For example:
location / {
limit_except GET POST {
deny all;
}
}
This means that only GET and POST requests are allowed; all other methods will be rejected.
< w/ Apache >
In Apache, you can use the Allow and Order directives to control the allowed methods.
For example:
<Directory "/var/www/html">
AllowOverride None
Order allow,deny
Allow from all
<LimitExcept GET POST>
Deny from all
</LimitExcept>
</Directory>
Similar to the Nginx example, this only allows GET and POST requests and rejects the other methods.
It is good practice to disable the HTTP methods that you do not intend to use, because this reduces the potential attack surface.
Enabling denial-of-service protection
To protect your website against denial-of-service attacks, you can limit the request rate (rate limiting). This makes it possible to limit the number of requests that a client can make within a certain period of time.
Web servers generally have options to limit the number of simultaneous connections, the connection time, the request size, etc., which can all help prevent denial-of-service attacks.
Here is how to proceed with Nginx and Apache:
< w/ Nginx >
In Nginx, you can use the ngx_http_limit_req_module module to limit the request rate.
For example:
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
...
location /login.html {
limit_req zone=one;
...
}
...
}
}
In this example, limit_req_zone defines a memory zone named "one" that stores the clients' IP addresses, and limits the request rate to 10 per second. limit_req applies this limit to a specific location, with a burst rate of 20 and without any delay.
< w/ Apache >
In Apache, you can use the mod_ratelimit module to limit the transfer rate, or the mod_evasive module for more complete protection against denial of service.
Here is an example configuration with mod_ratelimit:
<VirtualHost *:80>
...
<Location "/login.html">
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 500
</Location>
...
</VirtualHost>
In this example, SetOutputFilter RATE_LIMIT enables rate filtering for the specified location, and SetEnv rate-limit 500 limits the rate to 500 bytes per second.
To use mod_evasive, you will first need to install it, because it is not included by default with Apache.
sudo apt-get install libapache2-mod-evasive
After installation, you can enable and configure it by adding something like this to your configuration:
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
</IfModule>
This defines several parameters, such as the number of requests allowed per page and per site within a certain time interval, and the period during which a client will be blocked if it exceeds these limits.
Enabling content isolation: You can configure your server to use separate processes or threads for each request, which can limit the potential damage if a single request is compromised.
- Request rate limiting (Rate Limiting): To prevent brute-force or DDoS attacks, it can be useful to limit the number of requests that a client can make within a certain period of time.
- Setting up a web application firewall (WAF): This is another layer of security that can help protect your application against common attacks, such as SQL code injection.
- Using authentication: If your site contains sections that should not be accessible to the public, make sure to use some form of authentication. Apache has several modules for this, such as mod_auth_basic or mod_auth_digest.
