![如何让 nginx 除非请求特定域名才返回 404?](https://linux22.com/image/704295/%E5%A6%82%E4%BD%95%E8%AE%A9%20nginx%20%E9%99%A4%E9%9D%9E%E8%AF%B7%E6%B1%82%E7%89%B9%E5%AE%9A%E5%9F%9F%E5%90%8D%E6%89%8D%E8%BF%94%E5%9B%9E%20404%EF%BC%9F.png)
我有一个 nginx 服务器,我想在anything.mydomain.com
请求时返回 404,除非anything
是www
,mypythonapp1
或者mypythonapp2
我00-noredirect
在以下位置创建了一个文件/etc/nginx/sites-enabled
:
server {
listen 80;
listen 443 ssl;
server_name _;
return 404;
}
不幸的是,所有内容都会重定向至mypythonapp1
。
其他服务器块如下:
server {
listen mypythonapp1.mydomain.com:80;
server_name mypythonapp1.mydomain.com;
(...)
listen mypythonapp1.mydomain.com:443 ssl; # managed by Certbot
(...)
}
我认为这可能与certbot
我的添加有关/etc/nginx/sites-enabled/mypythonapp1
,尽管我不确定:
(...)
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
(...)
我需要添加一些东西00-noredirect
来避免这种不良行为吗?
编辑:按照@Tim的要求,这是我的几乎完整的nginx配置:
server {
listen 80;
server_name mypythonapp1.mydomain.com;
disable_symlinks off;
location /static {
alias /var/www/mypythonapp/mypythonapp/mypythonapp/static;
}
location / { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_pass unix:/var/run/uwsgi/app/mypythonapp1/socket;
}
listen 443 ssl; # managed by Certbot
# some ssl magic here
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}
server {
listen 80;
server_name mypythonapp2.mydomain.com;
disable_symlinks off;
location /static {
alias /var/www/mypythonapp/mypythonapp/mypythonapp/static;
}
location / { try_files $uri @yourapplication; }
location @yourapplication {
include uwsgi_params;
uwsgi_pass unix:/var/run/uwsgi/app/mypythonapp2/socket;
}
listen 443 ssl; # managed by Certbot
# some ssl magic here
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}
server {
listen 80;
server_name www.mydomain.com mydomain.com;
root /home/me/mystaticwebsite/;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
listen 443 ssl; # managed by Certbot
# some ssl magic here
if ($scheme != "https") {
return 301 https://$host$uri;
} # managed by Certbot
}
server {
listen 80 default_server;
server_name _;
return 444;
}
# this last bit I commented out because it broke everything...
#server {
# listen 443 default_server;
#
# server_name _;
#
# return 444;
#}
编辑 2:检查error.log
(为什么我之前没有这样做……)我意识到最后一部分“破坏了一切”,因为no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking
。我最终复制了添加到其他域的ssl_certificate
和ssl_certificate_key
行certbot
。现在我在请求时仍然有证书警告anything.mydomain.com
,但至少如果我绕过它,我就无法访问,mypythonapp1
而这正是我真正想要的。
答案1
创建服务器块,通过您要服务的域名指定 server_name。接下来创建一个默认服务器来处理所有其他服务器。您不应该返回 404,而应该返回更合适的代码。
server {
# These can be in individual servers if you like
server_name anything.mydomain.com www.mydomain.com etc.mydomain.com
# add configuration
}
# This just prevents Nginx picking a random default server if it doesn't know which
# server block to send a request to
server {
listen 80 default_server;
server_name _;
return 444; # "Connection closed without response"
}
答案2
if ($host !~ ^(www.mydomain.com|mypythonapp1.mydomain.com|mypythonapp2.mydomain.com|mydomain.com|localhost)$ ) { return 404; }
如果你需要在用户请求任何与你的列表不匹配的域名时返回 404,你只需将此行添加到你的服务器块中