Site icon Soul & Shell Blog

透過 Certificate Revocation List + HAProxy 來管理 HTTPS 連線

建立 CRL (Certificate Revocation List)

在大部分的情況,HTTP Server 都是一律信任來至 Client 的 SSL 加密連線,但其實有一種方法可以透過 Server 來簽發連線憑證。透過這樣的機制可以驗證 Client 的合法性,甚至取代傳統帳號密碼的認證方式來識別使用者。

我們透過 CRL (Certificate Revocation List) 這個機制即可達到效果,我們先來測試一下用法,這裡的場景是透過 HAProxy 進行 HTTPS Load Balance 連線,後端的 Web Cluster 是採用 HTTP 不加密。關於 Server 憑證的設定方式請參考這一篇文章,SSL 設定好之後我們會有 Server 的密鑰 ca.key 與憑證 ca.crt,接著先透過 openssl 產生 CRL 檔案(用來動態管理簽發的憑證),命令如下:

openssl ca -gencrl -keyfile ./private/ca.key -cert ./certs/ca.crt -out ./crl/ca.crl

上述命令執行時,預設會用 (/usr/lib/ssl/openssl.cnf) 這一支設定檔,我們也可以透過 -config 參數來指定其他設定檔。然後可以看一下目前 List 中的內容,如下:

openssl crl -in ./crl/ca.crl -text

檢視 CRL 資訊,目前 Revocation List 是空的。

HAProxy 傳遞憑證訊息至 Backend

假設我們先用以下命令產生一組 Client 憑證來測試:

openssl genrsa -out ./private/client2.key 2048

openssl req -new -key ./private/client2.key -out ./certs/client2.csr

openssl x509 -req -days 365 -in ./certs/client2.csr -CA ./certs/ca.crt -CAkey ./private/ca.key -set_serial 03 -out ./certs/client2.crt

接著產生 p12 讓瀏覽器匯入

openssl pkcs12 -export -in ./certs/client2.crt -out ./certs/client2.p12 -name "Client 2" -inkey ./private/client2.key

匯入後就可以進行 SSL 連線,為了讓 Cluster 可以接收到 HAProxy 解析的憑證資訊,我們必須在 Frontend Block 加入以下設定:

frontend https_frontend
    bind :443 ssl crt /etc/pki/CA/certs/server.pem ca-file /etc/pki/CA/certs/ca.crt verify optional crt-ignore-err all crl-file /etc/pki/CA/crl/ca.crl
    mode http
    option forwardfor

    # SSL Certificate
    http-request set-header X-SSL                  %[ssl_fc]
    http-request set-header X-SSL-Client-Verify    %[ssl_c_verify]
    http-request set-header X-SSL-Client-DN        %{+Q}[ssl_c_s_dn]
    http-request set-header X-SSL-Client-CN        %{+Q}[ssl_c_s_dn(cn)]
    http-request set-header X-SSL-Issuer           %{+Q}[ssl_c_i_dn]
    http-request set-header X-SSL-Client-NotBefore %{+Q}[ssl_c_notbefore]
    http-request set-header X-SSL-Client-NotAfter  %{+Q}[ssl_c_notafter]

透過上面的方式,HAProxy 就會將 SSL DN, CN, Verify 等等資訊以 HTTP Header 的方式帶到後端進行處理,如果是使用 PHP 就可以透過 $_SERVER['HTTP_X_SSL_CLIENT_CN'] 這樣的方式來取的 HAProxy 所解析的憑證資訊,可以做進一步的應用。

撤銷使用者憑證

一開始提到 CRL 的機制可以動態管理憑證,那接著我們試著在 Server 上將剛剛建立的 Client 連線憑證撤銷,直接禁止使用這個憑證建立 SSL 連線。命令如下:

openssl ca -revoke ./certs/client2.crt -keyfile ./private/ca.key -cert ./certs/ca.crt

重新產生 CRL File

openssl ca -gencrl -keyfile ./private/ca.key -cert ./certs/ca.crt -out ./crl/ca.crl

查看被撤銷的憑證,透過以下命令檢視 CRL 資訊,可以看到有一組憑證被撤銷

openssl crl -in ./crl/ca.crl -text

然後這個 Client 就無法拿著剛剛發的憑證向 Server 建立 SSL 連線囉。

Exit mobile version