我有一个 nginx 反向代理,它充当其他三个 Web 服务器的一对多(单个公共 IP)代理。
我已设置所有块以根据客户端提供的 URL 重定向到每个服务器。
如果客户端只是在浏览器中输入反向代理的 IP 地址而不是 URL,会发生什么情况?nginx 如何确定将流量发送到何处?
我刚刚尝试过,它似乎将流量发送到它转发流量到的最后一台服务器?
如何删除/拒绝与我的配置中的三个服务器块之一不匹配的流量(即使用 IP 而不是 URL 的流量)?
更新:对于我的配置,这是 sites-enabled 中唯一的 conf 文件:
######## Server1 ########
server {
if ($host = server1.domain.com) {
return 301 https://$host$request_uri;
}
listen 80;
server_name server1.domain.com;
return 404;
}
server {
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/server1.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/server1.domain.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
server_name server1.domain.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://192.168.20.2:443;
}
location ^~ /wp-login.php {
satisfy any;
allow 172.20.5.2;
deny all;
proxy_pass https://192.168.20.2:443;
}
}
######## Server2 ########
server {
if ($host = server2.domain.com) {
return 301 https://$host$request_uri;
}
listen 80;
server_name server2.domain.com;
return 404;
}
server {
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/server2.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/server2.domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name server2.domain.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://192.168.20.3:443;
}
}
######## Server3 ########
server {
if ($host = server3.domain.com) {
return 301 https://$host$request_uri;
}
listen 80;
server_name server3.domain.com;
return 404;
}
server {
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/server3.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/server3.domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name server3.domain.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass https://192.168.20.4:443;
}
}
Nginx 反向代理 IP 为 192.168.20.6
因此,我看到的情况是,如果我在浏览器中仅输入 IP,NGINX 似乎会转到我的配置文件中的第一个服务器块,该服务器块通过以下链接进行跟踪:https://nginx.org/en/docs/http/request_processing.html
在我的情况下,它确实尝试加载 server1,但由于网站内容的提供基于 URL,因此它会破坏我的三个 Web 服务器的某些功能。
查看上面的链接,我发现我可以在一开始就使用这样的块来阻止仅 IP 请求?
server {
listen 80;
listen 443;
server_name "";
return 444;
}
答案1
“默认服务器”
有时您不希望访问者通过您的 IP 地址访问服务,至少对我来说,最有效的方法是使用 Nginx 的 default_server 禁用直接 IP 访问。
文件内容/etc/nginx/sites-enabled/default_server.conf是;
listen 192.168.0.100:80 default_server;
listen 192.168.0.100:443 ssl default_server;
server_name ""; ## see update edit below
access_log off;
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;
return 444;
## If you'd prefer to redirect them to your actual site un-comment below.
# return 301 https://example.com$request_uri;
}
重新加载 Nginx,直接通过 IP 尝试访问的访问者将被拒绝。
访问者不应该能够直接进入您的后端服务器。Nginx 应该是唯一面向公众的 http 服务器。
黑客通常会直接访问您的 IP - 他们是坏人!
更新 编辑
我刚刚注意到上面的 conf 示例的最后一行是错误的。要重定向到 URL,您需要包含“return 301 https://example.com$request_uri;”
在我的回答中,我没有包含“return 301”。这是我的打字错误。
另外,我错误地设置了“server_name _;”。根据 Nginx 文档,正确的方法是 'server_name "";'