多个域的HAProxy动态SSL配置

时间:2016-12-24 16:58:07

标签: ssl haproxy

我在两个VPS中有100个类似的网站。我想使用HAProxy动态切换流量,但同时我想添加SSL证书。

我想使用添加变量来为每个网站调用特定证书。 例如:

frontend web-https 
    bind 0.0.0.0:443 ssl crt /etc/ssl/certs/{{domain}}.pem 
    reqadd X-Forwarded-Proto:\ https 
    rspadd Strict-Transport-Security:\ max-age=31536000 
    default_backend website

我还要检查SSL证书是否真的可用,如果它不可用,请切换到带有重定向的HTTP。

这可能与HAProxy有关吗?

1 个答案:

答案 0 :(得分:6)

这可以做到,但是TLS(SSL)不允许你按照你想象的方式去做。

首先,HAProxy允许您指定默认证书和附加证书的目录。

来自documentation for the crt keyword

  

如果使用目录名而不是PEM文件,则找到所有文件   该目录将按字母顺序加载,除非其名称以   '.issuer','。ocsp'或'.sctl'(保留扩展名)。该指令可能是   多次指定,以便从多个文件加载证书或   目录。证书将提供给提供a。的客户   有效的TLS服务器名称指示字段匹配其CN或alt之一   科目。支持通配符,其中使用通配符“*”   而不是第一个主机名组件(例如:* .example.org匹配   www.example.org但不是www.sub.example.org)。

     

如果客户端未提供SNI或SSL库不支持   TLS扩展,或者如果客户端提供不具有的SNI主机名   匹配任何证书,然后将显示第一个加载的证书。   这意味着从目录加载证书时,它是高度的   建议首先将默认值加载为文件或确保它将   永远是目录中的第一个。

因此,您只需要一个包含pem文件中每个证书/链/密钥的目录,并修改您的配置,如下所示:

bind 0.0.0.0:443 ssl crt /etc/haproxy/my-default.pem crt /etc/haproxy/my-cert-directory

请注意,您还应添加no-sslv3

  

我想使用添加变量来为每个网站调用特定证书

如文档中所述,如果浏览器发送服务器名称标识(SNI),则HAProxy将使用相应的证书自动与浏览器协商。

因此不需要可配置的证书选择,但更重要的是,这是不可能的。 SSL / TLS不能以这种方式工作(任何地方)。在浏览器成功协商安全通道之前,您不知道浏览器要求的网站,因为浏览器尚未发送请求。

如果浏览器不说SNI - 这个问题几乎完全不相关 - 或者如果文件中没有与SNI中显示的主机名相匹配的证书 - 则默认证书用于与浏览器协商。

  

我还要检查ssl是否真实可用且万一无法切换到带有重定向的http

这也是不可能的。请记住,首先协商加密,然后才是浏览器发送的HTTP请求。

因此,用户永远不会看到您的重定向,除非他们绕过浏览器的安全警告 - 他们必须看到这一点,因为默认证书中的主机名与浏览器期望在证书中看到的主机名不匹配。

此时,迫使他们回到http是没有意义的,因为通过绕过浏览器安全警告,他们建立了一个同时 - 不受信任但仍然加密的连接。连接在技术上是安全的,但用户在地址栏中有红色×,因为浏览器正确认为证书无效(由于主机名不匹配)。但是在用户坚持绕过警告时,浏览器仍然使用无效证书来建立安全通道。

如果你真的想在所有这些之后重定向,你需要看一下layer 5 fetches。您需要验证Host标头是否与SNI或默认证书匹配,如果您的证书是通配符,您也需要适应它,但这仍然只会在之后发生 em>用户绕过安全警告。

想象一下,如果事情如此简单,以至于没有有效证书的网络服务器可以通过简单地重定向来劫持流量而不需要浏览器要求服务器的证书有效(或者用户故意绕过警告)并且它应该变得明显为什么你最初的想法不仅不起作用,而且实际上不应该起作用。

另请注意,从配置目录加载的证书都是在启动时加载的。如果你需要HAProxy来发现新的或丢弃旧的,你需要热重启HAProxy(通常是sudo service haproxy reload)。