Elastic Beanstalk配置HTTPS后,接下来就需要配置HTTP请求redirect到HTTPS。
以前都是直接在application层面做redirect的。这次调查了一下在passenger层面来进行redirect的做法,记录在此。

Ruby平台基本信息:

  • EB平台: Passenger with Ruby 2.3 running on 64bit Amazon Linux/2.9.3
    • Ruby 2.3
    • Passenger模式
  • 前端使用ALB进行负载均衡,和后端EC2之间端口对应关系:
    • ALB:443 -> EC2:80 (在ALB侧进行HTTPS terminate)
    • ALB:80 -> EC2:80

修改方法

使用.ebextension直接修改passenger的配置文件/opt/elasticbeanstalk/support/conf/nginx_config.erb.
修改要点:

  1. 动态请求http_x_forwarded_proto 不是https的,redirect为https
  2. 静态文件请求的http_x_forwarded_proto不是https的,redirect为https
  3. 来自ELB health check的请求还是直接返回请求,而不用redirect为https

主要修改点如下:

  • 添加location /节点,判断http_x_forwarded_proto是否为https

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    set $redirect 0;
    location / {
    if ($http_x_forwarded_proto != "https") {
    set $redirect 1;
    }
    if ($http_user_agent ~* "ELB-HealthChecker") {
    set $redirect 0;
    }
    if ($redirect = 1) {
    return 301 https://$host$request_uri;
    }
    passenger_enabled on;
    }
  • 修改静态文件location,添加http_x_forwarded_proto的判断。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # Rails asset pipeline support.
    # location ~ "^/assets/.+-[0-9a-f]{32}\..+" {
    location ~ "^/assets/.+-([0-9a-f]{32}|[0-9a-f]{64})\..+" {
    if ($http_x_forwarded_proto != "https") {
    set $redirect 1;
    }
    if ($http_user_agent ~* "ELB-HealthChecker") {
    set $redirect 0;
    }
    if ($redirect = 1) {
    return 301 https://$host$request_uri;
    }
    error_page 490 = @static_asset;
    error_page 491 = @dynamic_request;
    recursive_error_pages on;
    if (-f $request_filename) {
    return 490;
    }
    if (!-f $request_filename) {
    return 491;
    }
    }

完整配置参见Github

Reference

留言