支持ELB的双向TLS / HTTPS

时间:2014-01-20 22:56:42

标签: ssl amazon-web-services amazon-elb authentication two-way

使用Amazon Elastic Load Balancing的单向(或服务器端)TLS / HTTPS为well documented

文档中没有明确支持双向(或客户端)TLS / HTTPS。

假设ELB正在终止TLS / HTTPS连接:

  1. ELB是否支持client authenticated HTTPS连接?
  2. 如果是这样,ELB服务的服务器是否收到X-Forwarded-*标头以识别ELB验证的客户端?
  3. ELB确实支持TCP转发,因此EC2托管服务器可以建立双向TLS / HTTPS连接,但在这种情况下,我感兴趣的是ELB终止TLS / HTTPS连接并识别客户端。

3 个答案:

答案 0 :(得分:14)

我不知道它是如何做的,在双端HTTPS模式下,因为ELB正在建立到后端服务器的第二个TCP连接,并且在内部它正在解密/加密到客户端和服务器的有效负载...所以服务器不会直接看到客户端证书,并且除了-For,-Proto和-Port之外没有记录的X-Forwarded- *头文件。

另一方面,当ELB以TCP模式运行时,SSL协商直接在客户端和服务器之间进行,ELB盲目地将流绑定在一起。如果服务器支持PROXY protocol,您可以enable that functionality in the ELB,以便您可以在服务器上识别客户端的原始IP和端口,以及直接识别客户端证书,因为客户端将直接与您协商...虽然这意味着你不再将SSL卸载到ELB,这可能是你想要做的事情的一部分。


更新:

看起来没有办法做你想做的一切 - 卸载SSL并识别客户端证书 - 仅使用ELB。以下信息是“为了它的价值而提供的。”

显然HAProxy有support for client-side certificates in version 1.5,并在X-标头中传递证书信息。由于HAProxy还通过配置支持PROXY协议(类似于tcp-request connection expect-proxy)...所以似乎可以想象你可以在TCP模式ELB后面使用HAProxy,HAProxy终止SSL连接并将两者客户端IP /端口信息从ELB(通过PROXY协议)客户端证书信息转发到应用服务器...从而允许您仍然保持SSL卸载。

我之所以提到这一点,是因为它似乎是一个互补的解决方案,或许比任何一个平台都要完整,而且,至少在1.4版本中,两个产品完美配合 - 我正在成功地为所有人使用HAProxy 1.4背后的ELB在我最大的网络平台(在我的情况下,ELB卸载SSL - 没有客户端证书)的请求,尽管级联负载平衡器明显冗余,它似乎是一个坚实的组合。我喜欢ELB是大型互联网上唯一存在的东西,尽管我没有理由认为直接暴露的HAProxy本身就存在问题。在我的应用程序中,ELB可以平衡A / Z中的HAProxies(我原本打算自动扩展),但即使在我们忙碌的季节,CPU利用率仍然很低,我从来没有超过一个可用区,我永远不会丢失一个,但是......)除了给我之外,它还可以在将流量传送到实际平台之前进行一些过滤,转发和删除标题一些记录,重写和流量分割控制,我自己没有ELB。

答案 1 :(得分:3)

如果您的后端本身可以支持客户端经过身份验证的HTTPS连接,您可以在端口443上使用ELB作为TCP,在后端侦听的端口上使用TCP。这将使ELB只是将未加密的请求直接重新发送到您的后端。此配置也不需要将SSL证书安装到负载均衡器。

更新:使用此解决方案x-forwarded- *标头未设置。

答案 2 :(得分:0)

您可以在Elastic Beanstalk上切换到单个实例,并使用ebextensions上传证书并为相互TLS配置nginx。

实施例

.ebextensions/setup.config

files:
  "/etc/nginx/conf.d/00_elastic_beanstalk_ssl.conf":
    mode: "000755"
    owner: root
    group: root
    content: |
      server {
        listen 443;
        server_name example.com;

        ssl on;
        ssl_certificate /etc/nginx/conf.d/server.crt;
        ssl_certificate_key /etc/nginx/conf.d/server.key;
        ssl_client_certificate /etc/nginx/conf.d/ca.crt;
        ssl_verify_client on;

        gzip on;

        send_timeout            300s;
        client_body_timeout     300s;
        client_header_timeout   300s;
        keepalive_timeout       300s;

        location / {
          proxy_pass  http://nodejs;
          proxy_http_version  1.1;
          proxy_set_header  Connection "";
          proxy_set_header  Upgrade $http_upgrade;
          proxy_set_header  Host  $host;
          proxy_set_header  X-Real-IP $remote_addr;
          proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;

          proxy_set_header X-SSL-client-serial $ssl_client_serial;
          proxy_set_header X-SSL-client-s-dn $ssl_client_s_dn;
          proxy_set_header X-SSL-client-i-dn $ssl_client_i_dn;
          proxy_set_header X-SSL-client-session-id $ssl_session_id;
          proxy_set_header X-SSL-client-verify $ssl_client_verify;

          proxy_connect_timeout   300s;
          proxy_send_timeout      300s;
          proxy_read_timeout      300s;
        }
      }
  "/etc/nginx/conf.d/server.crt":
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN CERTIFICATE-----
      MIJDkzCCAvygAwIBAgIJALrlDwddAmnYMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
      ...
      LqGyLiCzbVtg97mcvqAmVcJ9TtUoabtzsRJt3fhbZ0KKIlzqkeZr+kmn8TqtMpGn
      r6oVDizulA==
      -----END CERTIFICATE-----
  "/etc/nginx/conf.d/server.key":
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN RSA PRIVATE KEY-----
      MIJCXQIBAAKBgQCvnu08hroXwnbgsBOYOt+ipinBWNDZRtJHrH1Cbzu/j5KxyTWF
      ...
      f92RjCvuqdc17CYbjo9pmanaLGNSKf0rLx77WXu+BNCZ
      -----END RSA PRIVATE KEY-----
  "/etc/nginx/conf.d/ca.crt":
    mode: "000400"
    owner: root
    group: root
    content: |
      -----BEGIN CERTIFICATE-----
      MIJCizCCAfQCCQChmTtNzd2fhDANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMC
      ...
      4nCavUiq9CxhCzLmT6o/74t4uCDHjB+2+sIxo2zbfQ==
      -----END CERTIFICATE-----