haproxy动态SSL配置多个域名

问题描述:

我有两个VPS中的100个类似网站的东西'。我想使用haproxy来切换流量,但同时我想添加SSL证书。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可能吗?

这可以完成,但TLS(SSL)不允许您按照您的设想进行操作。

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

documentation for the crt keyword

如果一个目录名来代替PEM文件,然后在 找到的所有文件目录将按照字母顺序加载,除非他们的名字与 “.issuer”结束后, '.ocsp'或'.sctl'(保留扩展名)。为了从多个文件或 目录加载证书,可以指定多次指定 。证书将呈现给提供 有效TLS服务器名称指示字段的客户,该字段与其CN或其中一个 主题相匹配。支持通配符,其中使用通配符'*' 而不是第一个主机名组件(例如:* .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

我想用添加变量调用TE特定的证书对于每个网站

如文档中提到,如果浏览器发送服务器名称标识(SNI),然后HAProxy的将自动使用适当的证书与浏览器协商。

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

如果浏览器不会说SNI - 一个应该几乎完全不相关的问题 - 或者如果没有与SNI中提供的主机名匹配的文件证书 - 则使用默认证书与浏览器进行协商。

想我还检查SSL是真实可用,如果不可用开关与HTTP重定向

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

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

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

如果您确实想在所有这些之后重定向,则需要查看layer 5 fetches。您需要验证Host标头是否与SNI或默认证书相匹配,并且如果您的证书是通配符,则还需要适应此问题,但这种情况仍然只会在后发生,用户绕过安全警告。

想象一下,如果事情如此简单,以至于没有有效证书的Web服务器只需重定向它就可以劫持流量,而无需浏览器要求服务器证书有效(或者用户故意采取行动绕过警告),并且它应该成为显然你为什么原来的想法不但不行,而且事实上也不行。

还要注意,从配置目录加载的证书在启动时全部加载。如果您需要HAProxy来发现新的或丢弃旧的,则需要热启动HAProxy(通常为sudo service haproxy reload)。