簡體   English   中英

如何配置nginx X-Forwarded-Port為原始請求端口

[英]How to configure nginx X-Forwarded-Port to be the originally request port

我在標准反向代理場景中使用 nginx,將所有請求傳遞到/auth到另一台主機,但是我正在嘗試使用非標准端口。

我的最終目標是將X-Forwarded-Port標頭設置為請求進入的端口。

這是我在 nginx.conf 中的位置塊:

 location /auth/ { proxy_pass http://otherhost:8090; 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_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port <VAR>; }

這個 nginx 運行在一個 docker 容器中,該容器被配置為將請求從 8085 轉發到容器中的 80,這樣 nginx 進程就可以監聽 80:

0.0.0.0:8085->80/tcp

當我點擊網址時:

http://localhost:8085/auth/

我正確重定向到http://otherhost:8090 ,但X-Forwarded-Port標頭丟失或錯誤。

在原始塊中有<VAR>的地方,我嘗試了以下操作:

  • $server_port - 這是 nginx 正在偵聽的端口 (80),而不是請求端口。

  • $pass_port - 在我的設置中似乎為空,因此 nginx 刪除了標頭。

  • $http_port - 這是每個請求的隨機端口。

  • $remote_port - 這是每個請求的隨機端口。

可以在部署時將我的配置更改為硬編碼到傳入請求的已知端口,但理想情況下,我將能夠更改前端端口,而無需對 nginx 配置進行任何更改。

我已經搜索了 nginx 變量列表,但找不到類似$request_port 有什么方法可以實現我的意圖嗎?

我發現的唯一解決方法是使用map規則從http_host變量獲取端口,例如

    map $http_host $port {
      default 80;
      "~^[^\:]+:(?<p>\d+)$" $p;
    }

這是編寫 Nginx conf 的一個粗略想法,但我相信這可以幫助您重定向

server {    
    listen 80;  
    server_name host.docker.internal;   

    # By default land on localhost:80 to root so in root we copied UI build to the ngnix html dir.
    # have a look to docker-compose uiapp service.
    location / {    
            root   /usr/share/nginx/html;   
            index  index.html index.htm;    
    }   

   # after location add filter, from which every endpoint starts with or comes in endpoint 
   # so that ngnix can capture the URL and reroute it.
   # like /backend/getUserInfo/<UserId> 
   # In above example /backend is that filter which will be captured by Ngnix and reroute the flow.
    location /backend { 
        proxy_set_header X-Forwarded-Host $host;    
        proxy_set_header X-Forwarded-Server $host;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #proxy_pass http://<ContainerName>:<PortNumber>; 
        # In our case Container name is as we setup in docker-compose `beservice` and port 8080
        proxy_pass http://beservice:8080;   
    }   
}

有關更多詳細信息,您可以查看此項目

https://github.com/dupinder/NgnixDockerizedDevEnv

奇怪的是,這還沒有得到回答,但答案是

proxy_set_header X-Forwarded-Port $server_port;

在容器內部,您無法訪問外部配置。 並且 nginx 不支持在大多數配置塊中使用環境變量。

但是如果你使用poco,你可以在一個簡單的 env 文件中定義你的端口、路徑等。 這些定義也由 docker-compose 配置或 env 變量使用。 例如

你的配置文件

PROJECT_HOME=..
MAGIC_DOCKER_PORT=8085

poco.yml 文件(項目的主要配置,定義計划)

version: '3.0'
maintainer: "youremail@yourdomain.com"

environment:
  include: docker/conf/yourconfig.env

plan:
  live:
    description: "your plan to run live"
    docker-compose-file:
      - docker/dc-proxy.yml
      - docker/dc-other-service.yml
# you can define other plans to run local/dev env

並在 docker/dc-proxy.yml 撰寫文件(相關部分)中:

version: '3'
services:
  proxy:
    image: nginx:alpine
    env_file: conf/yourconfig.env
    ports:
      - ${MAGIC_DOCKER_PORT}:80
    command: /bin/sh -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" 

最后你的配置模板相關部分來自 /etc/nginx/conf.d/mysite.template

listen ${MAGIC_DOCKER_PORT};
...
  location /auth/ {
    ...
    proxy_set_header X-Forwarded-Port ${MAGIC_DOCKER_PORT};
    ...
  }

我使用以下文件夾結構來組織文件。 這不是強制性的,但對我來說很容易使用,因為我的每個項目結構都是相同的。

/
  docker                <- all of docker related files here
    conf                <- env files, service configs, etc
    scripts             <- shell scripts which used by containers
    dc-*.yml            <- separate all services into single compose files
  poco.yml              <- main config, "start here" point
  project-related-files <- separated by each service

解釋

在 .env 文件中定義鍵值對。 這被 poco 用於創建 docker-compose 文件,它用於在 nginx 容器中創建環境變量。 之后使用envsubst填寫nginx配置模板,最后啟動nginx服務

我用過這個:

map $http_x_forwarded_port $my_forwarded_port {
    default $remote_port;
    "~^(.*)$" $1;
}

所有標頭都在 nginx 中的變量中設置,以 http 為前綴。 即,如果標題中有 origin = domain.com,則可以使用 $http_origin 來獲取“domain.com”。 所以我的代碼將$my_forwarded_port設置$my_forwarded_port轉發端口(如果設置),否則設置為 $remote_port

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM