我有一个部分 NGINX 配置文件,该文件会被 AWS Elastic Beanstalk 自动拉入主 NGINX 配置文件中。我有两个正在运行的实例,一个是运行 PHP 的 EC2 Web 服务器,另一个是 SQS 工作器。
我已经设置了我的配置文件以强制使用 HTTPS:
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
return 301 https://$host$request_uri;
}
这对于强制使用 HTTPS 非常有效,但我遇到了两个问题:ELB 健康监视器由于 301(预期为 200)而失败,并且 SQS 队列也由于返回 301 而失败——该队列由配置的 cron 作业的 POST 触发,似乎不适用于 301 重定向:
version: 1
cron:
- name: "schedule"
url: "/worker/schedule"
schedule: "* * * * *"
这是使用一套它监听对该 URL 的 POST 请求,然后启动作业。
为了解决这些问题,我尝试检查适当的标题并关闭重定向:
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
set $redirect_to_https 0;
if ($http_x_forwarded_proto != 'https') {
set $redirect_to_https 1;
}
if ($http_user_agent ~* '^ELB-HealthChecker\/.*$') {
access_log off;
set $redirect_to_https 0;
}
if ($http_user_agent ~* '^aws-sqsd\/.*$') {
set $redirect_to_https 0;
}
if ($redirect_to_https = 1) {
return 301 https://$host$request_uri;
}
}
这对 ELB 健康检查 (200) 有效,但 SQS 工作程序仍然失败,现在出现 404。
在 SQS 工作器上唯一能正常工作的配置是精简版(我现在正在手动将其专门部署到工作器上):
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
以下是使用上述配置成功发送 POST 请求的屏幕截图:
所以问题是,如何设置我的配置文件以忽略 ELB 运行状况检查和 SQS 队列的 HTTPS 301 重定向,而无需部署单独的 NGINX 配置文件?
答案1
这是一个典型的例子“If is evil” NGINX 场景有一整页专门用于解释在位置块中使用 if 指令为何会产生问题/导致完全出乎意料的结果。
我建议使用 NGINX地图用于 UA 路由。或者,如果您必须使用if
内部位置,至少将其替换return 301
为,rewrite
因为后者在内部位置块中更稳定。祝你好运!
答案2
可以map
按如下方式使用:
map $http_x_forwarded_proto $proto {
default 1;
"~^https$" 0;
}
map $http_user_agent $agent {
default 1;
"~*^ELB-HealthChecker\/.*$" 0;
"~*^aws-sqsd\/.*$" 0;
}
http
地图需要在配置中按级别定义。
然后,在 中location
,我们将会得到:
if ($proto$agent = "11") {
return 301 https://$host$request_uri permanent;
}