如何使用弹性 beantalk 加密负载均衡器和 Web 服务器之间的流量

Posted

技术标签:

【中文标题】如何使用弹性 beantalk 加密负载均衡器和 Web 服务器之间的流量【英文标题】:How to encrypt traffic between the load balancer and web servers with elastic beanstalk 【发布时间】:2020-07-06 08:17:50 【问题描述】:

我想在 Elastic Beanstalk 环境中加密负载均衡器和 Web 服务器之间的流量。亚马逊在这里有一个指南:https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-endtoend.html,但它涉及为您的服务器手动生成证书。是否有全自动替代方案?

【问题讨论】:

【参考方案1】:

如果您让服务器生成自己的自签名证书作为部署容器命令的一部分,那么每次部署和启动新服务器时,每台服务器都会获得更新的证书。

我为此找到的最佳命令如下,它创建的证书有效期为 10 年:

sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/pki/tls/certs/server.key -out /etc/pki/tls/certs/server.crt -days 3650 -nodes -subj "/CN=example.com"

使用这种方法,只要您每十年至少部署一次(包括升级您的 EB 容器版本),您的服务器就会保持正常运行。

这也大大简化了设置。现在您需要做的就是:

    将配置文件添加到您的弹性 beanstalk 项目,该项目生成自签名证书并将 HTTPS 设置添加到 Web 服务器。 让 Web 服务器安全组接受来自负载平衡器安全组的端口 443 连接。 将负载平衡器设置为将流量从端口 443 转发到端口 443。

以下是用于 python 的完整 HTTPS 弹性 beanstalk 配置文件的示例。这是对AWS's suggested config file for python 的轻微修改。我已将生成证书命令添加到容器命令的开头,并删除了 /etc/pki/tls/certs/server.crt/etc/pki/tls/certs/server.key 的两个文件语句,因为它们现在是自动生成的。 AWS examples for other languages can be found here.

AWS Linux 2,基于 Apache 的部署

将以下内容放入.ebextensions/ssl.config

container_commands:
  01_create_certs:
    command: |
      sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/pki/tls/certs/server.key -out /etc/pki/tls/certs/server.crt -days 3650 -nodes -subj "/CN=example.com"
  02_restart_httpd:
    command: |
      # Condition on whether httpd is running for compatibility with EB worker environments
      sudo systemctl status httpd && sudo systemctl restart httpd || echo "httpd not running"
  03_wait_for_httpd_restart:
    command: "sleep 3"

将以下内容放入.platform/httpd/conf.d/ssl.conf

Listen 443
<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile "/etc/pki/tls/certs/server.crt"
  SSLCertificateKeyFile "/etc/pki/tls/certs/server.key"
  # Limit requests to 100 MB
  LimitRequestBody 104857600

  <Proxy *>
    Require all granted
  </Proxy>
  ProxyPass / http://localhost:8000/ retry=0
  ProxyPassReverse / http://localhost:8000/
  ProxyPreserveHost on
</VirtualHost>

AWS Linux 1,基于 Apache 的部署

将以下内容放入.ebextensions/ssl.config

packages:
  yum:
    mod24_ssl : []
    
files:
  /etc/httpd/conf.d/ssl.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      LoadModule wsgi_module modules/mod_wsgi.so
      WSGIPythonHome /opt/python/run/baselinenv
      WSGISocketPrefix run/wsgi
      WSGIRestrictEmbedded On
      Listen 443
      <VirtualHost *:443>
        SSLEngine on
        SSLCertificateFile "/etc/pki/tls/certs/server.crt"
        SSLCertificateKeyFile "/etc/pki/tls/certs/server.key"
        
        Alias /static/ /opt/python/current/app/static/
        <Directory /opt/python/current/app/static>
        Order allow,deny
        Allow from all
        </Directory>
        
        WSGIScriptAlias / /opt/python/current/app/application.py
        
        <Directory /opt/python/current/app>
        Require all granted
        </Directory>
        
        WSGIDaemonProcess wsgi-ssl processes=1 threads=15 display-name=%GROUP \
          python-path=/opt/python/current/app \
          python-home=/opt/python/run/venv \
          home=/opt/python/current/app \
          user=wsgi \
          group=wsgi
        WSGIProcessGroup wsgi-ssl
        
      </VirtualHost>
      
container_commands:
  01_create_certs:
    command: |
      sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/pki/tls/certs/server.key -out /etc/pki/tls/certs/server.crt -days 3650 -nodes -subj "/CN=example.com"
  02_kill_httpd:
    command: "sudo restart supervisord"
  03_wait_for_httpd_death:
    command: "sleep 3"

【讨论】:

【参考方案2】:

如果您在基于 Apache 的 AWS Linux 2 中为 Classic Load Balancer 执行此操作,而不是针对更出色、更新的 Application Load Balancer,除了adding the config files listed here,您还需要执行以下步骤:

    将以下内容放入.platform/httpd/conf.d/keepalive.conf
# Enable TCP keepalive
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 300
<IfModule mod_reqtimeout.c>
 RequestReadTimeout header=300 body=300
</IfModule>
    确保您的 ELB 配置为通过 HTTP 将 HTTP 流量路由到端口 80,通过 HTTPS 将 HTTPS 流量路由到端口 443。

这将防止 ELB 预连接被错误地终止,如果不加以检查将污染您的健康检查数据(有关此内容的更多信息,请参阅 Mysterious Http 408 errors in AWS elasticbeanstalk-access_log)。在我的测试中,不执行此步骤会导致自动运行状况检查的误报率为 25%。

您可能还希望考虑将 SSL 重写文件添加到配置中,以将所有传入的不安全流量重新路由到安全端口,例如.platform/httpd/conf.d/ssl_rewrite.conf 内容:

RewriteEngine On
<If "-n '%HTTP:X-Forwarded-Proto' && %HTTP:X-Forwarded-Proto != 'https'">
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [R,L]
</If>

【讨论】:

以上是关于如何使用弹性 beantalk 加密负载均衡器和 Web 服务器之间的流量的主要内容,如果未能解决你的问题,请参考以下文章

如何在弹性 beantalk 负载均衡器中设置自定义标头相关规则

我们可以将两种不同类型的 AWS EC2 实例与弹性 beantalk 负载均衡器一起使用吗

在弹性 beantalk 和 kubernetes 之间分配的应用程序负载均衡器

在弹性 beantalk 环境中负载测试并发用户

aws 弹性负载均衡器可以将端口 443 转发到端口 443 以获取弹性 beantalk 实例吗?

如何使用 https 在弹性 beantalk 中配置单个 ec2 实例