Nginx 默认 Server

默认情况下 nginx 的 default_server 指令可以处理没有匹配到 server_name 的请求,如果没有显式定义 default_server,则 nginx 会选取第一个定义的 server 作为 default_server。

默认 Server 存在的问题

这样的规则会导致两个问题:

  1. 当有任何域名解析到我们的服务器,我们的 default_server 都会处理它,如果我们没有设置 default_server 则我们的第一个 server 会处理这些域名,无论这些 server 是否绑定 server_name;
  2. 如果我们没有绑定 IP 到 server,当使用 IP 访问我们的服务器时,也会被 default_server 处理;

这两个问题会带来什么样的灾难,大家都明白,这里就不再赘述了;

如何规避默认 Server 带来的问题

取消 80 端口的 default_server

解决默认 Server 最简单的办法就是取消默认 Server 就行了;

但是 nginx 中我们无法取消,因为不显示申明,也会默认第一个 Server 作为隐式申明

既然不能取消,那我们就只能修改默认 Server 的表现行为了;

我们可以通过如下配置,让 default_server 直接返回 444 状态;

1
2
3
4
5
server {
listen 80 default_server;
server_name _;
return 444;
}

444 No Response

Nginx上HTTP服务器扩展。服务器不向客户端返回任何信息,并关闭连接(有助于阻止恶意软件)。

取消 443 端口的 default_server

由于 443 需要 ssl 证书,所以还需要再 80 的配置上增加关于 ssl 的配置;

1
2
3
4
5
6
7
8
9
server {
listen 443 default_server;
server_name _;

ssl_certificate /etc/nginx/ssl/nginx.crt; # 证书配置
ssl_certificate_key /etc/nginx/ssl/nginx.key; # 证书配置

return 444;
}

上述配置中的证书配置可以采用任意证书,因为我们本就不会处理匹配的请求,所以不需要正确的证书来获取浏览器的信任,但是 nginx 的 443 端口 server 又必须配置 ssl 证书,所以这里我们自己生成一个证书就可以了,不建议使用自有的真实证书,这会暴露域名;

生成证书:

1
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

HTTP 自动跳转到 HTTPS

有时候我们需要使用 default_server 为我们带来便利,例如:实际网站的 server 中仅配置 443 端口,80 端口的请求统一跳转到对应的 443 服务;

1
2
3
4
5
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}

那么这时候,未受理的域名和ip访问均会跳转到 443 端口,我们只需要对 443 的默认 Server 输出 HTTP Status 444 就行了;

1
2
3
4
5
6
7
8
9
server {
listen 443 default_server;
server_name _;

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

return 444;
}

完整配置

不自动强制 HTTPS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80 default_server;
server_name _;
return 444;
}
server {
listen 443 default_server;
server_name _;

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

return 444;
}

需要 HTTP 自动跳转到 HTTPS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 default_server;
server_name _;

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

return 444;
}

评论

富强、民主、文明、和谐,自由、平等、公正、法治,爱国、敬业、诚信、友善