visit
NGINX is built on a non-blocking, event-driven architecture. It has one primary process, several worker_processes, and two cache management processes. To see this, you just need to run the ps command with the switches:
ps -ef --forest | grep nginx
The worker_processes wait for an event using two types of API: epoll or kqueue. When receiving a new client event on the listener socket, the worker_process creates a new socket connection.
1. Check the correctness of the written configuration before applying it
After changing or creating a configuration, you need to check the syntax and the correctness of writing the config file. Nginx allows you to check the correctness of writing the configuration with the following command:
nginx -t
2. Reload Nginx without restarting the service
It is a good practice to apply settings without restarting the service. This does not terminate current connections and eliminates the waiting period when loading the service, i.e. there is no downtime:
nginx -s reload
/etc/init.d/nginx reload
service nginx reload
3. Disable Nginx server_tokens
By default, the server_tokens directive in Nginx displays the version number of Nginx. It is directly visible on all automatically generated error pages and in all HTTP responses in the server header.
This can lead to information disclosure - an unauthorized user can find out about your Nginx version. It would help if you disabled the server_tokens
the directive in the Nginx config file by setting:
server_tokens off;
4. Disable legacy SSL/TLS protocols
ssl_protocols TLSv1.2 TLSv1.3;
5. Disable any undesirable HTTP methods
Disable any HTTP methods that will not be used and do not need to be implemented on the web server.
If you add the following condition to the location block of the Nginx virtual host configuration file, the server will only allow GET, HEAD
, and POST
methods and will filter out methods such as DELETE
and TRACE
:
location / {
limit_except GET HEAD POST { deny all; }
}
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444; }
6. Setup and configure Nginx access and error logs
The Nginx access and error logs are enabled by default and located in logs/error.log
and logs/access.log,
respectively.
error_log logs/error.log crit;
7. Nginx worker connections
One crucial setting we configure is the number of worker processes and the number of worker connections in the Nginx configuration file /etc/nginx/nginx.conf
.
events {
worker_connections 20000;
}
8. Request rate limit
Among the many valuable tactics to prevent DDoS attacks, one of the simplest and most effective is limiting the rate of incoming traffic.
limit_req_zone $binary_remote_addr zone=req_per_ip:1m rate=30r/m;
server {
location /login {
limit_req zone=req_per_ip;
}
}
9. Limiting the number of connections
You can limit the number of connections that can open from a single client IP address, and here we are setting the limit_conn_zone and limit_conn
directives to restrict the number of connections per IP address:
limit_conn_zone $binary_remote_addr zone=conn_per_ip:1m;
server {
location / {
limit_conn conn_per_ip 10;
}
}
This example creates a storage zone named conn_per_ip
to store requests for the specified key, in this case, the client's IP address, $binary_remote_addr. The limit_conn
the directive then sets ten connections from each client's IP address.
10. Timeout options
Slow connections may represent an attempt to keep connections open for a long time. As a result, the server cannot accept new connections:
server {
client_body_timeout 5s;
client_header_timeout 5s;
}
In this example, the client_body_timeout
directive specifies how long Nginx waits between client body entries and client_header_timeout
specifies how long Nginx waits between client header entries. Both are set to 5 seconds.
11. Limit the size of requests
Similarly, large buffer values or large HTTP request sizes make DDoS attacks easier. So, we limit the following buffer values in the Nginx configuration file to mitigate DDoS attacks:
client_body_buffer_size 200K;
client_header_buffer_size 2k;
client_max_body_size 200k;
large_client_header_buffers 3 1k;
client_body_buffer_size 1k
— (default 8k or 16k) The directive specifies the size of the client request body buffer;
client_header_buffer_size 1k
- directive sets the header buffer size for the request header from the client. A buffer size of 1Kb is sufficient for the vast majority of requests.
client_max_body_size 1k
- the directive sets the maximum allowable size of the client request body, specified by the Content-Length line in the request header.
large_client_header_buffers 2 1k
- the directive assigns the maximum number and size of buffers for reading large headers from a client request.
12. IP Blacklist
If you can identify the client IP addresses used for the attack, you can blacklist them with the deny directive so that NGINX and NGINX Plus won't accept their connections or requests:
location / {
deny 111.111.111.4;
deny 111.111.111.0/24;
}
13. IP Whitelist
If your website or application is only allowed to be accessed from one or more specific sets or ranges of client IP addresses, you can use allow and deny directives together to allow only those addresses to access the site or application:
location / {
allow 111.111.111.4;
deny all;
}
14. Block access to a file or location
You can use Nginx to block access to a file or location completely. For example, if you notice that the register.php file is the target of an attack, you can completely block access to this file:
location /register {
deny all;
return 444;
}
15. Enable sysctl based protection
Enable sysctl-based protection. We can tweak the kernel and system variables on our server. Edit the /etc/sysctl.conf
file and set these two lines to 1 as follows:
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
16. Nginx as a load balancer
When Nginx is used as a load balancer, settings can be configured to limit the number of connections per server:
upstream domain {
server 111.111.111.4:80 max_conns=100;
server 111.111.111.5:80 max_conns=100;
queue 20 timeout=10s;
}
17. Deny certain user agents
You can easily block user agents i.e. crawlers, bots, and spammers that might be abusing your server:
## Block download agents ##
if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
return 403;
}
## Block some robots ##
if ($http_user_agent ~* msnbot|scrapbot|PxBroker) {
return 403;
}
18. Block Referral Spam
Referral spam is dangerous. That can hurt your SEO ranking through weblogs (if published) since the referrer field links to their spam site. With these lines, you can block access to referrer spammers:
if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) )
{
return 403;
}
19. Stop image hotlinking
An image hotlink or HTML means someone links your site to one of your images but displays it on their site.
location /images/ {
valid_referers none blocked www.domain.com domain.com;
if ($invalid_referer) {
return 403;
}
}
20. Limits the number of connections per IP address at the firewall level
The web server must monitor connections and limit the number of connections per second. This serves 101. Both pf and iptables can block end-users before accessing your Nginx server. Linux Iptables: Throttling Nginx connections per second. In the following example, incoming connections will be dropped if the IP makes more than 15 connection attempts on port 80 within 60 seconds:
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set && \
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 15 -j DROP && \
service iptables save
21. Disable content type sniffing in some browsers
If a response specifies an incorrect content type, then browsers may process the response in unexpected ways.
add_header X-Content-Type-Options nosniff;
22. Enable cross-site scripting (XSS) filter
Add the following line to your configuration file to enable the X-XSS-Protection header on your Nginx web server. When you're done, save your changes and reload Nginx:
add_header X-XSS-Protection "1; mode=block";
23. Configure HTTP/2 Support
HTTP/2 is the successor to the HTTP 1.x network protocol. HTTP/2 is widely used to reduce latency, minimize protocol overhead, add support for request prioritization, and speed up web application loading.
server {
listen 443 ssl http2;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
}
24. Add Content-Security-Policy (CSP)
CSP is an additional layer of security that helps detect and mitigate certain types of attacks, including cross-site scripting (XSS) and data injection attacks. These attacks are used for data theft, website corruption, and malware distribution:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
25. Monitoring Nginx
The state of your server must be constantly monitored. You can watch what the server returns by periodically sending requests to it, for example, through third-party paid services. Or you can fine-tune everything, and there are many ways to do it—more about it in the .
Instead conclusion
It is essential to be flexible and develop a configuration for each case separately.