27

我在标准反向代理场景中使用 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. 有什么方法可以实现我的意图吗?

4

5 回答 5

8

我发现的唯一解决方法是使用map规则从http_host变量中获取端口,例如

    map $http_host $port {
      default 80;
      "~^[^\:]+:(?<p>\d+)$" $p;
    }
于 2020-08-11T20:44:23.703 回答
6

这是编写 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

于 2020-08-18T09:02:53.487 回答
0

在容器内部,您无法访问外部配置。并且 nginx 不支持在大多数配置块中使用环境变量。

但是如果你使用poco,你可以在一个简单的 env 文件中定义你的端口、路径等。这些定义也被 docker-compose 配置或 env 变量使用。例如

yourconfig.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 服务

于 2020-08-12T09:02:02.723 回答
0

我用这个:

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

所有标头都设置在 nginx 中的变量中,以 http 为前缀。即,如果标题中有 origin = domain.com,则可以使用 $http_origin 获取“domain.com”。因此,如果已设置,我的代码将设置$my_forwarded_port为转发端口,否则设置为 $remote_port

于 2020-09-09T12:55:43.900 回答
-1

奇怪,这还没有回答,但答案是

proxy_set_header X-Forwarded-Port $server_port;
于 2020-06-07T14:50:17.400 回答