NGINX 强制使用 HTTPS,AWS Elastic Beanstalk 上的某些用户代理除外

NGINX 强制使用 HTTPS,AWS Elastic Beanstalk 上的某些用户代理除外

我有一个部分 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;
}

相关内容