從薪火相傳的密鑰文件到「密碼即服務」

一個可運行的軟件項目一般包括兩個要素:代碼和密鑰。咱們一般會使用無版本控制的FTP有版本控制的SVN、git等成熟的工具進行代碼管理;而在我參加的大大小小、許許多多的項目中,密鑰管理彷佛缺少成熟或標準的實踐。本文將歷數一下筆者在各個使用過的密鑰管理實踐並分析他們的優缺點。最後給你們推薦一款密鑰管理工具:vault。git

在軟件項目開發中,密鑰經常應用於下面四個場景:github

  • 本地開發:一般包括開發環境的數據庫密碼、用於訪問第三方API的token、一些私有程序包倉庫的憑證等。
  • CICD流水線:好比Push Docker鏡像的Docker倉庫的訪問憑證、用於部署的雲服務憑證(AWS Secret等)、用於訪問K8S集羣的token等
  • 運行線上服務:線上服務啓動所需的數據庫密碼、API Token等等,同時可能須要管理用於多套環境的不一樣密鑰。
  • 線上運維:線上發生事故時,須要在本地登入堡壘機(跳板機)的SSH Key或集羣的訪問憑證。

本地開發:「薪火相傳」的密鑰文件

當咱們加入一個團隊時,一般會有一個Readme文檔告訴你項目代碼庫的下載連接。除此以外它會告訴你須要向團隊「前輩」索要密鑰文件,否則你的代碼是不能在本地啓動的。同時有人告訴你,這個密鑰文件千萬不要加入到git倉庫中。docker

這種「薪火相傳」的密鑰管理方式,是最原始也是最多見的方式。它經常會伴隨這樣幾個問題:數據庫

  • 密鑰更換或者引入新的密鑰後,團隊其它成員由於沒有獲得最新的密鑰文件,致使服務在本地起不來。

好比你會聽到這樣的對話:安全

  • A: 「我拉了一下最近的代碼,怎麼就跑不起來了?」
  • 坐在旁邊的B忽然想起了什麼:「好吧,我想起來了!我改了一下數據庫密碼,忘記告訴你了,我把最新的密鑰發給你。」或者「我新加了一個功能由於使用API-KEY要訪問消息隊列,我在本身本地的環境變量裏面加上了這個KEY,忘記告訴大家了」
  • 隨後B把最新的密鑰文件傳給了A。幾天後,同在項目的C也遇到了一樣的問題……
  • 誤提交到代碼倉庫問題:

相信已經不止一次地聽人提醒:千萬不要將密鑰文件明文提交到git。可是密鑰泄露在代碼倉庫的問題依舊時有發生。架構

本地開發:將密鑰加密後存放在Git倉庫

密鑰和代碼同樣,在團隊項目中一樣須要進行共享、同步。密鑰放在git倉庫中原本是能夠解決團隊協做問題的,只不是不能被明文存儲。那麼,若是是將密鑰加密後再提交到git倉庫呢?運維

git-crypt即是這樣一款可將git倉庫中的密鑰文件進行透明加密和解密的工具。它能夠將密鑰文件在push時加密,在pull下來後解密。更多介紹和使用說明能夠參考:github.com/AGWA/git-cr…微服務

藉助git版本控制工具,它能夠實現:工具

  • 使用git進行密碼共享
  • 密鑰的版本控制
  • 用戶權限管理

問題:加密

  • 密碼可能在多個服務中使用,怎麼同步?

持續集成流水線中的密鑰管理

持續集成與持續部署(CI/CD)

在如今的Web項目的CI/CD流程中,一般會將項目代碼通過構建打包生成docker鏡像(製品);在部署階段,不一樣環境會採用相同的docker鏡像,可是會使用不一樣的環境變量(好比集羣、域名、數據庫地址密碼等)傳入到docker的運行時,從而完成在不一樣環境的部署。

環境(變量)在不一樣的CI/CD中有不一樣形式,好比的Jenkins的Credential、GoCD的Environment、CircleCI的Context。

若是將全部的部署與運行時所須要的密鑰數據都保存到pipeline上,會致使下面的問題

  • 過多的密碼字段,將密碼做爲環境變量一個個傳遞到服務十分複雜
  • pipeline存環境變量通常加密後難以解密,若是你設置完本身都忘記了,那這個環境就完全忘了

解決的辦法通常是在pipeline上保存儘可能少的密鑰字段,咱們經過一次認證就能夠具有獲取全部密鑰數據的權限。

密碼即服務:Hashicorp Vault

在雲和基礎設施自動化時代,咱們應該知道一家名爲Hashcorp的公司,其表明做有知名的terraform、consul、packer、vagrant。vault也是這家公司的產品之一,它經過API將密碼以服務的方式暴露出去。它能夠提供:

  • 中心化的密碼服務
  • 更安全的加密存儲
  • 密碼的服務化
  • 豐富的第三方集成:實現認證的擴展、多平臺密鑰管理

Vault架構

服務化後的vault能夠作到

  • 與Github身份認證集成,好比你能夠作到只容許在特定git organization下的用戶才能獲取密鑰
  • 簽發臨時的SSH證書:好比你只容許一個30分鐘內有效的SSH KEY來登陸堡壘機
  • 生成臨時的AWS KEY:好比你只能用一個30分鐘內有效的AWS憑證
  • 按期更換數據庫密碼,由於數據庫長期不更換會加大泄露的風險
  • OTP:基於時間的臨時密碼
  • 密碼權限策略:只容許特定的微服務讀取或者寫入指定的密鑰
  • 密碼的revoke(同事下項目了怎麼辦?)

最佳實踐

  • 不在本地持久化存儲密鑰
  • 密鑰是有時效,按期輪換
  • 密鑰獲取者是有身份的
相關文章
相關標籤/搜索