用 letsencrypt-cli Rubygem 在 Nginx 上實裝 Let's Encrypt 免費 SSL 服務

photo by nachans

引用來源:http://ryudo.tw/blog/2016/02/23/apply-letsencrypt-ssl-under-nginx/

Let’s Encrypt 是一個(目前)免費的 SSL 服務,它和其它 SSL 服務商的不同,除了免費之外,就是它需要透過一些方式來驗證你對網站的所有權來申請與更新憑證,而且一次憑證的有效期限(目前)最大是 90 天,也就是說你要持續定期的更新憑證才能使用。

Let’s Encrypt 運作原理

官網所示,比較白話一點的流程大概是:

  1. 用指令向 Let’s Encrypt 要求產生驗證 host example.com 的檔案
  2. LE 給你驗證檔案
  3. 你將檔案放在 http://example.com/.well-known/acme-challenge 下
  4. LE 會發出 HTTP Request 驗證該檔案是否存在前述 URL 下
  5. 如果有,則發放證書

今天要講的是用 Nginx 加上Let’s Encrypt Ruby Cli Rubygem的驗證方法

為何要使用 ruby-letsencrypt-cli 而非 LE 官方版本 CLI

  • 不需要 root 權限即可執行
  • 函式庫相依性較簡單
  • 功能相對單純

安裝 Let’s Encrypt Ruby Cli

安裝方式就是單純的 gem install letsencrypt-cli 即可。

事前準備

  • 安裝好 Gem
  • 預備好以下目錄:
    • key-directory:放 key 的地方
    • webroot-path:在前述的 step 3 給 LE 做 acme-challenge 的檔案放置目錄
    • 放置 account_key 的目錄,通常會放在你的 home
    • 在你要生 SSL 證書的網站的 Virtual Host 的設定內放置以下設定並重啟 nginx,讓 LE 可以用 http://example.com/.well-known/acme-challenge 的網址認證 :
server{
  ...
  location '/.well-known/acme-challenge/' {
    default_type "text/plain";
    alias /var/www/acme-challenge/;
  }
}
  • 註冊 account,執行:letsencrypt-cli register xxx.ooo.com ,產生帳號密鑰 account_key.pem
  • 讓 LE 認證你的網站,執行:letsencrypt-cli authorize --webroot-path /var/www/acme-challenge example.com
  • 生成 key:cd key-directory && letsencrypt-cli cert example.com,會生成:cert.pem chain.pem fullchain.pem key.pem 等四個檔案
  • 設定 Nginx 在 Virtual Host 使用剛才產生的檔案:
    server{
       ...
       ssl_certificate key-directory/fullchain.pem;
       ssl_certificate_key key-directory/key.pem;
    }
  • 重啟 Nginx,完成

更新 Key

執行

letsencrypt-cli manage --days-valid 30 -a :account_key.pem的位置: --webroot-path /var/www/acme-challenge --key-directory /etc/letsencrypt/live :你要更新的 hosts 以空白分隔:

建議把它加到 crontab 中定時執行

問題整理:

  • 執行 letsencrypt-cli 出現 Acme::Client::Error::Malformed 錯誤:請降級你的 json-jwt gem 到 1.5.2
  • 出現 Account Key Note Found:命令列加上 -a :account_key.pem的位置:
  • openssl 版本太舊:openssl 版本建議在 1.0.2 以上,特別是如果要跑 http/2 的話