代碼資料存在雲端,如何保障它的安全?
部分企業管理者對于雲端 代碼托管存在一絲擔心:我的代碼存在雲端伺服器,會不會被洩露?
接下來,我們将從代碼服務及代碼安全角度出發,看看雲效代碼加密技術如何解決這一問題。
一、前言
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代碼加密
雲端加密代碼庫是雲效團隊的自研産品,是目前國内首個支援代碼加密的托管服務,也是目前世界範圍内首個使用實時加密方案的代碼托管服務。
通過在雲端對托管在雲效
Codeup的代碼庫進行落盤加密,可以有效避免資料擁有者之外的人接觸到使用者的明文資料,避免資料在雲端發送洩露。同時,代碼加密過程對使用者完全透明,使用者可以使用任意官方Git端(包括但不限于Git、JGit、libgit2等)來通路Codeup上的代碼倉庫。
開啟倉庫加密
具有管理者權限的使用者,進入期望加密的具體倉庫的設定頁面可以看到「倉庫加密」開關,點選打開:

建立倉庫時開啟加密
建立倉庫時支援勾選啟用倉庫加密:

開啟/關閉倉庫加密
具有管理者權限的使用者,進入期望加密的具體倉庫的設定頁面可以看到「倉庫加密」開關,點選打開/關閉:

關閉加密時,會觸發倉庫的解密操作。
KMS密鑰管理服務
前往阿裡雲KMS服務,可以檢視到Codeup自動建立的服務密鑰,該密鑰不可删除和禁用,但可以通過修改KMS服務密鑰的标簽,臨時禁用Codeup對KMS的調用:

點選④——密鑰詳情,可以看到「标簽」部分有一個Codeup建立的标簽鍵
acs:rdc:git-encryption
:

通過臨時修改或者删除該标簽值,即可限制Codeup對密鑰的通路,達到臨時當機倉庫的目的。
