【问题标题】:How to forward request from one NGINX to another but keeping the domain of the first NGINX如何将请求从一个 NGINX 转发到另一个,但保留第一个 NGINX 的域
【发布时间】:2021-01-07 12:55:13
【问题描述】:

我有一个由我的组织维护的子域 (foo.domain.com),我无法控制该子域。 该组织将该域配置为指向 Route 53 服务,然后我创建了一个策略,将请求发送到 ALB,然后最终将其发送到运行 NGINX 的 EC2。

NGINX 将负责对我在不同 EC2 实例中运行的许多其他服务进行 URL 重写。

我想要的是,例如:

  1. 请求被发送到 foo.domain.com/service1

  2. 转到 Route53,然后转到 ALB,然后转到运行 NGINX 的 EC2

  3. 在 NGIX 中,我有以下配置

...

location = /service1/
{
    proxy_redirect              off;
    proxy_read_timeout          1m;
    proxy_connect_timeout       1m;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_pass https://public_ip_of_service1_ec2_instance$request_uri;
}
  1. 此请求发送到运行 service1 的 EC2 实例,这是另一个运行 node.js 应用程序的 NGINX 代理(npm build 有点像)

NGINX service1 conf 文件为:

server {
        listen 443 ssl;
        listen [::]:443 ssl;
        include snippets/self-signed.conf;
        server_name public_ip_of_service1_ec2_instance;
        root   /app; #this is where the static files are hosted

        location ~* \.html?$ {
            expires -1;
            add_header Pragma "no-cache";
            add_header Cache-Control "no-store, must-revalidate";
        }

        location / {
            add_header Content-Security-Policy "default-src 'self' 'unsafe-inline';";
            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
            add_header X-Frame-Options "SAMEORIGIN";
            index  index.html;
            try_files $uri $uri/ /index.html;
            # kill cache
            # expires -1;
        }

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }

如果我点击 service1 的 NGINX URL,它可以正常工作,但问题是当我从第 3 步调用 NGINX 代理时。

当我在浏览器上点击 URL foo.domain.com/service1 时,我看到了这个:

基本上,它说 foo.domain.com/js/chunk....js 找不到。这是正确的,因为该文件正在运行该 node.js 应用程序的 EC2 中提供(也就是说,它可以在 http://public_ip_of_service1_ec2_instance/js/chunk....js 找到)

为了能够始终为我的用户保留域 foo.domain.com/service1 并且永远看不到public_ip_of_service1_ec2_instance,我缺少什么配置

谢谢

编辑 1 这里报告的问题似乎和我的一模一样:https://serverfault.com/questions/805836/reverse-proxy-application-and-its-static-files-with-nginx

我遵循了那里的建议以及@anemyte 的建议,但它不起作用。 看起来 Proxy1 正在尝试提供托管在 Proxy2 中的静态文件,您可以在此处看到:

proxy    | 2021/01/04 10:16:22 [error] 29#29: *4 open() "/etc/nginx/html/js/app.53272292.js" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /js/app.53272292.js HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy    | ( - - ) 172.19.0.1 - - [04/Jan/2021:10:16:22 +0000] "GET /css/app.0988b263.css HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy    | ( - - ) 172.19.0.1 - - [04/Jan/2021:10:16:22 +0000] "GET /css/chunk-vendors.e78a06e5.css HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy    | 2021/01/04 10:16:22 [error] 29#29: *4 open() "/etc/nginx/html/css/app.0988b263.css" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /css/app.0988b263.css HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy    | 2021/01/04 10:16:22 [error] 29#29: *6 open() "/etc/nginx/html/css/chunk-vendors.e78a06e5.css" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /css/chunk-vendors.e78a06e5.css HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy    | 2021/01/04 10:16:23 [error] 29#29: *6 open() "/etc/nginx/html/js/chunk-vendors.7b27d7ff.js" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /js/chunk-vendors.7b27d7ff.js HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy    | ( - - ) 172.19.0.1 - - [04/Jan/2021:10:16:23 +0000] "GET /js/chunk-vendors.7b27d7ff.js HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy    | 2021/01/04 10:16:23 [error] 29#29: *6 open() "/etc/nginx/html/js/app.53272292.js" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /js/app.53272292.js HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy    | ( - - ) 172.19.0.1 - - [04/Jan/2021:10:16:23 +0000] "GET /js/app.53272292.js HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"

我的代理 1 conf 文件现在看起来像这样:

worker_processes 1;

events { worker_connections 1024; }

http {
    log_format  main   '( $proxy_host $upstream_addr ) $remote_addr - $remote_user [$time_local] "$request" '
                       '$status $body_bytes_sent "$http_referer" '
                       '"$http_user_agent" "$http_x_forwarded_for"';
    rewrite_log on;
    access_log         /var/log/nginx/access.log main;
         server {
            listen 80;
            server_name apacbsa.com;
            
 
            location /auspost/ {
                # proxy_redirect              off;
                # proxy_read_timeout          1m;
                # proxy_connect_timeout       1m;
                proxy_set_header            Host $host;
                proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for; 
                proxy_set_header            X-Forwarded-Proto $scheme;
                # proxy_buffering off;
                #proxy_set_header X-Real-IP $remote_addr;
                # proxy_set_header   X-Forwarded-Host $server_name;
                proxy_pass https://192.168.1.113/;
                
            }
        }
}

EDIT2

仍然没有运气。这是我在 NGINX1 日志中看到的:

proxy | ( 192.168.1.113 192.168.1.113:443 ) 172.19.0.1 - - [05/Jan/2021:00:00:37 +0000] "GET /auspost/ HTTP/1.1" 200 2111 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:37 +0000] "GET /css/chunk-vendors.e78a06e5.css HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | 2021/01/05 00:00:37 [error] 21#21: *9 open() "/etc/nginx/html/css/chunk-vendors.e78a06e5.css" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /css/chunk-vendors.e78a06e5.css HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:37 +0000] "GET /js/app.54337cb4.js HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:37 +0000] "GET /css/app.0988b263.css HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | 2021/01/05 00:00:37 [error] 21#21: *12 open() "/etc/nginx/html/js/app.54337cb4.js" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /js/app.54337cb4.js HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | 2021/01/05 00:00:37 [error] 21#21: *11 open() "/etc/nginx/html/css/app.0988b263.css" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /css/app.0988b263.css HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | 2021/01/05 00:00:37 [error] 21#21: *13 open() "/etc/nginx/html/js/chunk-vendors.7b27d7ff.js" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /js/chunk-vendors.7b27d7ff.js HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:37 +0000] "GET /js/chunk-vendors.7b27d7ff.js HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:38 +0000] "GET /css/app.0988b263.css HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:38 +0000] "GET /css/chunk-vendors.e78a06e5.css HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | 2021/01/05 00:00:38 [error] 21#21: *12 open() "/etc/nginx/html/css/app.0988b263.css" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /css/app.0988b263.css HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | 2021/01/05 00:00:38 [error] 21#21: *11 open() "/etc/nginx/html/css/chunk-vendors.e78a06e5.css" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /css/chunk-vendors.e78a06e5.css HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:39 +0000] "GET /js/chunk-vendors.7b27d7ff.js HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"
proxy | 2021/01/05 00:00:39 [error] 21#21: *13 open() "/etc/nginx/html/js/chunk-vendors.7b27d7ff.js" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /js/chunk-vendors.7b27d7ff.js HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | 2021/01/05 00:00:39 [error] 21#21: *11 open() "/etc/nginx/html/js/app.54337cb4.js" failed (2: No such file or directory), client: 172.19.0.1, server: apacbsa.com, request: "GET /js/app.54337cb4.js HTTP/1.1", host: "localhost", referrer: "http://localhost/auspost/"
proxy | ( - - ) 172.19.0.1 - - [05/Jan/2021:00:00:39 +0000] "GET /js/app.54337cb4.js HTTP/1.1" 404 153 "http://localhost/auspost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "-"

这就是我在 NGINX2(服务静态文件)日志中看到的内容(仅 1 行):

frontend | 172.21.0.1 - - [05/Jan/2021:11:04:17 +1100] "GET / HTTP/1.0" 200 2111 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:80.0) Gecko/20100101 Firefox/80.0" "172.19.0.1"

这是 NGINX2 的完整 nginx 配置文件:

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include            /etc/nginx/mime.types;
    default_type       application/octet-stream;
    log_format  main   '$remote_addr - $remote_user [$time_local] "$request" '
                       '$status $body_bytes_sent "$http_referer" '
                       '"$http_user_agent" "$http_x_forwarded_for"';
    access_log         /var/log/nginx/access.log  main;
    sendfile           on;

    keepalive_timeout 10m;
    proxy_connect_timeout  600s;
    proxy_send_timeout  600s;
    proxy_read_timeout  600s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;
    resolver_timeout 600s;

    # for DDOS protection - 3 requests per second
    limit_req_zone $binary_remote_addr zone=one:10m rate=3r/s;
    # limiting the number of connections one client can make
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    server {
        listen 80;
        listen [::]:80;
        server_name apacbsa.com;
        return 301 https://$server_name$request_uri;
    }

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        include snippets/self-signed.conf;
        server_name apacbsa.com;
        root   /app;

        location ~* \.html?$ {
            expires -1;
            add_header Pragma "no-cache";
            add_header Cache-Control "no-store, must-revalidate";
        }

        location /auspost/ {
            add_header Content-Security-Policy "default-src 'self' 'unsafe-inline';";
            add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
            add_header X-Frame-Options "SAMEORIGIN";
            index  index.html;
            try_files $uri $uri/ /index.html;
            # kill cache
            # expires -1;
        }

        location /api {
                # limiting the number of api calls
                limit_req zone=one burst=2 nodelay;
                # only one connection per client to the api
                limit_conn addr 1;

                proxy_pass          https://backend:5001/api;
                proxy_redirect              off;
                proxy_connect_timeout       1m;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_cache_bypass $http_upgrade;
            }

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

一切都在 docker 容器中运行,但这不应该是我认为的问题。

所以我从我的 Mac 笔记本电脑上的浏览器发出请求,并且在那台笔记本电脑上我正在运行 NGINX1 代理。然后转发到我的运行 NGINX2 静态文件的 Windows 机器。

【问题讨论】:

  • 嗨。我有几个问题:1)您的应用程序正在寻找的静态文件的基本路径是什么?是 domain.com/service1/js/.... 还是 domain.com/js/....?
  • 2) 您共享的日志。你能清楚地标出它们属于哪个Nginx吗?如果可能的话,我可以看到两个 Nginx 的日志吗?
  • 嗨@ManishDash - 我分享的日志与 NGINX1 相关,该日志转发到为静态内容提供服务的 NGINX2。我将更新我的帖子以包含来自 NGINX2 的日志

标签: nginx amazon-ec2 url-rewriting


【解决方案1】:

当您声明这样的位置时:

location = /service1/

这意味着您想要精确的 URL 匹配。所以它只适用于foo.domain.com/service1/foo.domain.com/service1/something 不会匹配这个位置。查看您请求的 URL (/js/chunk) 这不是您想要的,因此请从该位置删除 =

location /service1/

接下来是server_name。您的第一个代理传递 Host 标头,NGINX 使用该标头来确定要使用的虚拟主机配置。 Host 标头值应该是 foo.domain.com 但你在第二个 NGINX 上的 server_namepublic_ip_of_service1_ec2_instance。虚拟主机是否是默认虚拟主机并不重要,但我在您的配置中没有看到。

您可以在public_ip_of_service1_ec2_instance 之后添加foo.domain.com,或者将其中一个替换为另一个。在这种情况下什么是最好的,你应该自己决定,如果你想了解更多关于服务器名称的信息,我建议你阅读这些很棒的文章:How nginx processes a requestServer names

UPD:关于丢失的静态文件。

您需要将 service1 应用程序的基本 URL 或基本路径从 / 更改为 /service1/。这与 NGINX 无关,除非您的应用程序仅由静态文件组成。

为什么会这样?好吧,您已经告诉first NGINX,您希望将所有以/service1/ 开头的URL 请求转发到service1。当客户端点击service1 时,页面会引用一些静态的,例如/js/chunk-vendors.7b27d7ff.js。客户端的浏览器向first NGINX 发出附加请求,要求提供/js/chunk-vendors.7b27d7ff.js。由于 URL 不是以 /service1/ 开头,NGINX 不会将请求转发到 /service1/ 并且它使用另一个配置来处理这个请求(/ 最有可能)。

如果您将 service1 处的所有绝对 URL 更改为以 /service1/ 开头,则问题应该会解决。一个危险的替代方法是从绝对链接中删除第一个斜线。这样,URL 将与 当前 位置相关,而不是网站根目录。在选择第二个选项之前请三思。

【讨论】:

  • 感谢您的回复。我尝试了你的建议,但不幸的是它不起作用。似乎 Proxy1 正在尝试将 Proxy2 中的所有静态内容作为proxy1/js/chunk... 提供服务)这个人有同样的问题serverfault.com/questions/805836/… 并且能够按照您的建议使用位置 /service1/ 进行修复,但我不确定为什么它不是为我工作。
  • 我无法将解释放入评论中,因此我已将其添加到答案的末尾。 @FelipeCaldas
  • 我明白你的意思@anemyte。我的提供静态内容的 NGINX2 确实只有“location / {”。我将在今天晚些时候对此进行测试并恢复。谢谢。
  • 我在 EDIT2 下的帖子中添加了更多信息,感谢您的支持。
  • 所以我猜问题出在我的 Node.js 应用程序的“路由”中,我的应用程序从 / 而不是 /auspost/ 开始。我将不得不测试的东西。我会尽快回复你。再次感谢
【解决方案2】:

我最近做了一些测试,结果如下:

在您的 nginx 代理配置中,删除以下行:

proxy_set_header 主机 $http_host;

这将导致您的最终配置 nginx 文件为:

location = /
{
    proxy_redirect              off;
    proxy_read_timeout          1m;
    proxy_connect_timeout       1m;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_pass https://public_ip_of_service1_ec2_instance;
}

【讨论】:

  • 很遗憾没有成功,感谢您的留言。我用更多信息更新了我的问题。谢谢
【解决方案3】:

你可以在第一个 nginx 服务器中配置类似的东西

server {
    listen 80;
    listen [::]:80;
    listen 443 http2 ssl;
    listen [::]:443 http2 ssl;

    server_name domain1;

    if ($request_method ~* OPTIONS|GET|HEAD) {
        return 301 https://domain2$request_uri;
    }

    location ~* api {
        proxy_pass https://domain2$request_uri;
    }
}

【讨论】:

    猜你喜欢
    • 2017-01-22
    • 2017-05-20
    • 2014-05-01
    • 2020-11-30
    • 1970-01-01
    • 2020-05-28
    • 2015-06-16
    • 1970-01-01
    • 2014-06-07
    相关资源
    最近更新 更多