let's encrypt萬用字元證書自動續期工具支援騰訊雲DNS了
一個多月前,我寫了一個證書管理工具,用於自動續期 let's encrypt 萬用字元證書,彼時只支援阿里雲 DNS,今天該工具也支援騰訊雲 DNS 了。
該工具支援三種使用策略:
- 支援 Shell+PHP 操作阿里雲 DNS。
- 支援 Shell+Python 操作阿里雲 DNS。
- 支援 Shell+PHP 操作騰訊雲 DNS。
該工具託管在Github 上,如何使用請查閱 README.md 文件,README.md 會隨時更新,考慮到公眾號文章不能修改,所以本文不介紹該工具的使用方法了。
介紹該工具只是一個引子,主要想分享對於 Github 的一些零碎想法。
1:一些資料
一個月下來,該工具收穫了 11 個 star、5 個 fork、1 個 watch、7個 issues,說實話,感覺還是很激動的。
作為一個小眾的工具,受到不少人的關注,說明越來越多的人在關注免費 let's encrypt 證書了,而自己寫了不少關於 let's encrypt 的文章,在推進 HTTPS 普及方面做了一些工作,也體現了一定的個人價值。
2:Github 是一個社交工具
Github 不僅僅是一個開原始碼託管網站,更是一個軟體協作平臺,來自地球任何一個地方的人,只要對你的專案感興趣,可以通過 Github 和你溝通,給你提 issues 和 pull request。
以這個工具來說,其中三個人指出了工具存在的 Bug,體現了人多力量大;另外一個人提出了一個疑問,讓我意識到在某些方面沒有考慮全面,進而完善了該工具;最讓我意外的是 @Duke-Wu 提交了一個 PR,從而讓工具支援 Python 操作環境;最後一個人諮詢是否能夠支援騰訊雲 DNS,自己原來也考慮過這個需求,但一直遲遲沒有開發,看到有使用者也有這需求,立刻花費一個晚上搞定了。
3:Github 上應該放什麼樣的程式碼
以前和同事討論過,在 Github 上放什麼樣的程式碼(專案)才能受人關注呢?其實,我覺得不能太功利和刻意,託管的程式碼要能解決實際的問題,解決的問題是大是小並不重要,重要的是能幫助到人。
以我這個工具為例,最初只是為了解決自己遇到的問題,那時 let's encrypt 支援萬用字元證書特性並不久,當我續期的時候發現 renew 失敗,由於我對 let's encrypt 有一些研究,僅僅花了半天就解決了。但想到很多人也可能遇到同樣的問題,是否可以將解決方案整理成工具放到 Github 上呢?這就是最初的設想,完全是順其自然的。
我不太建議在 Github 公共倉庫上放一些寫給自己的程式碼,如果程式碼的受眾可能只有自己一個人,那建議放在私有倉庫上。在平時工作過程中,可以將通用的一些解決方案抽象、彙總並放到 Github 上。
4:README.md 很重要
從我的角度來說,寫這個工具並沒有花費太久的時間,反而是 README.md 反反覆覆修改了多次,花費了很多心力。
README.md 就是告訴人如何使用該工具,在編寫的時候要考慮受眾,比如多問自己幾個問題:
- 受眾知道萬用字元證書的含義嗎?
- 受眾知道 certbot 工具如何安裝嗎?
- 工具支援多種操作環境(騰訊雲、阿里雲、Python、PHP),在介紹的時候如何不冗餘又保持精簡呢?
- 受眾只是為了快速解決遇到的問題,不願意看長篇大論的介紹吧?
綜合考慮了這些問題,大家覺得目前的 README.md 如何,我希望達到幾個目的:
- 使用人能夠快速上手,即使不理解原理也可。
- 文件簡潔,不冗餘。
- 如果想全面瞭解萬用字元證書,這個文件也是最好的輔助學習資料。
5:一種優良的學習方式
長話短說,在 Github 中衝量是最好的學習方式,關於這點,每個人都會有所體會,我簡單列舉幾點。
(1)在 Github 放入的程式碼至少要體面一點吧,比如 commit 訊息要寫的完善一點,培養良好的變成習慣,如果沒有約束(所有的 Github 使用者可能會看到你的程式碼,這就是最大的約束),那開發程式碼的時候很難保持自律。
(2)能夠學習到很多優秀的編碼
我最近在寫一個小工具,其中使用了 PHP 中的名稱空間特性,看手冊感覺很簡單,但實際編寫的時候感覺理解的並不是很充分,有點難以上手的感覺,後來我借鑑了很多 Github 上的程式碼,看它們是如何組織名稱空間的,並從中收穫了很多,這就是 Github 的優勢。
(3)Github 基於 Git,如果你想學習 Git,根本沒有必要自己構建一個 Git 伺服器,Github 就是最好的 Github 伺服器。
學習使用 Github,同時又能學習 Git,何樂而不為呢?對於我來說,儘量通過命令列方式使用 Github,儘量少使用 Web 介面操作 Github。
(4)能夠基於 Github 學習到很多軟體開發模式、流程、方法,比如 PR、Issues、Wiki 這些都是 Git 沒有的。Github 以 Git 為基礎擴充了很多功能,讓開發者進一步離不開 Github,這就是他的偉大之處。
大家可以去GitHub Marketplace 看下,基於 Github 出現了很多工具,這些工具對於軟體開發非常重要,形成了完善的軟體開發體系。
6:動力
我想指出一點,花在 Github 上的時間不會佔用你平時工作、生活的時間,因為這些時間都時擠出來的,原因就在於動力十足,從時間管理的角度來看,動力讓你的效率得到極大的提高,也能充分利用時間。
動力來源於內在、外在,外在動力非常重要,以這個工具為例,當 star 數遞增的時候,當用戶對該工具有進一步期望(比如期望支援騰訊雲DNS)的時候,我就使用平時睡覺的時間解決了,這完全是擠壓出來的時間,每天的成就感也得到了滿足。
那麼內在動力在哪兒呢?對於開發者來說,是否擁有自己的 Github 非常重要,類似於簡歷但比簡歷更重要,因為簡歷可能造假、可能只能代表你以前的成就,而 Github 上的成就是無法偽造的,通過 Github 能夠看到你最近幹了些什麼,能夠看到你的程式碼編寫風格,能夠看到你的專業性,這是評價開發者專業能力最好的手段。
對我來說,Github 是學習和進步的源泉,也是找工作的利器,我也希望好好經營我的 Github,這就是最大的內在動力。
7:API 呼叫身份驗證的策略
這個工具讓我對阿里雲和騰訊雲 API 呼叫有了一些瞭解,API 呼叫的時候是如何對呼叫者身份驗證的呢?背後的密碼學演算法就是訊息驗證碼(MAC),它能夠保證訊息的完整性,避免訊息被篡改,需要注意的是訊息驗證碼並不是為了資料加密。訊息驗證碼傳送者和接收者必須擁有同一把金鑰,才能校驗訊息的完整性,這就是訊息驗證碼演算法的全部。關於訊息驗證碼的概念、使用方法可以參考我的書《深入淺出 HTTPS:從原理到實戰》。
不管是阿里雲還是騰訊雲,使用者如果想呼叫 DNS API,必須先申請 APP 金鑰(key),這個 key 必須保持私密,一旦洩露,所有的加密學演算法將一無用處,對於靜態金鑰,有幾個建議:
- 定期變更金鑰。
- 核心員工離職的時候,必須儘快變更金鑰。
- 每個專案使用獨立的金鑰。
- 金鑰的儲存非常重要,比如不要通過郵件傳遞。
- 該 API 金鑰不要明文儲存在程式碼倉庫中,可以使用對稱加密演算法對 API 金鑰加密後儲存在程式碼倉庫中,程式碼倉庫中同時儲存對稱加密演算法的金鑰(很拗口吧)。這樣即使攻擊者獲取到加密的 API 金鑰也無法反解出 API 金鑰。
這些就是 API 金鑰安全使用的一些建議,那麼阿里雲、騰訊雲是如何具體使用訊息驗證碼保護 API 呼叫的呢?
API 呼叫方:
- 根據具體 API 引數說明,拼裝 API 引數(比如 GET、POST)。
- 新增公共引數,比如 Nonce 引數是為了防重放。
- 對所有 API 引數(比如 GET、POST)進行排序,然後拼裝成一個原始字串。
- 對原始字串進行訊息驗證碼運算(包含 API 金鑰),然後進行 base64 運算,得到簽名字串。
- 將簽名字串作為 API 的一個引數和其他引數結合起來傳送 API 呼叫。
API 接收方(阿里雲或騰訊雲)
- 同 API 呼叫方一樣,根據接收到的引數(去除簽名值引數)計算出簽名字串。
- 將計算出的簽名字串和接收到的簽名值進行比較,相同代表校驗通過,反之校驗失敗。
具體的簽名示例可參考