我有两台服务器。
第一台服务器是我的前端应用程序,它使用 nginx 作为反向代理。第二台服务器是我的后端应用程序,它使用 docker。在 Docker 内部,我使用 nginx 容器作为反向代理。
我想将我的后端应用程序限制到我的前端和我自己的 IP,因为我的后端有管理页面。
我尝试了很多方法,但没有成功。
前端
upstream frontend {
server 127.0.0.1:4000;
}
server {
listen 80;
server_name frontend.com;
set_real_ip_from frontend_server_ip;
real_ip_header X-Real-IP;
real_ip_recursive on;
location / {
proxy_pass http://frontend;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
后端
upstream backend {
ip_hash;
server web:8000;
}
server {
listen 80;
server_name api.backend.com;
location / {
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
server {
listen 443 ssl;
server_name api.backend.com;
location / {
# it does not work
#allow front-end-ip;
#deny all;
##end test
if ($host !~* frontend_url) { #It does not work
return 403;
}
proxy_pass http://backend/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
正如您所看到的,我尝试通过域或 IP 进行限制,但它阻止了所有请求,但我不知道为什么。
更新
假设我们有两个应用程序(前端和后端),前端使用 rest API 与后端通信。因此前端服务器和后端服务器是独立的,我的前端使用 nginx,后端使用另一个 nginx。我的后端有管理页面。现在我想将我的后端应用程序限制为我的前端应用程序。
allow frontend_ip;
deny all;
如果我在后端 nginx 中使用上述代码,它会阻止所有请求,我可以在 nginx 日志中看到。
nginx_1 | frontend_ip-- -- - - [18/Feb/2020:17:41:37 +0000] "api.backend.com" "GET /articles/about/ HTTP/1.1" 200 2 "-" "Mozilla/5.0 (Linux x64) node.js/10.17.0 v8/6.8.275.32-node.54" 0.012
nginx_1 | frontend_ip-- -- - - [18/Feb/2020:17:41:37 +0000] "api.backend.com" "GET /articles/about/ HTTP/1.1" 200 2 "-" "Mozilla/5.0 (Linux x64) node.js/10.17.0 v8/6.8.275.32-node.54" 0.018
nginx_1 | 2020/02/18 17:41:40 [error] 550#550: *13449 access forbidden by rule, client: 5.51.0.220, server: api.backend.com, request: "GET /articles/about/ HTTP/1.1", host: "api.backend.com", referrer: "https://frontend_url.com/about"
nginx_1 | 5.51.0.220-- -- - - [18/Feb/2020:17:41:40 +0000] "api.backend.com" "GET /articles/about/ HTTP/1.1" 403 555 "https://frontend_url.com/about" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" 0.000
nginx_1 | 2020/02/18 17:41:40 [error] 550#550: *13449 access forbidden by rule, client: 5.51.0.220, server: api.backend.com, request: "GET /articles/about/ HTTP/1.1", host: "api.backend.com", referrer: "https://frontend_url.com/about"
nginx_1 | 5.51.0.220-- -- - - [18/Feb/2020:17:41:40 +0000] "api.backend.com" "GET /articles/about/ HTTP/1.1" 403 555 "https://frontend_url.com/about" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" 0.000
答案1
正如您添加的日志行所示,前端的服务器部分并不是唯一需要访问后端的部分。网页上的客户端 JavaScript 也会访问后端。
在这种情况下,您应该location
为您的管理页面创建一个单独的块(假设它在https//api.example.com/admin
),并拒绝任何人访问,但您自己除外:
location /admin/ {
allow your_ip;
deny all;
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}