代碼數據存在雲端,如何保障它的安全?
部分企業管理者對於雲端代碼託管存在一絲擔心:我的代碼存在雲端服務器,會不會被洩露?
接下來,我們將從代碼服務及代碼安全角度出發,看看雲效代碼加密技術如何解決這一問題。
一、前言
1. 代碼託管服務
什麼是代碼託管服務?
代碼託管服務是運行在公共環境,提供軟件版本控制管理的服務。
代碼託管服務核心要解決的兩個問題:
- 存檔:需要具備存檔的能力,也就是,把我們當前工作產出的某個副本保存下來,用於複製、追溯等等。
- 協作:可以讓不同的人,基於同一個對象內容進行工作,他們的成果可以一起體現在這個內容之上。
Git 自誕生以來,就和“開源”、“共享”這些詞緊緊地聯繫在一起,它之所以能快速推廣,併成為主流的軟件版本控制工具,正是得益於它改變了傳統軟件版本控制工具的協作方式,讓軟件貢獻與協作變得更加高效與便捷。
2. 代碼託管服務的兩種形態
代碼託管服務通常有兩種形態:
- 使用開源產品或購買私有部署產品,架設在用戶完全可控的部署環境上來提供服務。
- 使用雲託管服務產品,只擁有對服務的使用權,而不必關注服務的運維。
2.1 自建代碼託管服務
代碼資產作為企業資產的重要組成部分,一直備受重視。許多企業、機構都會有自運維的代碼託管服務。無論是從完全控制還是數據安全的心理上來說,私網服務似乎更加可信與無懈可擊,但隨之而來的穩定性、可靠性的問題,卻往往讓中小企業焦頭爛額。
企業發展之初,也許只需要一個服務器資源,搭建一個可用的代碼託管服務,即可滿足一定的日常研發需求;但隨著企業規模不斷擴大,遇到的問題逐步增多,開始需要投入專人來管理這個服務;而企業研發人員發展到千人以上的規模,甚至需要投入一個小的團隊,來負責代碼託管服務的運維及定製化開發工作。這無疑是一筆不小的成本開銷。
此外,由於自建服務配套不完善,很容易產生局部運維權限過大而引發安全風險,刪庫跑路等惡性事件,部分IT從業者可以僅憑一己之力蒸發公司上億的市值,無時無刻在為我們敲響警鐘。
2.2 雲代碼託管服務
而云代碼託管服務,以雲共享的方式,提供更大範圍的服務能力;同時,由於其背後往往都擁有一支經驗深厚的運維管理及產品團隊,其可靠性遠勝於企業自建的託管服務。
但相比較而言,由於雲代碼託管服務對用戶而言只有使用權,無法登錄存儲服務器,無法感知其背後的存儲和複製機制,又由於代碼本身的敏感性,對雲代碼託管服務的信任問題(如認為代碼數據對服務提供方運維人員可見)始終是一些中大型企業的癥結。
3. 代碼託管服務的演進方向
隨著雲計算不斷演進,通過雲原生技術理念的應用可以最大化享受雲計算的技術紅利,包括彈性伸縮、按量付費、無廠商綁定、高SLA等。
而在實踐雲原生理念時,勢必需要:
- 採取DevOps領域的最佳實踐來管理研發和運維流程。
- 通過CICD工具鏈做到應用的快速迭代和持續交付。
GitOps、Iac(Infrastructure as code)現在越來越多地被眾多企業所採納,代碼託管服務也逐漸成為了一種具備軟件版本控制能力與協作能力的存儲基礎設施,其在可靠性及跨地域訪問方面的能力,也逐漸成為各大雲代碼託管服務的核心衡量指標。而這方面的能力,也正是自建代碼託管服務所不能滿足的地方。
那麼,如何打造雲代碼託管安全體系,來提升用戶的信任感呢?
4. 雲代碼託管安全體系
為了更好地支撐代碼託管服務的存檔能力,雲代碼託管體系通常會按照以下四個方面來建設:
訪問安全:
訪問安全包括但不限於認證、權限控制、數據傳輸等等,它主要解決用戶的身份識別,最小限度地賦予指定用戶所需的合理權限,在事前最大程度保證代碼資產的安全性,同時通過對傳輸過程數據加密(如常見的https、openssl加密)等手段,避免中間人截取或篡改用戶的數據。
數據可信:
在訪問安全的基礎上,還需要通過一些額外的手段,確保代碼提交及代碼歸屬的可信度(如僅接受特定屬主的代碼,或要求必須對提交記錄進行GPG簽名),從而進一步降低因為賬號洩露等導致的風險。
存儲安全:
作為雲代碼託管服務最核心的能力,存儲安全不但要保證服務的可靠性,數據資產不丟失,更可以通過存儲快照及備份等手段,降低用戶使用過程中的風險。同時,如何保障存儲於物理設備的數據,不產生數據洩露風險,也是用戶最為關心的問題。
審計風控:
在事前及事中安全能力之外,在事後通過智能化風險識別、主動防禦等手段,進一步加固整個安全防護體系。
在訪問安全、數據可信、審計風控等方便,目前各雲代碼託管服務或多或少的都具備了一些這樣的能力,但我認為,存儲安全才是最核心的競爭力。在這其中,代碼數據加密技術的探索,也是最具有挑戰的。
5. 數據加密技術
通過對數據內容進行加密,並將打開這把鎖的鑰匙,交到用戶手中,是當下眾多雲服務用於解決用戶信任問題的銀彈。為此,具備雲盤加密、雲端加密能力的對象存儲服務更容易被用戶接受,眾數據庫服務廠商(如MySQL、Oracle、PostgreSQL等),也紛紛在自家產品上推出了TDE(Transparent Data Encryption)的能力。
那麼,同樣具備存儲屬性的代碼託管服務,是否也可以引入數據加密的能力呢?
在提供用戶對代碼資產的備份、刪除能力之外,通過數據加密,讓用戶的數據資產僅對用戶自己可見,從而達到對代碼存儲的近完全可控的目的。
二、業界代碼加密方案
1. 客戶端加密
以開源軟件 git-crypt 為代表的客戶端加密方法,是針對敏感信息存儲的不錯選擇。用戶生成一個數據密鑰,用於對目標文件加密,將加密後的內容,提交到git倉庫當中。
在這種模式下,加密的內容,僅提交人可見,而當你需要與他人共享時,可以通過獲取他人的 PGP 公鑰,對用於加密的數據密鑰加密後,提交到代碼倉庫。對方在獲取到數據密鑰密文後,使用自己的PGP私鑰解密,得到數據密鑰,就可以解密數據了。
但這種方式的弊端也很明顯,數據密鑰獲取一次,就可以反覆使用,無法解除授權;原有的文本文件加密後變成了二進制文件,也導致git無法對增量修改創建delta,大量使用及頻繁變更就會導致倉庫體積迅速膨脹。
2. 磁盤加密
磁盤加密技術已經非常成熟,似乎也是一個很好的選擇方案。但磁盤加密僅解決物理設備層面的數據安全問題,在vm(虛擬機)層面,仍然是明文訪問數據的。
3. 服務端閒時加密
對於使用不頻繁的代碼倉庫,閒時加密也不失為一種好的解決方案。在一個Git倉庫不被訪問時,對其進行加密,而當其重新需要被訪問時,就需要等待解密完成,再開放訪問。
這種方案的通用性很高,也可以有很多種加密的方案可以選擇,實現的成本也不高,但缺點也很明顯:倉庫訪問需要一個預熱的過程,倉庫越大,預熱時間也相應越長;高頻訪問的倉庫,幾乎總是以非加密的形態存儲在磁盤上,而這些熱點倉庫,也往往是用戶最為關注,也最不期望被洩露的。
4. 基於JGit、S3的雲存儲加密
AWS的代碼託管產品CodeCommit,提供了代碼加密的能力,它基於JGit實現的代碼託管服務,複用了原有JGit的存儲模型,利用S3的存儲加密能力。
JGit的社區活躍度大大低於Git的社區活躍度,並且在性能對比上,Git也是遠勝於JGit,這也是各大主流代碼託管服務均使用Git的原因。
三、雲端代碼託管的透明加密
雲代碼託管服的透明加密,是一種服務端加密技術(Server-Side Encryption):它使用用戶授權的密鑰來完成對用戶代碼數據的加密;在用戶訪問時,使用用戶的密鑰來對數據進行解密。整個加解密的過程對用戶完全透明,用戶可以使用常規的Git客戶端來進行代碼庫訪問,或是瀏覽代碼服務提供的頁面服務;但用戶保留對數據的完全掌控,可以在必要時,通過取消密鑰授權,達到凍結代碼數據的目的。
1. 雲端透明加密的優勢
Git TDE(Transparent Data Encryption)的優勢:
- 不依賴文件系統。
- 文件系統訪問的數據都是密文。
- 可選擇僅加密一些敏感倉庫來降低對性能的影響。
Git TDE 保護突破了文件系統訪問控制的安全威脅:
- 偷取存儲設備,並且直接訪問代碼庫文件的惡意用戶。
- 通過磁盤備份恢復數據的惡意用戶。
- 保護靜態數據(持久化的數據),對平臺運維人員不可見。
2. 加密方式
採用信封加密[2] 方式進行加解密:
- 由密鑰管理服務KMS產生數據密鑰,並將數據密鑰密文及加密後結果進行存儲。
- 在需要解密時,由KMS解密數據密鑰密文,從而解密加密後的內容。
KMS的加解密,通常用於處理少量的數據;而Git數據量較大,無法直接使用KMS的加解密服務,選擇信封加密來加密數據密鑰便是一個很好的選擇。
3. 密鑰粒度
每個代碼庫一個數據密鑰:一庫一密可以有效避免數據的洩露。
4. 哪些文件需要被加密
Git倉庫中的數據,包括引用數據(HEAD、分支branch、標籤tag等),索引數據(.idx, .bitmap),鬆散對象,打包數據(.pack)。
通常情況下,我們通過 git push
提交的少量代碼修改,都會以鬆散對象的方式存儲,一個鬆散對象文件對應一個用戶側文件實體。在進行垃圾回收 git gc
之後,會對鬆散對象進行清理,同時將他們打包整一個單獨的打包數據(即 packfile)。
那麼,在這種情況下,哪些文件需要被加密呢?
我們認為,分支等引用信息中,不包含敏感的用戶信息,所以無需加密。同時,索引文件僅用於打包數據的查找,也不是用戶信息,無需加密。通常情況下,我們的敏感信息都存儲在較小的文本文件中(如代碼文本),結合性能考量,我們決定:
- 僅加密<10MB的鬆散對象(相當於500萬字中文小說)。
大小 |
壓縮 |
加密 |
鬆散對象 |
Packfile |
< 10MB |
√ |
√ |
√ |
|
10MB ~ 512MB |
√ |
|
√ |
|
> 512MB |
√ |
|
|
√ |
- 對於提交的單文件packfile,不進行加密。(默認情況下,當我們向git服務提交單個大於500MB的文件時,服務端會將其存儲為單文件packfile,而不是鬆散對象,而單個大於500MB的文件,我們可以認為其為二進制資源或者程序,沒有加密的必要)
- 除上述單文件packfile外,其他pack文件均進行加密。
5. 何時加密
當用戶進行代碼提交時,用戶提交數據會先通過SSL/TLS加密,傳輸到代碼託管雲服務,同時獲取數據密鑰,對提交的數據進行加密,而後持久化到磁盤。
6. 如何加密
使用AES(Advanced Encryption Standard)作為我們的首選算法,預計在後續也會增加SM4的支持。
加密模式
使用CTR模式對數據內容進行加密。
密鑰長度
使用256位數據密鑰,由KMS生成,平臺只保存數據密鑰的密文。
7. 加密後效果
打包文件packfile效果:
鬆散對象效果:
8. 加密對性能影響
加密會對倉庫性能產生小幅度影響:
以Git工程的源代碼下載為例,加密後打包階段性能下降約10~20%;但由於下載過程中,網絡傳輸佔據絕大多數的時間(通常佔比90%以上),由加密引起的性能下降在整體使用過程中可忽略不計。
四、我們的代碼託管產品
Codeup代碼加密
雲端加密代碼庫是雲效團隊的自研產品,是目前國內首個支持代碼加密的託管服務,也是目前世界範圍內首個使用實時加密方案的代碼託管服務。
通過在雲端對託管在雲效Codeup 的代碼庫進行落盤加密,可以有效避免數據擁有者之外的人接觸到用戶的明文數據,避免數據在雲端發送洩露。同時,代碼加密過程對用戶完全透明,用戶可以使用任意官方Git端(包括但不限於Git、JGit、libgit2等)來訪問Codeup上的代碼倉庫。
開啟倉庫加密
具有管理員權限的用戶,進入期望加密的具體倉庫的設置頁面可以看到「倉庫加密」開關,點擊打開:
新建倉庫時開啟加密
新建倉庫時支持勾選啟用倉庫加密:
開啟/關閉倉庫加密
具有管理員權限的用戶,進入期望加密的具體倉庫的設置頁面可以看到「倉庫加密」開關,點擊打開/關閉:
關閉加密時,會觸發倉庫的解密操作。
KMS密鑰管理服務
前往阿里雲KMS服務,可以查看到Codeup自動創建的服務密鑰,該密鑰不可刪除和禁用,但可以通過修改KMS服務密鑰的標籤,臨時禁用Codeup對KMS的調用:
點擊④——密鑰詳情,可以看到「標籤」部分有一個Codeup創建的標籤鍵 acs:rdc:git-encryption
:
通過臨時修改或者刪除該標籤值,即可限制Codeup對密鑰的訪問,達到臨時凍結倉庫的目的。