使用 LE 在 haproxy.cfg 中进行基于通配符名称的配置

使用 LE 在 haproxy.cfg 中进行基于通配符名称的配置

尝试使用 haproxy.cfg 中的 catchall 通配符条目 [A, A1] 将某些域名重定向到特定后端(HAproxy v1.8.12 主机操作系统:Alpine Linux v3.9 版本详细信息 [B] 发布在最后,以防不同版本的行为不同[C]):

frontend http
        bind *:80
        reqadd X-Forwarded-Proto:\ http
        redirect scheme https code 301 if !{ ssl_fc }
        ### specific domains ###
        acl host_specificdomain hdr(host) -m reg -i  ^[^\.]+\.specific.domain$
        #Redirect all other domains with all extensions and all ports to:
        acl host_catchall hdr(host) -m reg -i ^[^\.]+\.^[^\.].^[^\.](:[0-9]+)?$
        ### clusters ###
        use_backend specificdomain_cluster if host_specificdomain
        use_backend catchall_cluster if host_catchall

frontend https
        bind       *:443 ssl no-sslv3 crt-list /etc/haproxy/ssl/ssl.lst
        rspadd Strict-Transport-Security:\ max-age=31536000;\ includeSubDomains;\ preload
        rspadd X-Frame-Options:\ DENY
        reqadd X-Forwarded-Proto:\ https
        acl app_letsencrypt  path_beg   /.well-known/acme-challenge/
        use_backend bk-letsencrypt if app_letsencrypt

backend bk-letsencrypt
    log global
    mode http
    server srv_letsencrypt 127.0.0.1:63443

backend catchall_cluster
        redirect scheme https if !{ ssl_fc }
        mode http
        balance roundrobin
        option forwardfor
        server server1 192.168.200.101:80 check
        server server2 192.168.200.102:80 check

backend specificdomain_cluster
        redirect scheme https if !{ ssl_fc }
        mode http
        balance roundrobin
        option forwardfor
        server server1 192.168.200:103:80 check
        server server2 192.168.200.104:80 check 

haproxy 统计数据显示所有服务器均处于活动状态,仅供参考。

上述情况提出了三个问题:

  1. 带有通配符的 catchall domains 选项(acl host_catchall hdr(host) -m reg -i ^[^.]+.^[^.].^^.?$)没有重定向所有域,但没有重定向 specific.domain(acl host_specificdomain hdr(host) -m reg -i ^[^.]+.specific.domain$)。

  2. 即使是 specific.domain 在以下情况下也会出现 503 错误“服务不可用,没有可用的服务器来处理此请求”:

$ curl -v --resolve specific.domain:443:127.0.0.1 https://specific.domain
* Expire in 0 ms for 6 (transfer 0x55c2bc8bc4c0)
* Added specific.domain:443:127.0.0.1 to DNS cache
* Hostname specific.domain was found in DNS cache
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55c2bc8bc4c0)
* Connected to specific.domain (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt   CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=specific.domain
*  start date: Jun 17 08:00:34 2019 GMT
*  expire date: Sep 15 08:00:34 2019 GMT
*  subjectAltName: host "specific.domain" matched cert's "specific.domain"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: specific.domain
> User-Agent: curl/7.64.0
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* HTTP 1.0, assume close after body < HTTP/1.0 503 Service Unavailable < Cache-Control: no-cache < Connection: close < Content-Type: text/html <  <html><body><h1>503 Service Unavailable</h1> No server is available to handle this request. </body></html>
* TLSv1.3 (IN), TLS alert, close notify (256):
* Closing connection 0

同一个域名可以通过 http 轻松访问,如下所示:

$ curl -v --resolve specific.domain:80:127.0.0.1 http://specific.domain
* Expire in 0 ms for 6 (transfer 0x55cecf76c4c0)
* Added specific.domain:80:127.0.0.1 to DNS cache
* Hostname specific.domain was found in DNS cache
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x55cecf76c4c0)
* Connected to specific.domain (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: specific.domain
> User-Agent: curl/7.64.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx
< Date: Sat, 22 Jun 2019 18:58:31 GMT
< Content-Type: text/html
< Content-Length: 17832
< Last-Modified: Wed, 19 Jun 2019 09:19:57 GMT
< Connection: close
< Vary: Accept-Encoding
< ETag: "5d09fe3d-45a8"
< Accept-Ranges: bytes
< 
<!doctype html>
...
  1. Haproxy 无法提取 DNS 指向机器特定 IP 的其他域证书:
Failed authorization procedure. www.specific.domain (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://www.specific.domain/.well-known/acme-challenge/APRETTYLONGID [PUBLIC IP]: "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n   \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<ht"

顺便说一句,我正在使用脚本 [D] 来生成 LE 证书,供您参考。

任何指示表示赞赏,

谢谢,欢呼,/z

参考:

A。https://serverfault.com/a/909483/528889

A1。https://unix.stackexchange.com/questions/166169/how-to-configure-haproxy-to-redirect-multiple-domain

B.HAproxy版本详情:

 haproxy -vvvvv
HA-Proxy version 1.8.12-8a200c7 2018/06/27
Copyright 2000-2018 Willy Tarreau <[email protected]>

Build options :
  TARGET  = linux2628
  CPU     = generic
  CC      = gcc
  CFLAGS  = -Os -fomit-frame-pointer
  OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1 USE_NS=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with OpenSSL version : OpenSSL 1.1.1a  20 Nov 2018
Running on OpenSSL version : OpenSSL 1.1.1b  26 Feb 2019
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with Lua version : Lua 5.3.5
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE version : 8.42 2018-03-20
Running on PCRE version : 8.42 2018-03-20
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with zlib version : 1.2.11
Running on zlib version : 1.2.11
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available filters :
        [SPOE] spoe
        [COMP] compression
        [TRACE] trace

C。https://superuser.com/questions/1195012/haproxy-1-7-2-refuses-to-match-host-in-acl

D.https://github.com/tisc0/letsHAP

答案1

首先,你的 https 前端缺少后端。

此外,我的建议是在前端使用默认后端,而不是使用复杂的正则表达式来捕获“所有其他域”。

关于主机头上使用正则表达式的 acls,我使用 hdr_reg(host) 比使用 hdr(host) -m reg -i 更成功。

我向你提出另一条建议: - 让事情变得不那么复杂 - 注释掉不必要的选项以方便排除故障

啊:我不确定您的正则表达式行是否在 http 前端读取,因为您之前使用了重定向方案 https:我想说您的所有请求都转到没有后端的 https。

希望能帮助到你。

干杯,

答案2

前端 https 的后端已附加到早期配置中,如下所示,但所有流量都发送到 host_catchall 服务器!?有什么线索吗?谢谢!


frontend http
        bind *:80
        reqadd X-Forwarded-Proto:\ http
        redirect scheme https code 301 if !{ ssl_fc }
        ### specific domains ###
        acl host_specificdomain hdr(host) -i subdomain.specific.domain -
        #Redirect all other domains with all extensions and all ports to:
        acl host_catchall hdr(host) -i subdomain.catchall.domain
        ### clusters ###
        use_backend specificdomain_cluster if host_specificdomain
        use_backend catchall_cluster if host_catchall

frontend https
        bind       *:443 ssl no-sslv3 crt-list /etc/haproxy/ssl/ssl.lst
        rspadd Strict-Transport-Security:\ max-age=31536000;\ includeSubDomains;\ preload
        rspadd X-Frame-Options:\ DENY
        reqadd X-Forwarded-Proto:\ https
        acl app_letsencrypt  path_beg   /.well-known/acme-challenge/
        use_backend bk-letsencrypt if app_letsencrypt

        ### specific domains ###
        acl host_specificdomain hdr(host) -i subdomain.specific.domain$
        #Redirect all other domains with all extensions and all ports to:
        acl host_catchall hdr(host) -i subdomain.catchall.domain
        ### clusters ###
        use_backend specificdomain_cluster if host_specificdomain
        use_backend catchall_cluster if host_catchall

相关内容