Nginx设置严格域名校验
配置 HTTP/HTTPS 网站时,Nginx 默认不严格校验 Host/SNI 字段。也就是说,假如我们只配置了 server_name 2dan.cc www.2dan.cc,但用户使用 IP 地址访问,仍然会访问到这个网站(server);另外使用 https://IP 访问,再查看SSL证书,会泄露IP上绑定的域名。
解决:
一、配置默认 server
要解决问题很简单,我们用 default_server 设置默认服务器就行了。对于 HTTP 协议,可以这么写:
server {
listen 80 default_server;
return 444;
}
其中 444 是 Nginx 自定义的、非 HTTP 标准的状态码,表示关闭连接;写成 403 之类也没问题。server_name 省略不写。
HTTPS 类似,但需要 SSL 证书。可以用现成的证书,但其中会有域名等信息。如果介意,自签名一张就好。
要自签名证书,我们先生成私钥(任选其一):
openssl genrsa -out /opt/self-signed.key 2048 # 2048 位 RSA
openssl ecparam -name secp384r1 -genkey -out /opt/self-signed.key # 384 位 ECC
然后根据私钥生成证书:
openssl req -new -x509 -days 3650 -key /opt/self-signed.key -out /opt/self-signed.crt -subj "/C=CN/ST=NULL/L=NULL/O=NULL/OU=NULL/CN=Please-enable-SNI"
其中 3650 是有效期天数,这里是 10 年。Please-enable-SNI 就是通用名称(Common Name),一般这里就是主域名,但我们自签名可以随便写,反正不受信任,也不需要被浏览器信任。