Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ssl 使用HAProxy仅为443端口上的某些流量提供证书_Ssl_Haproxy - Fatal编程技术网

Ssl 使用HAProxy仅为443端口上的某些流量提供证书

Ssl 使用HAProxy仅为443端口上的某些流量提供证书,ssl,haproxy,Ssl,Haproxy,我购买了一个通配符证书(比如,*.example.com) 我想用HAProxy来解决这个问题,这不是问题。但是,我不知道如何告诉HAProxy不要为任何与作为主机的*.example.com不匹配的内容提供证书 这些服务由另一个服务(使用Let's Encrypt)提供,我想将流量重定向到该服务。问题 我遇到的问题是,我想HAProxy处理域及其任何子域的SSL/TLS握手(我买了一个通配符证书) 任何与该域不匹配的内容,我都希望通过Let's Encrypt using为它们生成SSL证书,

我购买了一个通配符证书(比如,*.example.com)

我想用HAProxy来解决这个问题,这不是问题。但是,我不知道如何告诉HAProxy不要为任何与作为主机的*.example.com不匹配的内容提供证书

这些服务由另一个服务(使用Let's Encrypt)提供,我想将流量重定向到该服务。

问题 我遇到的问题是,我想HAProxy处理域及其任何子域的SSL/TLS握手(我买了一个通配符证书)

任何与该域不匹配的内容,我都希望通过Let's Encrypt using为它们生成SSL证书,并且我还需要Greenlock来处理SSL/TLS握手

解决方案 在HAProxy中,我们绑定到端口80和443以侦听两个端口上的流量

在端口80上,我们:

  • 如果请求不是SSL且请求路径不是以
    /.well-known/acme
  • 如果请求头中的主机与我们的通配符域不匹配,请使用绿锁后端
对于443端口,我们:

  • 首先使用tcp模式,因为此时我们不想处理SSL握手
  • 设置日志记录,以便我们可以看到通常包含 客户端尝试连接的主机的名称(即您的域)
  • 如果主机名与通配符域不匹配,请使用greenlock_https后端
  • 或者使用https后端作为回退(即,如果主机匹配通配符域,则使用此回退)
有趣的是
https-back
后端:

  • 它只是将请求转发到此地址
    unix@/var/run/haproxy.sock
谁在听那个地址?它是提供通配符证书的前端:

frontend https-front
    bind   unix@/var/run/haproxy.sock ssl crt /etc/haproxy/paid_certs/exapmle.com.crt accept-proxy
    mode   http
    option forwardfor
    reqdel X-Forwarded-Proto
    reqadd X-Forwarded-Proto:\ https if { ssl_fc }

    default_backend elb
为完整起见,以下是所有前端和后端:

frontend http-in
frontend http-in
        acl acme_challenge path_beg /.well-known/acme
        acl is_wildcard_domain hdr_end(Host) example.com
        bind *:80

        redirect scheme https if !{ ssl_fc } !acme_challenge
        use_backend greenlock_http if !is_wildcard_domain acme_challenge

frontend https-in
        bind *:443
        mode tcp

        tcp-request inspect-delay 5s
        tcp-request content capture req.ssl_sni len 40
        log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq ssl_sni: %[capture.req.hdr(0)]"

        tcp-request content accept if { req_ssl_hello_type 1 }
        acl is_wildcard_domain req.ssl_sni -m end example.com

        use_backend greenlock_https if !is_wildcard_domain
        default_backend https-back

backend greenlock_http
        server greenlock greenlock:80 
        cookie webserver insert indirect nocache

backend greenlock_https
        mode tcp
        server greenlock greenlock:443

backend https-back
        mode tcp
        server https-front unix@/var/run/haproxy.sock send-proxy-v2

frontend https-front
        bind   unix@/var/run/haproxy.sock ssl crt /etc/haproxy/certs/example.com accept-proxy
        mode   http
        option forwardfor
        reqdel X-Forwarded-Proto
        reqadd X-Forwarded-Proto:\ https if { ssl_fc }

        default_backend elb

backend elb
        mode http
        server elb ${ELB_HOST}
        balance roundrobin     #balance type
        option forwardfor
        cookie webserver insert indirect nocache
问题 我遇到的问题是,我想HAProxy处理域及其任何子域的SSL/TLS握手(我买了一个通配符证书)

任何与该域不匹配的内容,我都希望通过Let's Encrypt using为它们生成SSL证书,并且我还需要Greenlock来处理SSL/TLS握手

解决方案 在HAProxy中,我们绑定到端口80和443以侦听两个端口上的流量

在端口80上,我们:

  • 如果请求不是SSL且请求路径不是以
    /.well-known/acme
  • 如果请求头中的主机与我们的通配符域不匹配,请使用绿锁后端
对于443端口,我们:

  • 首先使用tcp模式,因为此时我们不想处理SSL握手
  • 设置日志记录,以便我们可以看到通常包含 客户端尝试连接的主机的名称(即您的域)
  • 如果主机名与通配符域不匹配,请使用greenlock_https后端
  • 或者使用https后端作为回退(即,如果主机匹配通配符域,则使用此回退)
有趣的是
https-back
后端:

  • 它只是将请求转发到此地址
    unix@/var/run/haproxy.sock
谁在听那个地址?它是提供通配符证书的前端:

frontend https-front
    bind   unix@/var/run/haproxy.sock ssl crt /etc/haproxy/paid_certs/exapmle.com.crt accept-proxy
    mode   http
    option forwardfor
    reqdel X-Forwarded-Proto
    reqadd X-Forwarded-Proto:\ https if { ssl_fc }

    default_backend elb
为完整起见,以下是所有前端和后端:

frontend http-in
frontend http-in
        acl acme_challenge path_beg /.well-known/acme
        acl is_wildcard_domain hdr_end(Host) example.com
        bind *:80

        redirect scheme https if !{ ssl_fc } !acme_challenge
        use_backend greenlock_http if !is_wildcard_domain acme_challenge

frontend https-in
        bind *:443
        mode tcp

        tcp-request inspect-delay 5s
        tcp-request content capture req.ssl_sni len 40
        log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq ssl_sni: %[capture.req.hdr(0)]"

        tcp-request content accept if { req_ssl_hello_type 1 }
        acl is_wildcard_domain req.ssl_sni -m end example.com

        use_backend greenlock_https if !is_wildcard_domain
        default_backend https-back

backend greenlock_http
        server greenlock greenlock:80 
        cookie webserver insert indirect nocache

backend greenlock_https
        mode tcp
        server greenlock greenlock:443

backend https-back
        mode tcp
        server https-front unix@/var/run/haproxy.sock send-proxy-v2

frontend https-front
        bind   unix@/var/run/haproxy.sock ssl crt /etc/haproxy/certs/example.com accept-proxy
        mode   http
        option forwardfor
        reqdel X-Forwarded-Proto
        reqadd X-Forwarded-Proto:\ https if { ssl_fc }

        default_backend elb

backend elb
        mode http
        server elb ${ELB_HOST}
        balance roundrobin     #balance type
        option forwardfor
        cookie webserver insert indirect nocache

证书不提供服务,但它们作为TLS握手的一部分由服务器发送。TLS握手由客户端发起。一旦客户端开始TLS握手,HAProxy必须以某种方式回复。正确的响应是继续TLS握手,其中包括发送一些证书。另一种反应是关闭连接,这将导致客户端出错。到目前为止,您只声明它不应提供特定的证书。但是您没有说它应该做什么,还要注意,服务器名称通常作为ClienHello(TLS握手的开始)中的SNI扩展发送。但是,可能有一些客户机不这样做(只有少数,例如所有浏览器都使用SNI),这意味着HAProxy不知道客户机想要访问什么主机名。这可能会在稍后的HTTP对话框中包含,但这需要首先成功地进行TLS握手,从而发送预期的证书。如果你想与这些客户打交道,你还需要指定如何处理这一特定案件。谢谢你的回复,@SteffenUllrich。我需要另一个服务来为某些主机提供证书而不是HAProxy。我已经在HAProxy中定义了一个后端,并希望将其用于HAProxy不应支持TLS握手的特定主机。或者可能对您有所帮助。证书不提供服务,但它们是作为TLS握手的一部分由服务器发送的。TLS握手由客户端发起。一旦客户端开始TLS握手,HAProxy必须以某种方式回复。正确的响应是继续TLS握手,其中包括发送一些证书。另一种反应是关闭连接,这将导致客户端出错。到目前为止,您只声明它不应提供特定的证书。但是您没有说它应该做什么,还要注意,服务器名称通常作为ClienHello(TLS握手的开始)中的SNI扩展发送。但是,可能有一些客户机不这样做(只有少数,例如所有浏览器都使用SNI),这意味着HAProxy不知道客户机想要访问什么主机名。这可能会在稍后的HTTP对话框中包含,但这需要首先成功地进行TLS握手,从而发送预期的证书。如果你想与这些客户打交道,你还需要指定如何处理这一特定案件。谢谢你的回复,@SteffenUllrich。我想要另一项服务来提供证书,而不是针对某些居屋
frontend http-in
frontend http-in
        acl acme_challenge path_beg /.well-known/acme
        acl is_wildcard_domain hdr_end(Host) example.com
        bind *:80

        redirect scheme https if !{ ssl_fc } !acme_challenge
        use_backend greenlock_http if !is_wildcard_domain acme_challenge

frontend https-in
        bind *:443
        mode tcp

        tcp-request inspect-delay 5s
        tcp-request content capture req.ssl_sni len 40
        log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq ssl_sni: %[capture.req.hdr(0)]"

        tcp-request content accept if { req_ssl_hello_type 1 }
        acl is_wildcard_domain req.ssl_sni -m end example.com

        use_backend greenlock_https if !is_wildcard_domain
        default_backend https-back

backend greenlock_http
        server greenlock greenlock:80 
        cookie webserver insert indirect nocache

backend greenlock_https
        mode tcp
        server greenlock greenlock:443

backend https-back
        mode tcp
        server https-front unix@/var/run/haproxy.sock send-proxy-v2

frontend https-front
        bind   unix@/var/run/haproxy.sock ssl crt /etc/haproxy/certs/example.com accept-proxy
        mode   http
        option forwardfor
        reqdel X-Forwarded-Proto
        reqadd X-Forwarded-Proto:\ https if { ssl_fc }

        default_backend elb

backend elb
        mode http
        server elb ${ELB_HOST}
        balance roundrobin     #balance type
        option forwardfor
        cookie webserver insert indirect nocache