Ssl

SharePoint - HAProxy 反向代理(SSL 問題)

  • July 16, 2020

下面更新


我決定使用 HAProxy 作為 SharePoint 網站的反向代理,沒有 SSL 一切正常,但使用 SSL 我無法啟動 haproxy.service。我嘗試了許多配置,但我無法弄清楚……

嘗試啟動服務:

$ sudo systemctl start haproxy.service
Job for haproxy.service failed because the control process exited with error code.
See "systemctl status haproxy.service" and "journalctl -xe" for details.

haproxy.service 的狀態:

$ sudo systemctl status haproxy.service
    haproxy.service - HAProxy Load Balancer
      Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; vendor preset: enabled)
      Active: failed (Result: exit-code) since date CEST;
        Docs: man:haproxy(1)
              file:/usr/share/doc/haproxy/configuration.txt.gz
     Process: ExecStart=/usr/sbin/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE $EXTRAOPTS (code=exited, status=0/SUCCESS)
     Process: ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS (code=exited, status=1/FAILURE)
    Main PID: (code=exited, status=0/SUCCESS)
systemd[1]: haproxy.service: Failed with result 'exit-code'.
systemd[1]: haproxy.service: Service hold-off time over, scheduling restart.
systemd[1]: Stopped HAProxy Load Balancer.
systemd[1]: haproxy.service: Start request repeated too quickly.
systemd[1]: Failed to start HAProxy Load Balancer.
systemd[1]: haproxy.service: Unit entered failed state.
systemd[1]: haproxy.service: Failed with result 'exit-code'.
systemd[1]: haproxy.service: Start request repeated too quickly.
systemd[1]: Failed to start HAProxy Load Balancer.
systemd[1]: haproxy.service: Failed with result 'exit-code'.

檢查配置文件問題:

$ sudo haproxy -c -f haproxy.cfg
   Enter PEM pass phrase:
   [ALERT]: parsing [haproxy.cfg:31] : 'bind *:443' : unable to load SSL private key from PEM file './cert.pem'.
   [ALERT]: Error(s) found in configuration file : haproxy.cfg
   [ALERT]: Proxy 'http_id': no SSL certificate specified for bind '*:443' at [haproxy.cfg:31] (use 'crt').    
   [ALERT]: Fatal errors found in configuration.

HAProxy -vv:

$ sudo haproxy -vv
HA-Proxy version 1.7.5-2

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.8
Running on zlib version : 1.2.8
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with OpenSSL version : OpenSSL 1.1.0e
Running on OpenSSL version : OpenSSL 1.1.0f
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.39
Running on PCRE version : 8.39
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with Lua version : Lua 5.3.3
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
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 :
       [COMP] compression
       [TRACE] trace
       [SPOE] spoe

日誌:

haproxy: [ALERT]: parsing [/etc/haproxy/haproxy.cfg:31] : 'bind *:443' : unable to load SSL certificate file './cert.pem' file does not exist.
haproxy: [ALERT]: Error(s) found in configuration file : /etc/haproxy/.cfg
haproxy: [ALERT]: Proxy 'http_id': no SSL certificate specified for bind '*:443' at [/etc/haproxy/haproxy.cfg:31] (use 'crt').
haproxy: [ALERT]: Fatal errors found in configuration.

我在另一台伺服器上為 nginx 使用相同的證書(但分為:證書、密鑰、鏈),它可以工作。我用命令為 HAProxy 創建了這個cat cert.crt priv.key certchain.crt > cert.pem,我嘗試了不同的順序,但錯誤是一樣的。命令haproxy -c -f haproxy.cfg伺服器也詢問密碼片語,所以我認為證書沒問題(也許我錯了)並且配置文件有問題。感謝您的時間和幫助。

我的 haproxy.cfg:

   global    
       tune.ssl.default-dh-param 2048
       maxconn 4096
       user haproxy
       group haproxy
       daemon
       #ssl-server-verify none
   
   defaults
       mode http
       option forwardfor
       log 127.0.0.1 local0 notice
       maxconn 2000
       option httplog
       option dontlognull
       timeout connect 5000
       timeout client 50000
       timeout server 50000
           
   backend sharepoint
       mode http
       #balance roundrobin
       option redispatch
       cookie SERVERID insert nocache
       server spsrv xxx.xxx.xxx.xxx:80
           
   frontend http_id
       #bind *:80
       bind *:443 ssl crt ./cert.pem
       mode http
       reqadd X-Forwarded-Proto:\ https
       acl hosts_sharepoint hdr_end(host) -i intranet.sharepoint.com:443
       use_backend sharepoint if hosts_sharepoint
       default_backend sharepoint

第一次更新

我嘗試了直通,現在 SharePoint 在埠 80 上請求憑據(在禁用 IIS 角色之後),然後 SharePoint 重定向到 https 並出現錯誤“504 網關超時”。這是我目前的 haproxy.cfg:

global
   maxconn 4096
   user haproxy
   group haproxy
   daemon
defaults
   mode tcp
   log 127.0.0.1 local0 notice
   maxconn 2000
   option tcplog
   option dontlognull
   timeout connect 20s
   timeout client 10m
   timeout server 10m
frontend httpid
   mode tcp
   bind *:443
   acl hosts_sharepoint hdr_end(host) -i intranet.sharepoint.com
   use_backend sharepoint if hosts_sharepoint
   default_backend sharepoint
backend sharepoint
   mode tcp
   balance roundrobin
   option redispatch
   cookie SERVERID insert indirect nocache
   server st1 xxx.xxx.xxx.xxx:443
   option ssl-hello-chk

同樣 command: $ curl xxx.xxx.xxx.xxx:**80** --header 'Host: sharepoint.intranet.com' -vv返回 401 ,因此連接正常,但是帶有埠 443 的命令$ url xxx.xxx.xxx.xxx:**443** --header 'Host: sharepoint.intranet.com' -vv返回curl: (56) Recv failure: Connection reset by peer. 我的配置文件正確嗎?或者也許我需要配置 IIS?

第二次更新

重新啟動 SharePoint 伺服器後,此配置正在使用pass-through

global
   maxconn 4096
   user haproxy
   group haproxy
   daemon
defaults
   mode tcp
   log 127.0.0.1 local0 notice
   maxconn 2000
   option tcplog
   option dontlognull
   timeout connect 20s
   timeout client 10m
   timeout server 10m
frontend httpid
   mode tcp
   bind *:443
   acl hosts_sharepoint hdr_end(host) -i intranet.sharepoint.com
   use_backend sharepoint if hosts_sharepoint
   default_backend sharepoint
backend sharepoint
   mode tcp
   balance roundrobin
   option redispatch
   cookie SERVERID insert indirect nocache
   server st1 xxx.xxx.xxx.xxx:443
   option ssl-hello-chk

也許它會對某人有所幫助。就我而言,我在 Linux 上配置了兩個網路適配器——本地網路和公共網路。在 Windows 上,我只有本地網路 - Windows 在本地網路中與 Linux 連接,然後通過 HAProxy,我可以從 Internet 打開 SharePoint 站點。

這是正確的配置,在我的情況下有效(對於 SSL,我使用了直通 - 重定向和證書在 Windows IIS 上):

global
   maxconn 4096
   user haproxy
   group haproxy
   daemon
defaults
   mode tcp
   log 127.0.0.1 local0 notice
   maxconn 2000
   option tcplog
   option dontlognull
   timeout connect 20s
   timeout client 10m
   timeout server 10m
frontend httpid
   mode tcp
   bind *:443
   acl hosts_sharepoint hdr_end(host) -i intranet.sharepoint.com
   use_backend sharepoint if hosts_sharepoint
   default_backend sharepoint
backend sharepoint
   mode tcp
   balance roundrobin
   option redispatch
   server st1 xxx.xxx.xxx.xxx:443 #local address of the Windows server
   option ssl-hello-chk

您應該避免在配置文件中使用相對路徑,例如./cert.pem. 請改成絕對路徑之類的/etc/ssl/cert.pem(調整為目前路徑)。

另外,檢查cert.pem文件本身。它應該只包含可列印的文本(不是二進制),至少包含兩個-----BEGIN CERTIFICATE-----,-----END CERTIFICATE-----塊(您的證書和鏈中的 CA)和一個-----BEGIN PRIVATE KEY-----,-----END PRIVATE KEY-----塊(或者可能是一個-----BEGIN RSA PRIVATE KEY-----, -----END RSA PRIVATE KEY-----)。

如果文件中有任何二進製cert.pem文件,您應該將原始文件 ( cert.crt, priv.key) 轉換為 PEM 格式並重新創建cert.pem文件。連接的正確順序應該是最終證書、密鑰、直接頒發者、下一個頒發者等。您可以省略根 CA,因為不包括它被認為是一種好習慣(沒有真正需要,交換的字節數更少)。

您可以使用 openssl 從二進制格式(又名 DER)轉換為文本格式(又名 PEM):

對於證書(input.crt將是 DER 文件,並且output.crt將是 PEM 格式的新文件):

openssl x509 -inform DER -in input.crt -out output.crt

對於密鑰(我假設它是 RSA 密鑰,這是最常用的)注意:它會要求輸入(新)密碼output.key,請參閱我稍後對此的評論。

openssl rsa -inform DER -in input.key -out output.key

注意:大多數伺服器假定密鑰沒有加密(即-----BEGIN PRIVATE KEY-----contains的下一行ENCRYPTED)。如果是這種情況並且您的伺服器仍然無法啟動,請嘗試將密鑰轉換為未加密的格式(注意:在此命令中,我假設inputcipher.key文件已經是 PEM 格式):

openssl rsa -in inputcipher.key -nodes -out outputclear.key

至於錯誤的傳遞504,在後面的配置中你指向的是,server st1 xxx.xxx.xxx.xxx:443而在攔截配置中你指向的是server spsrv xxx.xxx.xxx.xxx:80. 請重新檢查一下你的後端是監聽80埠還是443埠,但是443似乎沒有後端監聽。

引用自:https://serverfault.com/questions/930409