有这样的配置在监听 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;
}
1
Pastsong 2023-01-12 04:09:32 +08:00
你加个 default 就好了吧 server_name 匹配不到就去 default_server 了
|
2
bronana OP @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`网站. |
3
h0099 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/ } |
4
ETiV 2023-01-12 04:32:08 +08:00 via iPhone
server{
server_name _; listen 80; location / { return 401; } } |
5
bronana OP @h0099 #3 谢谢回复,读到第二个链接的时候,就解决问题了
``` +server { + listen 80 default_server; + server_name _; # _ 下划线是无数个无效域名中的一个 + return 444; +} ``` |
8
h0099 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 |
9
h0099 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 端口的) |
10
RynItme 2023-01-13 10:27:42 +08:00
配置泛解析 *
|