應用上雲,怎能沒有容器!點擊上方

容器魔方

關注我

1.1問題

在使用

Docker

運行容器化應用時,宿主機通常先要從

Registry

服務(

如Docker Hub

)下載相應的鏡像(

image

)。這種鏡像機制在開發環境中使用還是很有效的,團隊成員之間可以很方便地共享同樣的鏡像。然而在實際的生產環境中,當大量主機需要同時從

Registry

下載鏡像運行容器應用時(比如發布新版本,打補釘等情形),

Registry

服務往往會成為鏡像分發的瓶頸,應用鏡像需要較長時間才能傳送到所有主機上,使得應用發布的周期大大延長。

不少企業提出了

P2P

加速鏡像下載的解決方案,但都是私有雲及內部環境的使用場景,在公有雲未得到使用。其中很大一部分原因是共有雲使用P2P的安全性問題,如何確保用戶數據在P2P傳輸中是安全的成為了其中的難點。

我們就該問題設計實現了確保用戶數據安全的P2P鏡像分發系統。本文就其安全性展開闡述。

1.2 架構

華為P2P容器鏡像分發系統示例圖

華為P2P容器鏡像分發系統包含3個組件:客戶端代理(Proxy)、BT客戶端和BT Tracker。

客戶端代理(Proxy)

客戶端代理部署在集群的每個節點中,配置為Docker的Http Proxy,截獲Docker Daemon的鏡像下載請求,通知Client下載,並最終將鏡像導入到Docker daemon中。

BT客戶端

部署在集群節點的BT客戶端和Tracker共同組成了一個完整的P2P文件傳輸系統。在整個鏡像的分發過程中,它們利用BT協議完成鏡像下載。

BT Tracker

Tracker是BT系統的一部分,它存儲了BT客戶端下載過程中所需要的元數據信息和種子信息,並協助各個BT客戶端完成整個通信過程。

1.3安全

首先,我們限制了跨集群的P2P下載,最大限度的租戶間的數據泄露。

之後,在鏈路層面的安全性和業務層面的安全性做了增強。

1.3.1

鏈路安全

一想到鏈路安全,我們首先會想到的是加密。

對稱加密服務端和客戶端採用相同的秘鑰加密和解密,只要這個秘鑰不公開,並且秘鑰足夠安全,那麼鏈路就是安全的。但是在網路中都使用相同的對稱加密秘鑰,無異於公開傳輸,如果秘鑰被劫持,那麼就可以篡改鏈路的所有數據。

然後我們肯定會想到HTTPS,它是怎麼實現安全的?我們先來了解下HTTPS的實現方式。

在具體的數據傳輸過程中,HTTPS採用的是對稱加解密的方式,但是它在連接建立時增加了握手協商的過程。

什麼是公鑰?

公鑰是非對稱加密中的概念。

非對稱加密演算法方式基於一個秘鑰對,數據通過一個秘鑰加密,只有通過另外一個秘鑰才能解密。服務端保存私鑰,公鑰發給客戶端。

我們假設一個場景,我們生成秘鑰對,客戶端通過公鑰加密數據,服務端通過私鑰解密。那麼即使用戶劫持到公鑰,他無法劫持篡改用戶的數據。然而從服務端到客戶端的鏈路還是不安全的。

HTTPS

藉助了非對稱加密的這個特性,確保對稱機密秘鑰的傳輸是安全的,最後採用對稱加密傳輸數據。

證書的意義

然而,這又產生了一個新的問題,公鑰被劫持了怎麼辦?

HTTPS當然不會這麼簡單就被劫持,為了解決上訴問題,它引入了數字證書和第三方機構。證書是由第三方認證機構通過公鑰簽發的,其中不僅包含公鑰,還包含簽名( 由簽發節點的私鑰加密產生)、有限期、簽發機構、網址、失效日期等。

HTTPS

返回的不在是私鑰,而是證書。當客戶端接收到證書,會對證書做一個校驗。在各個機器中都會維護一個權威的第三方機構列表(包括它們的公鑰),當客戶端需要公鑰時,可根據頒發機構信息本地查找到公鑰。客戶端通過頒發機構的公鑰驗證簽名的有效性和證書的完整性,保證公鑰未被篡改。

HTTPS

通過私鑰、證書、和CA(簽發機構)確保了鏈路的安全性。在P2P場景下,BT Client之間是對等的,他們相互傳輸數據,更應該是服務端校驗客戶端,而不是HTTPS的客戶端校驗服務端。並且由於BT Client是部署在用戶的節點,還需要考慮證書和私鑰都被劫持的風險。

我們是怎麼做的?

●  Client之間

BT Client間傳輸數據肯定是需要加密的,防止鏈路的數據被劫持。但是只增加HTTPS,雖然鏈路被加密,但是客戶端可能會被假冒,只要假冒者不校驗服務端的證書,直接和服務端握手,就能從其他BT Client獲取到他想要的數據。

我們借鑒和HTTPS的實現,採用了雙向驗證的模式。

需要有證書,首先需要一個統一的CA(簽發機構),因此我們在Tracker中保存證書和私鑰做為簽發機構,Proxy獲取種子的同時返回CA,用戶校驗客戶端的證書。

然後,只使用一個證書對並且放在Bt Client是危險的,很有可能性被入侵截獲到證書,因此我們獲取證書的方式改為從Tracker獲取,獲取種子的同時獲取Tracker生成的臨時證書私鑰對,把它加入BT Client的下載隊列。在BT Client開始相互連接時,首先相互確認對方的證書的有效性(簽名、簽發機構等信息),校驗通過後才能請求並相互下載數據。

這種方式下,Client之間的鏈路是安全的。

1.

鏈路經過證書加密,直接截獲鏈路是不可行的

2.

即使仿照BT Client的方式,由於Client每個連接都需要進行雙向的證書校驗,想通過這個方式截獲數據就必須請求Tracker去獲取,而訪問Tracker首先是HTTPS的,然後我們還做了業務層的安全校驗(下文業務層安全會提及),也是不可行的。

● Docker Daemon 到 Proxy

我們在Proxy中需要劫持Docker的請求,因為Docker在不配置時訪問Registry採用的是HTTPS,因此Proxy劫持Docker請求就必須和Docker保持HTTPS連接。

我們讓客戶端代理只監聽localhost埠,杜絕外部使用該代理的可能性。同時,客戶端代理綁定一套臨時生成的簽發給registry域名的自簽名證書和CA證書,用於劫持Docker Daemon的請求,並將CA證書添加到機器的信任證書當中。

代理綁定的證書只保存在內存中,即使通過特定方式獲取到當前節點的CA證書和服務端證書,也無法截取其他節點數據。

● 從用戶節點到Registry、Tracker

首先,為了確保鏈路的安全,

Regstry、Tracker

都綁定從權威第三方機構購買的

HTTPS

證書私鑰對。

Proxy和BT Client

在訪問它們的時候都會去校驗證書的有效性,只要在證書有效的情況下才發送請求,這從根源上杜絕了

Regstry、Tracker

被假冒的可能。

1.3.2業務加密

在確保鏈路安全後,我們還做了一層業務安全加固。首先我們先了解下

JWT Token

Json web token(JWT)

是為了網路應用環境間傳遞聲明而執行的一種基於JSON的開發標準(RFC 7519),該token被設計為緊湊且安全的,特別適用於分散式站點的單點登陸(SSO)場景。

JWT

的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源伺服器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。

在我們使用Docker命令下載鏡像時,Docker首先會到Registy獲取Token,在之後的獲取鏡像層的過程中,多會帶上該Token用於鑒權。

其中Token時組要包含以下信息:

1.用戶信息

2.資源信息,為操作的鏡像和namespace的名稱

3.許可權信息:是否有PULL/PUSH許可權

4.用於解析Token簽名的證書

利用JWT Token中自帶解析Token證書這個特性,我們在BT Client間通信又增加了Token的校驗。在前文中的證書校驗通過後,客戶端需要發送Token給服務端用於校驗。為了防止Token被假冒,入侵者採用第三方生成,我們使用服務端截從Docker截取的Token中的證書解析校驗客戶端的Token,杜絕這種情況。

同時,Proxy 訪問Tracker的介面也會帶上這個Token,Tracker會校驗Token的許可權,完成業務層的安全驗證,防止證書和種子被盜取。

總結

通過以上鏈路層和業務層的安全加固,用戶數據被盜取的可能性已幾乎為零。如果大家有更好的建議,歡迎點評。

推薦閱讀

P2P-如何拯救海量k8s鏡像分發的阿喀琉斯之踵

如何實現雲上編排系統

為什麼雲上需要自動化???

點擊

閱讀

原文

回帖

報名,還在等什麼!


推薦閱讀:
相关文章