想请教大家 nginx 如何判断 server_name - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bronana
V2EX    NGINX

想请教大家 nginx 如何判断 server_name

  •  
  •   bronana 2023-01-12 03:44:45 +08:00 3173 次点击
    这是一个创建于 1003 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有这样的配置在监听 80 端口

    server { listen 80; server_name www.domain.cc cloud.domain.cc mail.domain.cc blog.domain.cc linux.domain.cc tools.domain.cc notebook.domain.cc domain.cc; return 301 https://$host$request_uri; } 

    我想要判断访问的 host 是否在 server_name 里面

    server { listen 80; server_name www.domain.cc cloud.domain.cc mail.domain.cc blog.domain.cc linux.domain.cc tools.domain.cc notebook.domain.cc domain.cc; #region 这里应该怎么写? if ($host not in server_name) { # 在此返回 404 结束 return 404; exit; } #endregion return 301 https://$host$request_uri; } 
    11 条回复    2023-01-13 13:00:13 +08:00
    Pastsong
        1
    Pastsong  
       2023-01-12 04:09:32 +08:00
    你加个 default 就好了吧 server_name 匹配不到就去 default_server 了
    bronana
        2
    bronana  
    OP
       2023-01-12 04:19:41 +08:00
    @Pastsong #1 刚试了不可以,它直接走 `return 301 https://$host$request_uri;`了,

    假设我有只有一个服务在 `https://cloud.domain.cc`,没有 `https://blog.domain.cc`,

    `cloud.domain.cc` 和 `blog.domain.cc` 域名解析是指向的同一个服务器(ip 一样)

    有人访问`blog.domain.cc`这个不存在的网站,打开的却是`cloud.domain.cc`网站.
    n0099
        3
    n0099  
       2023-01-12 04:25:58 +08:00   2
    首先 if is evil https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/
    我想阁下现在遇到的问题是请求任何`非`列出来的这些子域时(例如`curl -I `Host: example.com` -v http://您的服务端 IP`)仍然会匹配这个 block 导致进入`return 301 https://$host$request_uri`
    如果您所有的 nginx.conf 文件中只有这一个 server block 那么文档 http://nginx.org/en/docs/http/request_processing.html 对此早有预言
    > If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port. In the configuration above, the default server is the first one which is nginx’s standard default behaviour

    要想在 80 和 443 上搭建正确的 default http(s) server 您可以参考 https://serverfault.com/questions/847978/best-practice-to-handle-default-server-and-public-ip-in-nginx
    一个常见错误是只设置了 port80 的 default server ,导致使用 http 或 https 协议请求 443 (或其他)端口时仍然会绕过 default server (因为 default 是针对单个 listen 端口的)
    http://nginx.org/en/docs/http/ngx_http_core_module.html#listen 进一步指出:
    > The default_server parameter, if present, will cause the server to become the default server for the specified address:port pair. If none of the directives have the default_server parameter then the first server with the address:port pair will be the default server for this pair.

    ```nginx
    server {
    listen 80 fastopen=256 default_server;
    listen 443 fastopen=256 ssl default_server;
    server_name _ "";
    access_log path/to/log/default.access.log;
    error_log path/to/log/default.error.log;

    ssl_certificate /etc/nginx/snippets/self-signed-ssl.crt; # 使用 openssl 生成的自签名证书 https://stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl
    ssl_certificate_key /etc/nginx/snippets/self-signed-ssl.key;

    return 444; # https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return The non-standard code 444 closes a connection without sending a response header. https://www.reddit.com/r/Network/comments/e8aveo/nginx_explain_http_444_like_im_five/
    }
    ETiV
        4
    ETiV  
       2023-01-12 04:32:08 +08:00 via iPhone
    server{
    server_name _;
    listen 80;
    location / { return 401; }
    }
    bronana
        5
    bronana  
    OP
       2023-01-12 04:54:27 +08:00
    @h0099 #3 谢谢回复,读到第二个链接的时候,就解决问题了
    ```
    +server {
    + listen 80 default_server;
    + server_name _; # _ 下划线是无数个无效域名中的一个
    + return 444;
    +}
    ```
    bronana
        6
    bronana  
    OP
       2023-01-12 04:54:52 +08:00
    @ETiV #4 谢谢回复,问题解决了
    bronana
        7
    bronana  
    OP
       2023-01-12 05:00:25 +08:00
    @Pastsong #1 谢谢回复,好像结果和您说的差不多,可能是我先前操作还是不当.问题解决了,再次感谢.
    n0099
        8
    n0099  
       2023-01-12 17:52:40 +08:00   1
    #4 @ETiV listen directive 必须加 default 修饰,不然按照 nginx 的脑瘫逻辑,他只会将他读到的所有 conf 文件中第一个出现的 listen 作为 default

    #3
    如果您所有的 nginx.conf 文件中只有这一个 server block 那么文档
    http://nginx.org/en/docs/http/request_processing.html 对此早有预言
    > If its value does not match any server name, or the request does not contain this header field at all, then nginx will route the request to the default server for this port. In the configuration above, the default server is the first one which is nginx’s standard default behaviour
    n0099
        9
    n0099  
       2023-01-12 17:55:13 +08:00
    #5 @bronana 您忘了配置 https 版本以及监听 443 端口的 default listen ,我猜您现在执行
    `curl -v -I 'Host: example.com' https://您的服务器 ip`
    又会进入最初的`return 301 https://$host$request_uri`

    #4 对此早有预言
    > 一个常见错误是只设置了 port80 的 default server ,导致使用 http 或 https 协议请求 443 (或其他)端口时仍然会绕过 default server (因为 default 是针对单个 listen 端口的)
    RynItme
        10
    RynItme  
       2023-01-13 10:27:42 +08:00
    配置泛解析 *
    bronana
        11
    bronana  
    OP
       2023-01-13 13:00:13 +08:00
    @RynItme #10 正解,我试过 *.domain.cc,这个也可以.
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1388 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 37ms UTC 16:49 PVG 00:49 LAX 09:49 JFK 12:49
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86