dehydrated

来自Gea-Suan Lin's Wiki
Gslin讨论 | 贡献2020年11月24日 (二) 15:14的版本 →‎進階設定
跳到导航 跳到搜索
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

dehydrated
原作者 Lukas Schauer
開發狀態 運行中
编程语言 Shell Script
许可协议 MIT license
網站 dehydrated.de
源代码库 github.com/lukas2511/dehydrated

dehydrated是一套支援ACME協定的軟體套件(目前主要是由Let's Encrypt提供服務)。

特色

相較於官方推廣的Certbot使用Python撰寫,dehydrated僅使用Shell Script與OpenSSLcurl的指令就可以執行,這些指令在大多數系統中都已經提供。

安裝

Ubuntu 17.10之後的版本(包含即將出版的18.04)的APT內有dehydrated[1]可以裝,但因為我自己包了一包只有執行檔的(比較小),可以透過PPA安裝:

sudo add-apt-repository -y ppa:gslin/dehydrated-lite; sudo apt update; sudo apt install -y dehydrated-lite

另外也可以直接去官方網站上下載檔案,僅需下載dehydrated檔案。我建議把這個檔案放到/usr/sbin/下。

基本設定

dehydrated在偵測到/etc/dehydrated/config/usr/local/etc/dehydrated/config時(兩個都有時前者優先),會將/etc/dehydrated或是/usr/local/etc當作設定目錄,所以我們需要產生/etc/dehydrated/config,目前裡面不需要有東西:

sudo mkdir -p /etc/dehydrated /var/www/dehydrated
sudo touch /etc/dehydrated/config

進階設定

這邊的設定都是選擇性設定,進階使用者可以修改dehydrated預設值,對安全性與效能的參數進行調整。

config內可以設定開啟憑證內標示一定要開OCSP Stapling:

OCSP_MUST_STAPLE=yes

也可以設定KEYSIZE,預設是4096,可以改成2048:

KEYSIZE=2048

另外也可以指定使用ZeroSSL的CA,其中的EAB資訊xy可以在註冊ZeroSSL後從網頁界面上拿到:

CA=zerossl
EAB_HMAC_KEY=x
EAB_KID=y

域名設定

認證可以透過http-01或是dns-01的協定。無論是那種,都是在domains.txt內設定要申請的網域名稱,裡面一行就是一張憑證,一行如果有多個域名就是將這些域名申請到同一個憑證裡:

一張憑證一個域名

一行放一個域名,將需要申請的網域名稱放到domains.txt內:

cd /etc/dehydrated
echo 'blog.gslin.org' | sudo tee -a domains.txt
echo 'wiki.gslin.org' | sudo tee -a domains.txt

一張憑證多個域名

將想要放在同一張憑證的域名放在同一行,一樣是domains.txt內:

cd /etc/dehydrated
echo 'blog.gslin.org wiki.gslin.org' | sudo tee -a domains.txt

Wildcard

Wildcard的認證一定要有帶有一個主域名(沒有*):

cd /etc/dehydrated
echo 'gslin.org *.gslin.org' | sudo tee -a domains.txt

認證設定

Domain-validated certificate(即DV,非Wildcard的)的可以用http-01或是dns-01的方式認證。Wildcard的只能使用dns-01的方式認證。

http-01

dehydrated預設會用/var/www/dehydrated/作為認證目錄,需要將網頁的/.well-known/acme-challenge/指到這邊。以nginx的設定會像是這樣:

server {
    # ...

    # map /var/www/dehydrated/
    location /.well-known/acme-challenge/ {
        alias /var/www/dehydrated/;
    }
}

Apache的會是這樣(放到/etc/apache2/conf-available/dehydrated.conf內,再用a2enconf dehydrated啟用):

Alias /.well-known/acme-challenge /var/www/dehydrated
<Directory /var/www/dehydrated>
    Options None
    AllowOverride None
    Require all granted
</Directory>

dns-01

dns-01會需要使用TXT record認證。這邊會使用lexicon(不適合用pyenv安裝,因為通常使用root權限跑dehydrated,這會使得環境無法取得),這需要另外安裝。

另外dehydrated需要lexicon的examples/dehydrated.default.sh(將dehydrated的hook命令轉給lexicon使用),所以需要下載這個檔案,複製到/usr/sbin/lexicon-dehydrated.default.sh以便後續更新:

cd /tmp
git clone https://github.com/AnalogJ/lexicon.git
sudo cp lexicon/examples/dehydrated.default.sh /usr/sbin/lexicon-dehydrated.default.sh

或是直接用GitHub提供的連結下載:

cd /tmp
curl -LO https://raw.githubusercontent.com/AnalogJ/lexicon/master/examples/dehydrated.default.sh
sudo install -g root -m 0755 -o root dehydrated.default.sh /usr/sbin/lexicon-dehydrated.default.sh

執行

第一次需要同意條款:

sudo dehydrated --register --accept-terms

之後就可以用-c自動更新:

sudo dehydrated -c

如果是使用dns-01(像是Wildcard),可能需要在環境變數裡提供對應的API token(給lexicon使用):

sudo PROVIDER=digitalocean LEXICON_DIGITALOCEAN_TOKEN=x dehydrated -c -k /usr/sbin/lexicon-dehydrated.default.sh --challenge dns-01

另外因為lexicon在設定DNS的值之後,預設會停30秒才會跑下一步,會比較慢,需要等一下才會知道結果。

自動更新

上面提到更新的指令可以放到/etc/cron.weekly內執行,並且透過傳回值可以判斷是否有更新,然後重跑nginx或是Postfix(以及其他有用到的服務)。

像是:

#!/bin/bash
export PATH=/usr/sbin:/usr/bin:/bin:"${PATH}"
sleep $(expr $(printf "%d" "0x$(hostname | md5sum | cut -c 1-8)") % 86400); dehydrated -c && ( service nginx reload; service postfix reload )

或是:

#!/bin/bash
export PATH=/usr/sbin:/usr/bin:/bin:"${PATH}"
sleep $(expr $(printf "%d" "0x$(hostname | md5sum | cut -c 1-8)") % 86400); PROVIDER=digitalocean LEXICON_DIGITALOCEAN_TOKEN=x dehydrated -c -k /usr/sbin/lexicon-dehydrated.default.sh --challenge dns-01 && ( service nginx reload; service postfix reload )

其中:

  • sleep片段是為了同一個時間連到Let's Encrypt的伺服器造成類似DDoS的效果。
  • sleep後面不使用隨機變數而是使用hostnamemd5sum計算是為了隨機打散,但又要避免很湊巧一堆機器同時打Let's Encrypt的伺服器。

其他

這邊主要是我的個人想法,放在最後避免干擾只是想要學設定方法的讀者。

dehydrated的相依性較少,僅需BashOpenSSLcurl,這三個套件在蠻多Linux作業系統內已經內建,這對於自動化環境帶來的負擔會比較少(指的是Puppet或是Chef這類工具),同時也避免了套件版本互相影響的問題。

目前比較大的問題在於申請Wildcard certificate時,因為需要透過dns-01申請,而這常常會用到lexicon(因為其他使用Shell Script的DNS操作軟體支援度比較低)。但lexicon使用Python撰寫而引用了大量套件,這違背了使用dehydrated的本意(輕量)。

快速安裝

這邊是設定在更新後重啟nginx

sudo add-apt-repository -y ppa:gslin/dehydrated-lite; sudo apt update; sudo apt install -y dehydrated-lite; sudo mkdir -p /etc/dehydrated /var/www/dehydrated; sudo touch /etc/dehydrated/config; sudo dehydrated --register --accept-terms; echo -e '#!/bin/bash\nexport PATH=/usr/sbin:/usr/bin:/bin:"${PATH}"\nsleep $(expr $(printf "%d" "0x$(hostname | md5sum | cut -c 1-8)") % 86400); dehydrated -c && ( service nginx reload )' | sudo tee /etc/cron.weekly/dehydrated-lite; sudo chmod 755 /etc/cron.weekly/dehydrated-lite

參考資料

外部連結