[HAProxy] 處理憑證相關筆記:Let’s Encrypt 自動續約、default-dh-param 與 憑證串順序 等

本篇文章更新時間:2021/01/29
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣贊助支持。


續上篇 [HAProxy] 建立 WordPress 負載平衡 Load balancing 架構筆記 把憑證處理的部分拆到這篇來集中。

環境一樣是 Ubuntu 20.04 Server + 套件安裝的 HA-Proxy version 2.0.13-2ubuntu0.1 2020/09/08

關於憑證的作業,這塊 完全不推薦使用 Let's Encrypt 來作業,但玩票性質還是可以用它來試試!

會說不推薦的原因主要是高流量的網站經不起停機,使用 Let's Encrypt 有驗證網域的階段,這會導致服務中斷,如果你網站流量經常性高負載,隨意切服務導致客戶消費體驗中斷,可能就是一大筆錢的流失。所以憑證部分會建議購買一組用,能切換指向 IP 前就設定好新主機/架構,無痛切換。

Let's Encrypt 自動續約

新版本的 Let's Encrypt 安裝方式改透過 snapd 套件處理,安裝方式如下:

apt install snapd
snap install core; snap refresh core
snap install --classic certbot

HAProxy 設定開啟服務來接收驗證的操作:

frontend frontend-http
    bind :80
    bind :::80
    mode http
    # ACL for detecting Let's Encrypt validtion requests
    acl is_certbot path_beg /.well-known/acme-challenge/
    use_backend backend-certbot if is_certbot
# Contains certbot stand-alone webserver
backend backend-certbot
    mode http
    server certbot 127.0.0.1:9080

確認設定無誤後重新載入 HAProxy 設定。

然後使用 Let's Encrypt 這邊要請求新的授權指令為:

certbot certonly --standalone --preferred-challenges http --http-01-address 127.0.0.1 --http-01-port 9080 -d mydomain.com --email [email protected] --agree-tos --non-interactive

如果網域有指向正確到這台 HAProxy 主機的話,這時候 certbot 會開啟一個驗證服務在 9080 Port,剛好給 HAProxy 接收轉發,完成驗證!

完成驗證會取得憑證檔案在 /etc/letsencrypt/live/,搭配下方 Shell Script ( /etc/haproxy/prepareLetsEncryptCertificates.sh )組裝憑證串給 HAProxy 使用:

#!/bin/bash

# Loop through all Let's Encrypt certificates
for CERTIFICATE in `find /etc/letsencrypt/live/* -type d`; do

  CERTIFICATE=`basename $CERTIFICATE`

  # Combine certificate and private key to single file
  cat /etc/letsencrypt/live/$CERTIFICATE/fullchain.pem /etc/letsencrypt/live/$CERTIFICATE/privkey.pem > /etc/haproxy/ssl/$CERTIFICATE.pem

done

使用前先建立一個目錄存放: mkdir /etc/haproxy/ssl

執行這隻 Shell Script

chmod +x /etc/haproxy/prepareLetsEncryptCertificates.sh
sh /etc/haproxy/prepareLetsEncryptCertificates.sh

如此一來就完成憑證串接的任務,可以準備重新載入 HAProxy 使用了。

自動續約的部分如下:

建立 Shell Script 檔案: /etc/haproxy/renewLetsEncryptCertificates.sh

#!/bin/bash

certbot renew --standalone --preferred-challenges http --http-01-address 127.0.0.1 --http-01-port 9080 --post-hook "/etc/haproxy/prepareLetsEncryptCertificates.sh && systemctl reload haproxy.service" --quiet

記得賦予執行權限: chmod +x /etc/haproxy/renewLetsEncryptCertificates.sh

最後掛載 Cron job 定期續約。

0 0 * * * /bin/sh /etc/haproxy/renewLetsEncryptCertificates.sh

最後才補上 HAProxy 設定讀取憑證開始使用

frontend frontend-https
    bind :443 ssl crt /etc/haproxy/ssl/
    bind :::443 ssl crt /etc/haproxy/ssl/
    mode http
    # ACL for detecting Let's Encrypt validtion requests
    acl is_certbot path_beg /.well-known/acme-challenge/ 
    use_backend backend-certbot if is_certbot
    default_backend backend-web

這部分文獻參考 LET’S ENCRYPT WITH HAPROXY。 一次全上文獻裡的 HAProxy 設定會出錯,要注意有先後順序,也就是先要開啟的是 HTTP 服務與 certbot 服務來做驗證,最後才是補上 HTTPS 的服務設定。

default-dh-param 預設加密長度問題

主要是使用預設DH金鑰的檔案長度已經過時了,會出現錯誤訊息:

Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.

解決辦法就是不要用預設的,自己產生過:

openssl dhparam -out /etc/haproxy/dhparams.pem 2048

調整 HAProxy 設定 vi /etc/haproxy/haproxy.cfg

ssl-default-server-ciphers PROFILE=SYSTEM 這行後補上 ssl-dh-param-file /etc/haproxy/dhparams.pem 這行,存擋重啟,完成!

參考:HAproxy SSL/TLS Warning: Setting tune.ssl.default-dh-param to 1024 by default

憑證串接順序

由於不推薦使用 Let's Encrypt 作為高流量的網站上線使用,所以如果是自己買過的憑證,就要把他串起來餵給 HAProxy 使用。

串接順序是:

-----BEGIN PRIVATE KEY-----
[Your private key 私鑰]
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
[Your certificate 憑證]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Intermediate#1 certificate 中繼憑證A]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Intermediate#2 certificate 中繼憑證B]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Root certificate 根憑證]
-----END CERTIFICATE-----

參考:HAProxy and Intermediate SSL Certificate Issue

HAProxy 設定使用 SNI 分流方法

伺服器名稱指示(英語:Server Name Indication,縮寫:SNI) 這情況常見在單一主機多網站代管,且每個網站又有 HTTPS 憑證需求的時候。

憑證部分 HAProxy 可以掃目錄的方式處理,不用指定 pem 檔案,但設定上要使用 ssl_fc_sni 關鍵字補上判斷網域來轉請求。

詳細參考設定:

frontend ft_test
  mode http
  bind 0.0.0.0:443 ssl crt /etc/haproxy/ssl/ 
  use_backend bk_cert1 if { ssl_fc_sni my.example1.com } # content switching based on SNI
  use_backend bk_cert2 if { ssl_fc_sni my.example2.org } # content switching based on SNI

backend bk_cert1
  mode http
  server srv1 <ip-address2>:80

backend bk_cert2
  mode http
  server srv2 <ip-address3>:80

參考:Configure multiple SSL certificates in Haproxy

後記

憑證部分會處理到的常見操作應該就這些了吧!至少目前還沒碰到過其他需求,等碰到再補吧~ 有錯也歡迎留言或來信告知。


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____34%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *