nginx: Block IP-based access
There are 2 different methods to access a website:
-
Through domain name:
example.org
. -
Through IP address:
1.2.3.4
.
Some site owners don’t want clients access their website through an IP address. If so, they can configure their nginx server to block such access.
HTTP server
Block IP-based access to a HTTP server is very easy:
server {
listen 80 default_server;
server_name _;
return 444;
}
444
is an unofficial HTTP status code used by nginx.
HTTPS server
Block IP-based access to a HTTPS server is slightly tricky:
server {
listen 443 default_server ssl;
server_name _;
ssl_certificate _.crt;
ssl_certificate_key _.key;
return 444;
}
Use OpenSSL to generate _.crt
and _.key
:
openssl req -x509 -days 3650 -out _.crt -keyout _.key -nodes -subj '/CN=_'
Note that you must add options ssl_certificate
and ssl_certificate_key
to
the default server. The certificate can be self-signed, but must be a valid SSL
certificate. Using /dev/null
won’t work. Not specifying these options will
raise an error (even if the client is accessing another server defined in its own
block, with its own domain name and ssl certificate):
no “ssl_certificate” is defined in server listening on SSL port while SSL handshaking …
This is weird. Because with SNI, the request should be routed to that server block and has nothing to do with the default server. It remains a question why nginx must require such a certificate on the default server…