nginx在决定请求由哪个server块执行时,主要关注的是server块中的listen和server_name两个字段,如果根据listen指令无法得到最佳匹配,将会开始解析server_name指令。nginx会检查请求中的”Host”头,这个值包含了客户端实际试图请求的域名或者ip地址。nginx会根据这个值去匹配server_name指令,匹配规则会在文章中详细描述。其中有一个需要大家注意的地方是如果没有匹配到任何规则的话,则会选择可用列表中的第一个server,带来的问题就是未绑定域名或IP直接访问80和443端口会给后端逻辑服务增加压力并产生不合理的错误日志,合适的解决办法是通过在nginx的server块中添加default_server禁止未绑定域名或IP访问80和443端口过滤不合理的流量。

Server_name指令

如果根据listen指令无法得到最佳匹配,将会开始解析server_name指令nginx会检查请求中的Host头,这个值包含了客户端实际试图请求的域名或者ip地址nginx会根据这个值去匹配server_name指令,匹配规则如下:

1.nginx会尝试寻找一个和sever_nameHost值完全匹配的server块,如果找到多个精确匹配,则会使用第一个匹配的server块;
2.如果没有找到精确匹配的server块,则nginx尝试找到server_name带有*开头的server块,如果找到多个,则选择最长匹配的server块;
3.如果没有找到使用开头的server块,则会寻找以结尾的server块,同样,如果有多个匹配, 选择最长匹配;
4.如果没有找到使用*匹配的server块,则会寻找使用正则表达式(以~开头)定义server_nameserver块,如果找到多个匹配,会使用第一个匹配;
5.如果没有找到正则表达式匹配的server块,则nginx将会选择一个匹配listen字段的default server块.每一个ip和端口组合都可以配置一个且只能配置一个默认的default_server块,如果没有的话,则会选择可用列表中的第一个server;

精确的server_name匹配

server {
     listen       80;
     server_name  www.domain.com;
     ...
}

以*通配符开始的字符串:

server {
     listen       80;
     server_name  *.domain.com;
     ...
}

以*通配符结束的字符串:

server {
     listen       80;
     server_name  www.*;
     ...
}

匹配正则表达式:

server {
     listen       80;
     server_name  ~^(?.+)\.domain\.com$;
     ...
}

如果以上都没有匹配,则使用default_server.如果没有指定default_server,则会选择第一个可用的server.我们可以指定对于没有匹配的host值时,返回错误到客户端.可以用来防止别人把垃圾流量转到你的网站。

server {
    listen  80   default_server;
    server_name  _;    return 444;
}

HTTP

server {
    listen 80 default_server;
    server_name _;
    root /var/www/html/;

    location / {
        return 444;  # close connect,do not return response
    }
}
  • 444: 这个状态码表示 Nginx 直接关闭连接,而不返回任何响应。这意味着请求者不会收到任何反馈,无法得知请求是否成功。
  • 404: 这个状态码表示“未找到”,返回给客户端一个标准的错误页面,表明请求的资源不存在。

HTTPS

Create SSL Certificate

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /usr/local/nginx/conf/ssl/nginx.key -out /usr/local/nginx/conf/ssl/nginx.crt

Configure File

server {
    server_name _;
    listen 80 default_server;
    listen 443 ssl default_server;

    ## To also support IPv6, uncomment this block
    # listen [::]:80 default_server;
    # listen [::]:443 ssl default_server;

    ssl_certificate /usr/local/nginx/conf/ssl/nginx.crt;
    ssl_certificate_key /usr/local/nginx/conf/ssl/nginx.key;
    return 444; # or whatever
}

参考文档

标签: nginx, https, http, default_server, 444, 404, 403

添加新评论