Disable Direct IP Address Access in Nginx on Linux
Nginx's server_name
directive indicates the domain name it's listening on. But if none of the server
blocks match the incoming request, it will still fall back to the last HTTP/HTTPS server
block. So direct access by IP address will probably be caught by some route instead of being dropped, which is often not ideal.
To drop the requests by IP address, we'll be creating fallback server
blocks and end the connections without sending any data.
Disable IP Access in HTTP
Create a server
block with the server_name
of _
to catch all requests, and add default_server
to the listen
directive:
server {
server_name _;
listen 80 default_server;
listen [::]:80 default_server; # IPv6
return 444; # end the connection without sending any data
}
Nginx config
Disable IP Access in HTTPS
The same goes with HTTPS. However, a little workaround is needed if you're not running Nginx v1.19.4+.
To check your Nginx version:
$ nginx -v
nginx version: nginx/1.20.2
Output
Nginx v1.19.4+
Create a HTTPS server
block with the ssl_reject_handshake
directive set to on
, which will reject TLS/SSL handshake since we're not going to send any data in this route:
server {
server_name _;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server; # IPv6
ssl_reject_handshake on; # reject ssl handshake
return 444; # end the connection without sending any data
}
Nginx config
Legacy Nginx
We'll be using self-signed certificate for the HTTPS server
block, since Nginx will throw an error if you're not providing certificates to a server
block with ssl
on.
Use openssl
to generate a certificate that lasts 100 years, so we won't need to renew it:
$ sudo openssl req -x509 -nodes -newkey -days 36500 rsa:4096 -keyout /etc/nginx/self_signed.key -out /etc/nginx/self_signed.crt
Change the output locations if you like.
Create a server
block with the certificate:
server {
server_name _;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server; # IPv6
ssl_certificate /etc/nginx/self_signed.crt;
ssl_certificate_key /etc/nginx/self_signed.key;
return 444; # end the connection without sending any data
}
Nginx config
Finishing Up
Reload your Nginx's configuration:
$ sudo nginx -s reload