在 Synology NAS 上設定 Let's Encrypt 憑證

Let’s Encrypt Beta Problem

2016.05.09 Update: Synology DSM 6.0 發佈之後,就已內建整合 Let’s Encrypt 憑證的申請、更新及管理,在多個 domains, virtual hosts 也可以成功運作,更加方便。

2016.01.28 Update: 現在有一個非官方但更方便的工具 – letsencrypt.sh,它是 BASH script,只需要一些大部份機器上都有的 command line tools 就可以執行,在 Synology NAS 上也可以成功的取得憑證,方法請參見:在 Synology NAS 上用 Shell Script Renew Let’s Encrypt

Let’s Encrypt 是一個最近新興的 certificate authority (CA), 他們的一個宏高的理想是 “encrypt the entire web”,提供免費的 SSL 憑證,在幾天前,他們開始了 Beta Program填個資料就可以參加,我收到確認信後,也試著安裝了一下。

和一般的 CA 不同(例如之前申請過的 StartSSL),不是透過 web 來下載,他們提供了一個 python script 讓使用者可以方便的取得憑證,但在 Synology NAS 上並沒有辦法成功的安裝與執行,參考了 mgoerges 的做法,透過另一台機器取得後,再 import 進 DSM 中,以下簡要的記錄一下步驟:

Synology NAS 上的準備

在 vhost 的目錄下(或是另建一個讓 Let’s Encrypt 暫時用的目錄),

$ mkdir -p .well-known/acme-challenge

要暫時讓出 domain 的 http 連線,原本有 mod_rewrite 導到 https 的部份要取消,或是新增繞過 .well-known/acme-challenge 的 rule,有設 HSTS 的也要先取消。另一個做法是把 domain 的 ip 改到另一台機器上,但這樣會連原本還可以運作的 https 連線也會暫時中斷,所以就不採用這種作法。

用另一台 Linux 進行 script

為了讓 python script 可以順利執行,我找了另一台 Linux server (下稱 L), 上面跑的是 Ubuntu 14.04.1。

$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt
$ ./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory certonly -a manual

安裝程式會要求輸入 domain 和同意記錄 IP 位址,之後回到 Synology NAS 上,在 domain 所在路徑下建立一個有特定字串內容的檔案 .well-known/acme-challenge/#{hash_file_name},例如:

Make sure your web server displays the following content at
http://tsai.it/.well-known/acme-challenge/aFQ0LDDkn75K3LmvCIUvEYwq2Op1s9-ullGSwjsh0Is before continuing:

aFQ0LDDkn75K3LmvCIUvEYwq2Op1s9-ullGSwjsh0Is.ONcckxWtBH9uUepl5Eo_BMJHTng23yAdFJ_jVtfSNLg

Content-Type header MUST be set to text/plain.

如果透過 Synology NAS 上的 Apache,預設的 header 就是 text/plain, 不需特別調整。建立完後,回到 L 再繼續下一步。

如果可以成功驗證這個檔案後,script 會自動產生下面四個 certificates 檔:

/etc/letsencrypt/live/${domain}/privkey.pem
/etc/letsencrypt/live/${domain}/cert.pem
/etc/letsencrypt/live/${domain}/chain.pem
/etc/letsencrypt/live/${domain}/fullchain.pem

另外,Beta Program 也會提醒:

IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/tsai.it/fullchain.pem. Your cert will expire
on 2016-02-05. To obtain a new version of the certificate in the
future, simply run Let’s Encrypt again.

在 DSM 上匯入 Certificates

如果要用做整個 Synology NAS 的憑證,可以直接用 DSM 的 GUI 來匯入,將 privkey.pem, cert.pem, chain.pem 上傳即可。

如果要設多個 vhost 的 certificates, DSM 沒有介面可以設定,要直接改設定檔 /etc/httpd/sites-enabled-user/httpd-ssl-vhost.conf-user

在所屬的 ServerName 下加入:

SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/privkey.pem
SSLCertificateChainFile /path/to/chain.pem

缺點是每一次有動過 DSM 的設定,就得要重設並重啟 httpd,有點小麻煩。

照目前的 Beta 計劃,三個月後要 renew 憑證,再執行一次 script 驗證身份即可。暫時可以不需要 CloudFlare 提供的 SSL,如果還是要用他們的 CDN 服務,也可以改用 Strict Mode 來達到更好的安全性。


8 Comments

  • dip987

    2015/11/11

    請教一個問題。依照您的範例,我需要在 acme-challenge 這個資料夾底下新增一個檔案,名稱為:aFQ0LDDkn75K3LmvCIUvEYwq2Op1s9-ullGSwjsh0Is

    但是這個檔案的內容應該要為何呢?

    截至目前所有的操作卡在這邊。在 ubuntu 按下 Enter 之後都會出現下列錯誤訊息

    “Self-verify of challenge failed, authorization abandoned.”

    Thanks

    Reply
    • tsaiid

      2015/11/11

      python scrip 會提示你建立一個檔案,它應該是一串亂碼,請不要用上面的例子當做檔名,因為每一次執行 script 的檔名都會不一樣。

      至於內容,也是會在提示中出現。以我上面的例子,我要建立的檔名是 aFQ0LDDkn75K3LmvCIUvEYwq2Op1s9-ullGSwjsh0Is 而內容是 aFQ0LDDkn75K3LmvCIUvEYwq2Op1s9-ullGSwjsh0Is.ONcckxWtBH9uUepl5Eo_BMJHTng23yAdFJ_jVtfSNLg

      Reply
      • dip987

        2015/11/11

        Hi,看來我的理解是沒有錯誤的。但是不曉得為什麼還是會授權失敗。
        我的是 DSM 6.0,安裝 web station 套件。啟用個人網站服務
        然後在 volume1/web 底下新增 .well-known/acme-challenge 資料夾
        接著用 ubuntu 15.1 x64 執行 ./letsencrypt-auto –agree-dev-preview –server https://acme-v01.api.letsencrypt.org/directory certonly -a manual

        會出現視窗,輸入參加 beta 的 domain,接著會出現 IP 確認。點選 Yes
        就會出現如您的教學範例。在 acme-challenge 資料夾底下新增檔案。名稱為 aFQ0LDDkn75K3LmvCIUvEYwq2Op1s9-ullGSwjsh0Is

        然後內容為 aFQ0LDDkn75K3LmvCIUvEYwq2Op1s9-ullGSwjsh0Is.ONcckxWtBH9uUepl5Eo_BMJHTng23yAdFJ_jVtfSNLg

        接著按 Enter。就出現 “Self-verify of challenge failed, authorization abandoned.”

        Reply
        • tsaiid

          2015/11/11

          我不太清楚為什麼你的認證檔的檔名和內容會和我的一樣,理論上不應該相同的。

          如果你可以正確存取到 「http://你的domain/.well-known/acme-challenge/你的檔名」 這個 url,而且內容是你剛剛填入的,應該就可以認證。除非你的 header 不是 plain/text。

          Reply
          • dip987

            2015/11/11

            Hi

            我只是您的範例來當舉例而以。那串亂碼每次都會不同。不過後來問題解決了…
            我猜想應該是在 console 底下 touch 那個檔案的格式不是 UTF-8。我後來用 文字編輯器 修改格式之後就正常了。

            感謝您的教學 :)

  • 黃彥儒

    2015/11/20

    希望有人可以寫個程式讓我們可以直接取得密鑰內文

    Reply
    • tsaiid

      2015/11/20

      的確,這樣可以省下一些工夫

      Reply
  • Pingback: 在 Synology NAS 上用 Shell Script Renew Let's Encrypt | I-Ta Tsai's Blog

Leave a Reply