nginx 重定向所有子域(当它不应该时)
nginx redirecting all subdomains (when it shouldn't)
我有一个 nginx 服务器 运行。我希望它将 http://www.example.com
重定向到 https://www.example.com
,但不要触及 http://foo.example.com
.
等任何其他子域
出于某种原因,无论我在子域中添加什么,它仍然会被重新路由。我的网页显示在 www.example.com(它应该),但也在 foo.example.com 和 example.com(它不应该)
这是我的 example.com 配置文件:
server {
listen 80;
server_name www.example.com;
# For debug
add_header X-debug-message "listen:80, server_name:www.example.com, redirect:https://$host$request_uri" always;
# Riderect
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
# For debug
add_header X-debug-message "listen:443, server_name:www.example.com, redirected:https://$host$request_uri" always;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root /var/www/example.com;
# Redirect
location / {
proxy_pass http://192.168.1.224:80;
}
}
前往 www.example.com
按预期显示我的网页。但是去 foo.example.com
也给了我我的网页 - 它不应该。 example.com
也给我网页。
在我的浏览器中打开 www.example.com
,我看到以下 http header(如预期的那样):
X-debug-message: DEBUG: listen:443, server_name:www.example.com, redirected:https://www.example.com/
在我的浏览器中打开 foo.example.com
,我看到以下 http header(与预期不同):
X-debug-message: DEBUG: listen:443, server_name:www.example.com, redirected:https://foo.example.com/
如何让我的 nginx 只重定向 www.example.com
?
确保 foo.yourdomain.com 的 dns 记录实际上是用
DNS 提供商
为子域创建第二个服务器块 'foo.example.com'
否则所有请求到端口 80
将被重定向到可用的服务器块,在您的情况下
www.example.com - 服务器块应如下所示:
server {
server_name foo.example.com;
location / {
root path/to/foo/index.html;
index index.html index.htm;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
try_files $uri $uri/ /index.html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate
/etc/letsencrypt/live/example.com/fullchain.pem; # n
managed by Certbot
ssl_certificate_key
/etc/letsencrypt/live/nextoma.com/privkey.pem; # managed by
Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by
Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by
Certbot
}
使用以下命令将 ssl 证书添加到 foo.example.com:
certbot --nginx -d foo.example.com
重新启动 nginx 并再次检查 foo.example.com
谢谢大家的评论!
对于其他读者,以及未来的参考,这是我现在开明的理解。
nginx 将其 enabled-sites conf 中的第一个条目视为默认路由。因此,第一个条目
server {
listen 80;
server_name example.net www.example.net;
...
}
实际上被视为
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
所以,我的错误是将 *.example.com -> MyIP
添加到我的 DNS,并假设 nginx 只会 404
所有我没有明确定义的路由。事实上,它会寻找匹配 foo.example.com
的路由,如果不匹配,则将其路由到默认路由。
所以,我现在更改了我的 DNS 以明确处理我想要路由的所有子域,并且我在 nginx 中明确列出了所有子域。
现在 - 我如何实现我最初的计划 - 只路由 *.example.com
到我的 IP,并让 nginx 404
除了我明确定义的请求之外的所有请求 - 我仍然不明白。
在 DNS 中显式路由所有子域不太灵活,因为如果我想在内部测试新服务,我需要更新 DNS 并等待更改传播。但是,我想现在可以了。
您需要让第一个条目在 443 上侦听 HTTPS 和服务器名称 _
和 return 404。
server {
listen 443 ssl;
server_name _;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_certificate /etc/nginx/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/nginx/certs/nginx-selfsigned.key;
location / {
return 404;
}
}
通过在文件中将典型的 HTTP 重定向到 HTTPS(我将其作为最后一个条目):
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
然后所有 HTTP 请求都转换为对应的 HTTPS。然后,如果您请求一个尚未在 NGINX 配置文件中配置的子域,它将默认为 returns 404 的第一个条目。所有其他已配置的子域和根域,如果您将其作为条目,将正确解析。
您还可以保留通配符 DNS,这比必须将每个子域添加为条目更实用,正如您在回答中指出的那样。
我有一个 nginx 服务器 运行。我希望它将 http://www.example.com
重定向到 https://www.example.com
,但不要触及 http://foo.example.com
.
出于某种原因,无论我在子域中添加什么,它仍然会被重新路由。我的网页显示在 www.example.com(它应该),但也在 foo.example.com 和 example.com(它不应该)
这是我的 example.com 配置文件:
server {
listen 80;
server_name www.example.com;
# For debug
add_header X-debug-message "listen:80, server_name:www.example.com, redirect:https://$host$request_uri" always;
# Riderect
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
# For debug
add_header X-debug-message "listen:443, server_name:www.example.com, redirected:https://$host$request_uri" always;
# SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root /var/www/example.com;
# Redirect
location / {
proxy_pass http://192.168.1.224:80;
}
}
前往 www.example.com
按预期显示我的网页。但是去 foo.example.com
也给了我我的网页 - 它不应该。 example.com
也给我网页。
在我的浏览器中打开 www.example.com
,我看到以下 http header(如预期的那样):
X-debug-message: DEBUG: listen:443, server_name:www.example.com, redirected:https://www.example.com/
在我的浏览器中打开 foo.example.com
,我看到以下 http header(与预期不同):
X-debug-message: DEBUG: listen:443, server_name:www.example.com, redirected:https://foo.example.com/
如何让我的 nginx 只重定向 www.example.com
?
确保 foo.yourdomain.com 的 dns 记录实际上是用 DNS 提供商
为子域创建第二个服务器块 'foo.example.com' 否则所有请求到端口 80 将被重定向到可用的服务器块,在您的情况下 www.example.com - 服务器块应如下所示:
server { server_name foo.example.com; location / { root path/to/foo/index.html; index index.html index.htm; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; try_files $uri $uri/ /index.html; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # n managed by Certbot ssl_certificate_key /etc/letsencrypt/live/nextoma.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot }
使用以下命令将 ssl 证书添加到 foo.example.com:
certbot --nginx -d foo.example.com
重新启动 nginx 并再次检查 foo.example.com
谢谢大家的评论!
对于其他读者,以及未来的参考,这是我现在开明的理解。
nginx 将其 enabled-sites conf 中的第一个条目视为默认路由。因此,第一个条目
server {
listen 80;
server_name example.net www.example.net;
...
}
实际上被视为
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
所以,我的错误是将 *.example.com -> MyIP
添加到我的 DNS,并假设 nginx 只会 404
所有我没有明确定义的路由。事实上,它会寻找匹配 foo.example.com
的路由,如果不匹配,则将其路由到默认路由。
所以,我现在更改了我的 DNS 以明确处理我想要路由的所有子域,并且我在 nginx 中明确列出了所有子域。
现在 - 我如何实现我最初的计划 - 只路由 *.example.com
到我的 IP,并让 nginx 404
除了我明确定义的请求之外的所有请求 - 我仍然不明白。
在 DNS 中显式路由所有子域不太灵活,因为如果我想在内部测试新服务,我需要更新 DNS 并等待更改传播。但是,我想现在可以了。
您需要让第一个条目在 443 上侦听 HTTPS 和服务器名称 _
和 return 404。
server {
listen 443 ssl;
server_name _;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_certificate /etc/nginx/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/nginx/certs/nginx-selfsigned.key;
location / {
return 404;
}
}
通过在文件中将典型的 HTTP 重定向到 HTTPS(我将其作为最后一个条目):
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
然后所有 HTTP 请求都转换为对应的 HTTPS。然后,如果您请求一个尚未在 NGINX 配置文件中配置的子域,它将默认为 returns 404 的第一个条目。所有其他已配置的子域和根域,如果您将其作为条目,将正确解析。
您还可以保留通配符 DNS,这比必须将每个子域添加为条目更实用,正如您在回答中指出的那样。