[教學] 家用免費CA signed SSL Certificate

本帖最後由 blaze 於 2020-9-1 23:03 編輯

終於有時間坐低寫個長po,遲咗啲大家見諒!原po都有唔少ching分享心得,多謝大家。

「點解要用SSL/TLS證書」
如果你唔知咩係SSL/TLS,建議你先停一停,Google攞個background ,睇吓你需唔需要先。
有免費SSL,梗係有唔免費㗎啦!依家啲SSL Certificate(證書/憑證)其實都可以好平,幾蚊美金一年有交易,仲有啲有賠償保障!幾個host/alias的話,DV wildcard都affordable(你用得幾部機嘅話,都應該付擔得起嘅!)。

「咁仲要免費SSL? 」
除咗因為「我就是可以」、「唔想課金」、「想落手落腳」呢啲咁個人嘅理由之外,其實我個人覺得現今科技,安全性好基本,已經唔單單只係講功能性同埋可用性。每一個product同setup都應該“Secured by Design”。SSL/TLS呢啲基本嘢好應該係免費或者低成本做到!保護自己嘅data最正確不過!再者,小數怕長計,既然自己做到就get my hands dirty!

「免費嘅嘢得唔得㗎 ?」
當然係有伏位。”免費SSL”大概可以分為兩種。一種係”self-signed”,另一種就係透過一啲提供免費服務嘅 Certificate Authority CA (證書頒發機構),用certbot獲取。私人用基本上都冇問題!而依個po講嘅係後者。

其實依類型嘅免費CA服務唔計個別機構已知嘅漏洞,係佢地面世嗰陣時係的確有俾人濫用。之前有啲不法之徒恃住呢一樣嘢成本低,申請一啲domain name近似嘅certificates例如 google.com vs g00gle.com,嘗試透過釣魚電郵誤導用家去自己嘅網站,偷人地嘅密碼同埋其他資訊。呢啲安全性嘅問題,就超越左呢一個po嘅範圍,唔多討論。大家記住 ”There is no free lunch!”!食得鹹魚抵得渴!

仲有好重要,免費certificate一般都唔會有好長嘅有效期,我見過30日至90日不等。相信係防止濫用同埋本身服務上可以控制成本。呢一個po當然會講埋自動renew!

「講咁多嘢,呢個教學有咩用?」
原Po 可見大家家用寬頻有唔同程度嘅限制,如果你已經可以用到NAS自帶嘅免費SSL功能,可略過此po。但都講吓依個po響咩情況應該幫到手,基本上申請確認同續期可以透過ACME工具進行,最多採用嘅有HTTP-01(需要web server)同DNS-01(用上DNS record)兩種方法去證明你對指定domain嘅擁有權。依個po係用上DNS-01去處理,點解?


  • NAS自帶嘅免費SSL功能用唔到。可以係你唔想開port80/443、external port被佔用或者俾ISP block咗port
  • 有幾部server響同一個LAN裏面NAT,想獨自acquire 同renew
  • ?? 想要多幾個Subject Alternative Names (SAN ) - 可能原生或者其他方法都得,我冇驗證過


有冇限制?概括一吓用後感:
1. 唔可以用LAN上面嘅hostname放入SAN,更加唔可以放IP address
2. 因為每一個SAN都要認證,所以唔可以亂咁放,例如放埋自己個DDNS domain
3. 如果得一張cert但係又冇得隨便設定SAN,一係就要經過full domain address入server,一係你就每一次入嗰陣時接受browser提你有風險。再複雜就自己簽多一張cert包灑啲internal hostname, IP address加上reverse proxy指定用邊張cert。

「帶個頭盔同埋俾返啲Credit人哋先」
此文純粹技術同埋經驗分享,各位隨便參考。本人不會附上所有因為參考此文或者此文提及嘅其他文章或資源等而發生問題所衍生嘅任何責任。此文參考xfelix.com亦有參與該文之討論。另外參考acme.sh之說明。各位請參考佢哋各自嘅使用條款。

本帖最後由 blaze 於 2020-9-1 23:02 編輯

所需資源:

  • 行到Docker嘅NAS或者其他server。小弟偏好Synology。
  • 擁有或者一個你控制到嘅domain(域名),支援DNS API。小弟偏好Cloudflare。

    • 如果你用嘅domain name服務唔支援API,acme.sh 另提供DNS manual模式,大家可以自己參閱

  • 知道你NAS裏面”root”密碼。以Synology嚟講,即係”admin”密碼
  • 有電腦可以SSH去NAS (準備呢一個分享嘅時候其實好似見到acme.sh支援Synology certificate install。應該可以唔使SSH,但係有見到manual話DSM upgrade之後要整啲嘢。感覺上未係太成熟,所以唔睇住)


步驟一:準備acme.sh Docker container

  • DSM安裝Docker app。
  • Docker app增加image(映像檔):

  • 去Image利用啱啱下載嘅image點一下”Launch”(佈署)建立一個container
  • 憑自己喜好俾個名(我喺呢度用CONTAINER_NAME做例子)同埋限制資源(好少已經夠,我自己比最低CPU, 48MB RAM)
  • 選”Advanced Settings” (進階設定):

    • Volume (儲存空間):”Add Folder” () > ”Create Folder” () e.g. /docker/acme。之後啲config, certificate同埋key都係喺呢一度generate。”Mount Path” () 輸入 "/acme.sh",不要選”Read-Only”
    • Network (網路):選取 ”Use the same network as Docker Host” (與 Docker 主機同一網路)
    • Environment (環境設定):Command (指令)裏面輸入"daemon"
    • 最後,完成之前唔好選擇建立後run


步驟二:準備DNS Account ID、API key,配置acme.sh

  • acme.sh需要Zone:Zone:Read, and Zone:Dns:Edit permission權限。去Cloudflare dashboard用相關設定去generate一個Application Token
  • 2. 亦都記低自己嘅Account ID
  • 3. 開一個文字檔案,名為”account.conf”,放進之前剛建立的資料夾 e.g. /docker/acme/。文字檔內容包括API Token及Account ID如下:
    1. export CF_Token=“xxxxxx”
    2. export CF_Account_ID=“yyyyy.”
    複製代碼


步驟三:獲取certificate同埋key

  • 開Docker裏面嘅Container部份,你會見到啱啱建立嘅container。打開container然後Start(啟動)。
  • 去Terminal (終端機) tab (頁籤),Create (新增) Launch with Command (使用執行指令),輸入"sh"跟住 Ok。
  • 輸入
    1. acme.sh --issue --dns dns_cf -d SUBDOMAIN.YOURDOMAIN.COM
    複製代碼
  • Certificate同埋key將會自動生成然後儲存到呢個目錄"/volume1/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/"


步驟四:安裝certificate同埋key

  • DSM Control Panel (控制台)裏面Security(安全性)有一個Certificate嘅tab
  • 安裝certificate選擇Add(新增),俾個自己認得嘅Description (描述),選擇Import(匯入) 步驟三第四點提及嘅path搵到嘅檔案,對應如下,揀啱檔案”Ok”

    • SUBDOMAIN.YOURDOMAIN.COM.key -> Private Key (私鑰)
    • SUBDOMAIN.YOURDOMAIN.COM.cer -> Certificate
    • ca.cer -> Intermediate Certificate (中繼憑證),呢個其實唔一定要填

  • 去返個Docker,可以Stop(停止)頭先嗰個container。
  • 最後,條private key應該要從 "/docker/acme/SUNDOMAIN.YOUDOMAIN.COM" 移除或者移到一個安全嘅地方。否則俾人偷咗嘅話係一個安全隱患。


恭喜你!你已經成功將一張免費嘅CA signed SSL certificate擺咗入去呢個NAS!
至於點樣用,就唔喺度詳細講喇。按理呢啲嘢你應該一早識做先至會嚟睇依一個po。如果依張係你第一張cert,DSM應該自動幫你設定為default cert,所以SSL服務都用佢。但係基本來講,DNS CNAME/A record對你嗰個router/firewall external IP,而你部router/firewall設定好port forward,響Control Panel 裏面Security>Certificate嘅tab設定好乜嘢服務用邊一張cert應該就冇咩問題。

好喇,到最後一個步驟!亦都係最麻煩,因為需要SSH去NAS!

步驟五:設定自動renewal
DSM 6.2 以後佢支援多張certificate,所以要先搵出剛才import嗰啲cert同埋key放響邊度!

  • 響Control Panel嘅Terminal (終端機) & SNMP裏面打開SSH選項
  • 喺自己部電腦度開個command prompt / terminal (Win10, macOS built-in已經有SSH client)
    [list=2]
    1. ssh -l USERNAME [Your NAS’s IP]
    複製代碼
  • USERNAME要喺 NAS 嘅 administrators 群組裏面

  • 提升自己嘅權限去root
    [list=2]
    1. sudo -i
    複製代碼
  • 要入返USERNAME嘅密碼

  • 確認一下頭先generate嗰啲cert同埋key嘅path
    1. cd /volume1/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/
    複製代碼
  • 再去搵出import咗嘅cert同key放喺邊度
    [list=2]
  • 首先
    1. cd /usr/syno/etc/certificate/_archive/
    複製代碼
  • "ll" 睇吓裏面有乜嘢,如果你只係得一套certificate,你應該只會見到一個folder,而個名係一串似乎係random嘅六位英數
  • 萬一有多個一個的話,可以睇吓裏面啲檔案嘅timestamp,或者睇吓一個叫做INFO嘅檔案,裏面有描述。”desc”應該係你頭先步驟四第二點import cert同key嘅時候自己打。
  • 因為依個folder名個個都唔同,我喺呢度俾個名佢 RANDOM_PATH
  • 最後我哋去Control Panel裏面嘅Task Scheduler(任務排程表)加一個Task:
    [list=2]
  • Create (新增) > Scheduled Task (排程任務) -> User-defined Script (使用者定義指令碼)
  • General (一般設定) tab:Task (任務名稱) 俾一個你認得嘅名,User (使用者帳號) 選擇”root”,選擇Enabled (已啟用)
  • Schedule (排程):Date(日期)選擇Run on the following date (在以下日子執行),揀選一個日子同埋選擇”Repeat monthly” (每月重複)。時間方面可以自行選擇。
  • Task Settings (任務設定):Send run details by email (透過電子郵件傳送執行細節) 我一般都會打開,可以睇吓行咗啲乜嘢。User-defined script如下:

    1. echo
    2. echo Let’s Encrypt SSL Certificate Renewal
    3. echo
    4. echo Starting docker container CONTAINER_NAME with acme.sh in daemon mode…
    5. echo
    6. docker start CONTAINER_NAME
    7. echo
    8. echo Sleep for 2 minutes…
    9. sleep 2m
    10. echo
    11. echo Execute acme.sh renewal command for SUBDOMAIN.YOURDOMAIN.COM using DNS-01 with Clareflare hook…
    12. echo
    13. docker exec CONTAINER_NAME acme.sh --renew --dns dns_cf -d SUBDOMAIN.YOURDOMAIN.COM
    14. echo
    15. echo Sleep for 2 minutes…
    16. sleep 2m
    17. echo
    18. echo Attempting to overwrite public certificate…
    19. echo
    20. rsync -avh /volume1/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/SUBDOMAIN.YOURDOMAIN.COM.cer /usr/syno/etc/certificate/_archive/RANDOM_PATH/cert.pem
    21. #echo
    22. #echo Attempting to overwrite private key…
    23. #echo
    24. #rsync -avh /volume1/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/SUBDOMAIN.YOURDOMAIN.COM.key /usr/syno/etc/certificate/_archive/RANDOM_PATH/privkey.pem
    25. echo
    26. echo Attempting to overwrite certificate chain…
    27. echo
    28. rsync -avh /volume1/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/fullchain.cer /usr/syno/etc/certificate/_archive/RANDOM_PATH/fullchain.pem
    29. echo
    30. echo Attempting to overwrite CA certificate…
    31. echo
    32. rsync -avh /volume1/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/ca.cer /usr/syno/etc/certificate/_archive/RANDOM_PATH/chain.pem
    33. echo
    34. echo Attempting to remove the private key from docker folder and modify file permissions to owner read-only
    35. echo
    36. #rm -v /volume1/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/*.key
    37. chmod 400 /usr/syno/etc/certificate/_archive/RANDOM_PATH/*
    38. echo
    39. echo Attempting to restart web server…
    40. echo
    41. /usr/syno/etc/rc.sysv/nginx.sh reload
    42. echo
    43. echo Stopping docker container…
    44. docker stop CONTAIN_NAME
    45. sleep 2m
    46. echo
    47. echo Bye!
    複製代碼
    響個script裏面有幾句係comment咗 (i.e."#" 開頭)係因為xfelix.com原文使用acme.sh既force issue重新簽新嘅certificate包括重新generate public/private key pair。我自己唔太鐘意依個方法,所以自己改做renewal。如果大家想用force issue,可以將 "docker exec" 裏面嘅 "--renew" 改為 "--issue --force" 。其他comment咗嘅都要攞走個"#"因為要update埋條private key同埋移除 "/docker/acme/SUBDOMAIN.YOURDOMAIN.COM/" 裏面嘅private key。

    攪掂!

    希望大家睇得明我寫啲咩嘢!Happy hunting!
  • TOP

    thanks share!!!!
    用緊 lets encrypt , Free
    不過學多樣野 thanks!!
    REF: https://www.minwt.com/website/20735.html

    TOP

    回覆 2# blaze


        多謝Ching

    TOP

    Good!Thanks

    TOP

    Thank you for share

    TOP

    Thanks Ching

    TOP

    Thanks Ching for such a great post !

    TOP