在西元2015年之後,我們所熟悉的HTTP網站已經被大多數人認為是不安全的網站了,許多瀏覽器甚至會直接針對沒有使用HTTPS協定的網站打上「不安全」的標籤,就連搜尋引擎也會降低HTTP網站的排名。因此讓網站支援SSL,並使用HTTPS協定進行傳輸,已經是再基本不過的事了。在過去使用公開的SSL時,通常都需要去向第三方安全認證機構購買所謂的「SSL憑證」,一直到2015年,Let's Encrypt逐漸興起後,免費公開的SSL憑證才流行起來。
由於向Let's Encrypt申請到的免費SSL憑證只有三個月的有效期,如果要繼續使用就必須要重新申請,因此為了要加速這件重複申請Let's Encrypt的日常工作,選擇一個適當的工具是很重要的!
acme.sh
「acme.sh」是一個利用Unix Shell Script來完成Let's Encrypt的SSL憑證申請的開源工具,ACME為「Automated Certificate Management Environment」的縮寫,中文譯作「自動證書管理環境」,簡單來說,我們可以透過JSON文件格式和HTTPS協定來按照ACME的規範(例如驗證網域的所有權的方式),完成Let's Encrypt的SSL憑證申請。
GitHub:
安裝acme.sh
執行以下指令即可安裝「acme.sh」:
接著執行以下指令,可以讓「acme.sh」在將來自動更新:
使用acme.sh
「acme.sh」通常會直接在伺服器上跟著伺服器程式(如Nginx和Apache)和Web應用程式一同使用,使用者在使用「acme.sh」的「--issue」參數申請到SSL憑證之後,即可放著不管它,每隔60天它都會自動作SSL憑證的延展,避免憑證過期而導致網站失效。
以下區分幾種「acme.sh」的使用情境:
「acme.sh」存在於公開的網站伺服器
網站的根目錄是公開存取的
假設網域名稱是「example.com」,在能「公開存取」的網站根目錄下新增「file.txt」檔案時,使用「http://example.com/file.txt」或是「https://example.com/file.txt」可以存取到「file.txt」檔案。
這時候就可以使用以下指令來申請SSL憑證:
如果在申請的過程中,需要驗證網域所有權的話,「acme.sh」就會自動在網站根目錄下新增「.well-known/acme-challenge」目錄和一個帶有雜湊訊息的檔案。如此一來,Let's Encrypt就能從外部夠透過網址來嘗試存取這個檔案。如果能存取得到,而且雜湊訊息也沒錯的話,就會頒發憑證。
注意這邊「-d」選項可以是複數個,而且也支援「Wildcard」,可以使用星號來表示所有子網域。
使用Nginx作為前端伺服器程式
如果網站並沒有能「公開存取」的網站根目錄,但網站是使用Nginx來作為前端伺服器的話,可以使用以下指令來申請SSL憑證:
使用Apache作為前端伺服器程式
如果網站並沒有能「公開存取」的網站根目錄,但網站是使用Apache來作為前端伺服器的話,可以使用以下指令來申請SSL憑證:
獨立的驗證伺服器程式
如果網站並沒有能「公開存取」的網站根目錄,同時也沒有使用Nginx或是Apache作為前端伺服器的話,可以使用「acme.sh」自帶的前端伺服器,指令如下:
這個自帶的前端伺服器必須使用HTTP的80連接埠。
「acme.sh」存在於私人的電腦,且我們擁有網域的記錄修改權限
如果我們並未將「acme.sh」直接用於伺服器主機上,而是想在自己開發、測試用的電腦上作業,可以使用使用以下指令:
指令執行之後,「acme.sh」會回傳DNS的TXT記錄需要修改的項目。我們在手動完成DNS的修改之後,還需等待DNS對應(通常要兩分鐘以上)。之後再使用以下指令來告訴Let's Encrypt來驗收我們的設定。
但如果網域有幾十個或是幾百個,一個一個手動設定DNS的話實在是太麻煩。所幸「acme.sh」有提供各大DNS服務廠商的API支援。
以CloudFlare來舉例,如果我們的網域是CloudFlare代管的,需要先到CloudFlare的帳號設定頁面取得API Key。
接著將這個API Key設成「CF_Key」環境變數,並再把我們登入CloudFlare所用的電子郵件信箱設成「CF_Email」環境變數,即可使用以下指令來申請SSL憑證,而不需要手動設定DNS記錄:
申請到的SSL憑證在哪?
SSL憑證申請成功之後,會得到cert、CA cert、full chain certs和key這四個檔案,並儲存在家目錄中的「.acme.sh/網域名稱」下,檔名分別為「網域名稱.cer」、「ca.cer」、「fullchain.cer」、「網域名稱.key」。接著使用伺服器程式或是Web應用程式來讀取並套用即可。
Nginx
如果使用Nginx作為前端伺服器的話,只要在設定檔中加上:
ssl_certificate_key "家目錄/.acme.sh/網域名稱/網域名稱.key"
使用以下指令重啟之後即可套用:
Apache
如果使用Apache作為前端伺服器的話,只要在設定檔中加上:
SSLCertificateKeyFile "家目錄/.acme.sh/網域名稱/網域名稱.key"
使用以下指令重啟之後即可套用:
如果以上不行(因為常用的Apache服務名稱有兩種),則:
設定伺服器程式或是Web應用程式自動套用新的SSL憑證檔案
「.acme.sh」官方並不是很建議直接使用「.acme.sh/網域名稱」下的SSL憑證檔案。因為這樣的作法無法讓持續運作的伺服器程式或是Web應用程式,自動套用到新的SSL憑證檔案。
官方建議的作法是將憑證檔透過「.acme.sh」的「--install-cert」指令「安裝」到某個路徑,再透過某個指令去通知伺服器程式或是Web應用程式去使用新的SSL憑證檔案。如此一來,就會每隔60天自動作SSL憑證的安裝和通知。
Nginx
如果使用Nginx作為前端伺服器的話,安裝SSL憑證的指令如下:
在設定檔中加上:
ssl_certificate_key "/path/to/fullchain.pem"
注意這邊的「service nginx reload」,如果沒有root權限的話是無法成功執行的。可以改為「sudo service nginx reload」,並在「/etc/sudoers」設定檔中加上:
Apache
如果使用Apache作為前端伺服器的話,安裝SSL憑證的指令如下:
在設定檔中加上:
SSLCertificateKeyFile " /path/to/key.pem"
注意這邊的「service httpd reload」,如果沒有root權限的話是無法成功執行的。可以改為「sudo service httpd reload」,並在「/etc/sudoers」設定檔中加上:
若Apache的服務名稱不是叫「httpd」,應該就是叫「apache2」。
Web應用程式
如果沒有使用Nginx或是Apache作為前端伺服器的話,那就要看該Web應用程式有沒有支援HTTPS且有沒有支援不斷線更新SSL憑證的功能了。如果有的話,應該也要提供某種能夠用指令通知的方式,來替換運作中的Web應用程式所使用的舊SSL憑證。
Simple SSL with ACME and CloudFlare
Simple SSL with ACME and CloudFlare是筆者用Rust程式語言開發的開源工具,簡化「acme.sh」和CloudFlare的使用方式,除了能夠輕易地使用OpenSSL的設定檔來產生出自己的CSR檔案外,還支援4096位元的dhparam(Diffie-Hellman Parameter)的產生。此外「CF_Key」和「CF_Email」不是透過環境變數來設定,而是直接透過CLI介面從命令列參數傳給程式來使用,如此一來就算有多個CloudFlare帳號也很容易切換。
GitHub:
安裝Simple SSL with ACME and CloudFlare
如果系統環境中有安裝「Cargo」的話,可以直接使用以下指令來下載「Simple SSL with ACME and CloudFlare」的原始碼專案,並進行編譯安裝。
如果是使用Linux作業系統的話,可以直接到以下頁面取得「Simple SSL with ACME and CloudFlare」的執行檔,手動放置到「/usr/local/bin」目錄中即可。網址如下:
使用Simple SSL with ACME and CloudFlare前,必須先安裝好OpenSSL和「.acme.sh」。
使用Simple SSL with ACME and CloudFlare
執行以下指令,即可開始使用Simple SSL with ACME and CloudFlare:
Simple SSL with ACME and CloudFlare需要輸出一些檔案,預設會放在目前工作目錄下的「ssl」目錄內,如果想更改的話,可以加上「-o」選項來設定。
如果輸出目錄中並沒有「dhparam」檔案,程式就會開始建立。
建立「dhparam」檔案需要一些時間,請耐心等待。
接著程式會提示需要去設定輸出目錄中的「config.txt」,那個就是OpenSSL的設定檔案,用來產生CSR和key。
「config.txt」的設定方式如下圖:
然後再重新執行剛才的Simple SSL with ACME and CloudFlare指令,就可以開始申請SSL憑證啦!
SSL憑證申請成功後,憑證的相關檔案都會匯出到輸出目錄中,程式還會印出Nginx和Apache設定檔套用「dhparam」檔案和SSL憑證檔案的撰寫方式,複製貼上即可使用。
另外,之後若要延展憑證,只要重新執行剛才的Simple SSL with ACME and CloudFlare指令即可。如果有需要修改「config.txt」設定檔的話,在修改完畢後,重新申請SSL憑證時,指令需加上「--force-csr-key」選項,不然還是會沿用先前產生出來的CSR和key哦!
檢查SSL的設定
參考以下這篇文章來檢查SSL設定有沒有問題: