Nginx proxy_pass 在变量中定义目标时改变行为
回答问题
我正在使用 nginx 反向代理 AWS API Gateway 阶段。这很简单:
location /api {
proxy_pass https://xxxxxxxxxx.execute-api.eu-central-1.amazonaws.com:443/production;
proxy_ssl_server_name on;
}
但是,当xxxxxxxxxx.execute-api.eu-central-1.amazonaws.com的 DNS 条目发生更改时,这种方法将使 nginx 为上游提供陈旧的服务,因为它在启动时解析该条目。
在这篇文章之后:https://www.nginx.com/blog/dns-service-discovery-nginx-plus/我现在正在尝试在这样的变量中定义我的代理目标:
location /api {
set $apigateway xxxxxxxxxx.execute-api.eu-central-1.amazonaws.com/production;
proxy_pass https://$apigateway:443/;
proxy_ssl_server_name on;
}
这将使 API Gateway 以ForbiddenException: Forbidden响应将通过先前设置而不使用变量的请求。阅读本文档:https://aws.amazon.com/de/premiumsupport/knowledge-center/api-gateway-troubleshoot-403-forbidden/它告诉我这可能是 WAF 过滤我的请求(当 WAF 是未为该 API 启用)或者它可能是私有 API 的缺少主机头(当 API 是公共的时)。
我想我可能做错了这些事情:
1.设置变量的语法错误
- 使用该变量会使 nginx 向 API Gateway 发送不同的 headers,我需要手动干预。我确实尝试过设置一个
Host标头,但它没有任何区别。
使用的nginx版本是1.17.3
Answers
您在变量中嵌入了 URI/production,因此:443被标记在 URI 的末尾而不是主机名上。我不相信您需要:443,它是https的默认端口。
此外,当在 proxy_pass 中使用变量并且在指令中指定了 URI 时,它会按原样传递给服务器,替换原始请求 URI。详见本文档。
您应该使用rewrite...break更改 URI 并从proxy_pass语句中删除任何可选的 URI。
例如:
location /api {
set $apigateway xxxxxxxxxx.execute-api.eu-central-1.amazonaws.com;
rewrite ^/api(.*)$ /production$1 break;
proxy_pass https://$apigateway;
proxy_ssl_server_name on;
}
此外,您将需要在配置中的某处使用resolver语句。
更多推荐

所有评论(0)