【问题标题】:ELB to backend server using HTTPS with self-signed certificate使用带有自签名证书的 HTTPS 到后端服务器的 ELB
【发布时间】:2019-07-26 14:33:42
【问题描述】:

我希望设置一个使用 HTTPS 与后端服务器通信的 ELB。我正在尝试使用单个后端服务器设置概念证明,但似乎无法让 ELB 与服务器通信。我几乎可以肯定这是一个证书问题,因为任何没有 SSL 的设置都可以完美运行。

我该如何设置?我从多个答案和博客文章中尝试了各种建议,但没有运气。

我现在正在做的是使用以下命令(来自AWS ELB -> Backend Server over HTTPS with Self-Signed Certificate)设置自签名证书:

$ openssl genrsa \
  -out /path/to/ssl.key 2048
$ openssl req \
  -sha256 \
  -new \
  -key /path/to/ssl.key \
  -out /path/to/ssl.csr
$ openssl x509 \
  -req \
  -days 365 \
  -in /path/to/ssl.csr \
  -signkey /path/to/ssl.key \
  -out /path/to/ssl.crt

我尝试了多个域名,在签名时,我可以使用它们进行 curl:

curl https://[Public DNS, or private DNS or IP used to create the SSL crt]/status --cacert /path/to/ssl.crt

我应该在这里使用域/IP/DNS 条目吗?我觉得 curl 至少有效。

目前我的 nginx 配置(在启用站点的文件中)如下所示:

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    ssl_certificate     /path/to/ssl.crt;
    ssl_certificate_key /path/to/ssl.key;

    server_name <dummy value of "_" or name used to make SSL certs>;
    client_max_body_size 20M;
    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass         http://127.0.0.1:8000/;
        proxy_redirect     off;

        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}

这适用于上面的 curl 命令。

我尝试过经典和应用负载平衡器。对于经典,我尝试添加 ssl.crt 内容 - 我没有看到与应用程序负载均衡器类似的选项,但我想尽可能使用它们,因为它们可以非常轻松地转发 HTTP->HTTPS。无论哪种方式,经典负载均衡器或应用程序负载均衡器都不会与服务器通信。

对缺少的内容有什么建议吗?或者如何确定缺少什么?

【问题讨论】:

    标签: amazon-web-services ssl aws-elb


    【解决方案1】:

    这很接近,只是少了几个小步骤。我使用 ALB ELB 进行了这项工作。

    首先,我使用了类似于此处描述的脚本:https://myopswork.com/how-to-do-end-to-end-encryption-of-data-in-transit-b-w-aws-alb-and-ec2-3b7fd917cddd

    #!/bin/bash
    
    DIR=$(dirname $0)
    
    domain=$(uname -n)
    echo "Generating SSL for $domain"
    commonname="$domain"
    country="US"
    state="California"
    locality="LA"
    organization="My Inc."
    organizationalunit="Org"
    email="my@email.com"
    
    # Optional
    password=dummypassword
    
    echo "Generating key request for $domain"
    
    mkdir -p /etc/ssl/private
    chmod 700 /etc/ssl/private
    mkdir -p /etc/ssl/certs
    
    # Generate a key
    openssl genrsa -des3 -passout pass:$password -out /etc/ssl/private/$domain.key 2048 -noout
    
    # Remove passphrase from the key. Comment the line out to keep the passphrase
    echo "Removing passphrase from key"
    openssl rsa -in /etc/ssl/private/$domain.key -passin pass:$password -out /etc/ssl/private/$domain.key
    
    # Create the request
    echo "Creating CSR"
    openssl req -new -key /etc/ssl/private/$domain.key -out /etc/ssl/private/$domain.csr -passin pass:$password \
        -subj "/C=$country/ST=$state/L=$locality/O=$organization/OU=$organizationalunit/CN=$commonname/emailAddress=$email"
    
    # Create the cert
    openssl x509 -req -days 365 -in /etc/ssl/private/$domain.csr -signkey /etc/ssl/private/$domain.key -out /etc/ssl/certs/$domain.crt
    
    # Setup nginx config
    sed "s/{{hostname}}/${domain}/" < $DIR/template.conf > /etc/nginx/sites-available/site.conf
    ln -sf /etc/nginx/sites-available/site.conf /etc/nginx/sites-enabled/site.conf
    

    模板看起来像这样:

    server {
        # listen 80 #uncomment to also listen on port 80 - useful for debugging
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name {{hostname}};
    
        ssl_certificate /etc/ssl/certs/{{hostname}}.crt;
        ssl_certificate_key /etc/ssl/private/{{hostname}}.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
        add_header X-Frame-Options sameorigin;
        add_header X-Content-Type-Options nosniff;
    
        location / {
            ...
        }
    }
    

    域名类似于ip-172-10-11-12

    为了调试所有内容,我运行了以下 类似 的内容 - 这是从内存中提取的,因此它可能包含详细信息。我首先确保我可以通过点击 nginx 在本地 curl 服务器:

    curl https://ip-172-10-11-12/healthcheck --cacert /etc/ssl/certs/ip-172-10-11-12.crt
    

    然后我得到了 ELB 地址,并确保我可以对抗它。我必须使用可以访问 ELB 机器的机器。请注意,由于安全规则,ELB 不可 pinagable,但可 curl。我相信我测试了这两种方式。首先,我试过了:

    curl https://elb-address/healthcheck --insecure
    

    然后我将 ip-172-10-11-12 添加到 /etc/hosts 文件中并尝试:

    curl https://ip-172-10-11-12/healthcheck --cacert /cert/file/copied/onto/machine
    

    一旦我开始工作,ALB ELB 就开始工作了。在最后一次调用之前,我必须检查防火墙规则、AWS 安全组等。但是当它确实工作时,ELB 开始看到服务器。

    我在调试时也有一个最终见解:如果 ELB 是从公共 Internet 访问的,则 ELB 必须只有公共子网,并且公共子网应该与目标机器位于同一可用区

    【讨论】:

      猜你喜欢
      • 2016-07-10
      • 1970-01-01
      • 2016-11-08
      • 1970-01-01
      • 2016-07-17
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多