我有一个正在运行的 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 标头(如预期):
X-debug-message: DEBUG: listen:443, server_name:www.example.com, redirected:https://www.example.com/
在浏览器中打开
foo.example.com
,我看到以下 http 标头(与预期不同):
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
您需要使第一个条目在 443 上监听 HTTPS 和服务器名称
_
并返回 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 配置文件中配置,它将默认为返回 404 的第一个条目。所有其他配置的子域和根域(如果您将其作为条目)将解析正确。
您还可以保留通配符 DNS,这比必须将每个子域添加为条目更实用,正如您在答案中指出的那样。
谢谢大家的评论!
供其他读者和将来参考,这是我现在的开明理解。
nginx 将其启用站点配置中的第一个条目视为默认路由。因此,第一个条目
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 并等待更改传播。但是,我想现在这样就可以了。
要将除指定子域之外的所有子域路由到 404,您可以使用:
server {
listen 443 ssl http2;
server_name *.domain.com;
location / {
return 404;
}
}