本文主要分享,我如何採用Docker的方式進行Let's Encrypt憑證申請,
Let's Encrypt有相當多種類的ACME Client,
我將使用官方推廌Certbot(ACME Client)做說明。
並且使用docker的方式來執行ACME Client。
這樣做對筆者來說,有兩個好處:
一、我不需要在主機端(host),使用最高權限(root),跑certbot程式,也不需安裝相關執行Client的Python環境。
二、貼上指令,自動下載Client並執行,然後取得憑證,當您理解docker指令及certbot參數後,這將會是非常簡易的一件事情。**
再開始前,我們先來看看Certbot所提供的Dockerfile設定。
理解Dockerfile的設定,有助於我們了解等下要執行指令的目地,所以我們來稍微看看吧。
Dockerhub的位置,請參看這裡:https://hub.docker.com/r/certbot/certbot
可以看見,上方的ENTRYPOINT就是certbot指令,我們可以由host代入參數端執行container內指令。
我將他分為四種運用情境,並不是四個步驟哦。
情境二,只需一行指令,就可以產生憑證的。
請留意docker命令中,certbot/certbot之後所代入的參數,
不同的情境,使用了不同的參數哦。
情境一、manual手動設定
代表當網頁伺服器,是遠端的主機,我們想在自己的電腦產生憑證給該主機用時。
因為要掛載目錄到container中,讓產生的憑證可以寫入我們的主機。
請先建立資料夾。
mkdir -p /etc/letsencrypt
再用下方的指令產生憑證(請自己換成您自己的郵件哦)
docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -ti certbot/certbot certonly --manual --email devin@ccc.tc --agree-tos
過程中,會詢問我們,要使用那個域名,並且會要求我們將challenage的資訊,放到遠端網頁伺服器上。
這裡提供我的做法,直接ssh到該主機,拷貝certbot要求的相關資訊,用echo標準輸出,透過大於,重導成檔案即可。
完成後,再壓Enter,如果他能經由網址連到該檔驗證通過,就會將憑證發出,放至於/etc/letsencrypt下的相關目錄中。
情境二、certonly只產生憑證
代表了,透過運行中的網頁伺服器來產生憑證,簡單說我們要執行指令的地方,
已經有一台活生生的網頁伺服器運作中了。
執行指令前,請先確認主機端有這兩個目錄。
mkdir -p /etc/letsencrypt
mkdir -p /var/www/html/.well-known/acme-challenge
(這裡假定您運作中的主機的網站根目錄是在/var/www/html下,另外,請自行換成產生憑證的域名,用www.ccc.tc是過不了的)
如果您的目錄不是/var/www/html請自行調整掛載的位置。
上方指令,使用了-v的參數分別掛載了host端的兩個資料夾。
/etc/letsencrypt (憑證與let's encrypt設定)
/var/www/html (網站的根目錄)
另外多出了–webroot -w /html 這是什麼意思呢?
這裡是我定義了網站的根目錄是/html (容器內)。不過我們透過了docker的-v /var/www/html:/html參數,
將host端的真正的跟目錄/var/www/html掛載進了容器的/html中了。
所以certbot可將challenge的檔寫到我們的網站目錄下。
/var/www/html/.well-known/acme-challenge
也就是說他會來連結我們主機上的由certbot隨機生成檔案及內容。
http://www.ccc.tc/.well-know/acme-challenge/0wCvy2q6URD-AwFTJQGUkz5sug6d3ptGp6QQGzqe1Eg
通過後,certbot便會將憑證及設定存入host端的/etc/letsencrypt中(-v /etc/letsencrypt:/etc/letsencrypt)。
因此,同樣的docker掛載方式,將certbot的entrypoint後,變更成renew,在憑證快到其時,就能自動更新囉。
0 0 * * * docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -v /var/www/html:/html -ti certbot/certbot renew
試執行renew,可以看見,顯示憑證未過期:
情境三、standalone獨立伺服器
當certbot多了–standalone參數時,代表了,他自己會建立一台challenges的http伺服器,因此,您應該確認您的防火牆是有開啟port 80的,
下方的例子中-d後面所代入的域名的DNS正解,需能解析出您電腦所使用的外網IP。
這個例字中,由certbot幫我們建立一台webserver接收challenge並產生憑證。
很明顯的,可以看到,這裡透過-p將在主機端開啟port 80並mapping到容器中的port 80。
另外當然要掛載容器內的/etc/letsencrypt,用來保留產生的憑證,
由於docker參數中,我加了–rm,當執容器執行完必後,是會自動被移除的,
所以我們要透過-v掛載/etc/letsencrypt來保留設定及獲取憑證。
所以,不需要有網頁伺服器,docker run時,certbot就會獨立生成一台網頁伺服器,作業結束後該主機就被停止。
然後,我們的/etc/letsencrypt上,就有該憑證了。
關於-v左方的/etc/letsencrypt目錄是可以自訂的。
如果我是在自己的家目錄中建了letsencrypt資料夾,就可以設定如下的方式掛載 -v ${HOME}/letsencrypt:/etc/letsencrypt。
${HOME}指的就是我們的家目錄,您可以用MacOS或Linux系統上echo ${HOME}看看。
希望大家能思考及了解參數背後的意義,進而依自己的環境需求調整參數,而不是只調整域名及郵件,就貼上。
情境四、wildcard憑證申請
如果我們要生成任意的子域名憑證(*.ccc.tc),就可以用下方的指令。
wildcard的憑證需採用dns進行challenge,所以您必需要能調整DNS Server,加入他要求的txt記錄進行驗證。
如果您能成功的用docker的方式產生憑證。其實參數都是一樣的,
在無docker的環境,你也可以直接安裝certbot檔,直接使用certbot指令來產生憑證。
把下方整段的docker指令
想成執行certbot指令即可
/usr/bin/certbot
網頁伺服器的憑證設定,不在本篇的討論範圍,但是這裡給大家一點小提示,在第二種的certonly的設定中,
因為產生憑證主機跟網頁主機是同一台上,我們可以直接將憑證設定寫到網頁伺服器的設定中,以Apache為例:
加上排程每天檢測certbot renew及如下指令來重啟主機。
service httpd graceful
如此一來,就可以神不知鬼不覺的自動更新憑證啦。
如果您的主機是nginx,可以用
nginx -s reload
如果是在container(容器)內的主機,我相信這招應該通殺,您或許可以試試 :)