現代軟體開發中,機密資訊的管理至關重要,諸如密碼、API 金鑰等資訊的保護攸關系統安全。本文除了探討機密資訊管理的六大核心原則外,更深入剖析實務上的挑戰與解決方案。程式碼中硬編碼機密資訊的風險不容忽視,應採用更安全的管理方式,例如使用組態管理系統的加密功能、專用的機密資訊管理工具,或是結合安全引導與秘密伺服器來提升安全性。此外,善用雲端平台的內建安全功能也是一種有效方法。
管理機密資訊:原則與實踐
在現代的軟體開發和佈署中,機密資訊(如密碼、API 金鑰、加密令牌或公鑰/私鑰對)的管理是一個至關重要的課題。這些機密資訊對於系統的安全運作至關重要,但同時也帶來了巨大的安全風險。正確的機密資訊管理需要遵循一系列原則,以確保這些敏感資訊只被授權的實體存取。
機密資訊管理的原則
定期變更機密資訊:機密資訊應該定期變更,或在有理由懷疑其洩露時立即變更。如果變更機密資訊需要停機並手動更新多個位置,這是一個需要改進的問題。
加密儲存和傳輸:機密資訊在靜態儲存和傳輸過程中都應該被加密,並且只有在經過正確的身份驗證和授權後才被分發到系統中。
最小化知情人員:理想情況下,應該沒有人知道機密資訊,包括開發人員和維運人員。至少應該盡量減少知道機密資訊的人數。
保護機密資訊儲存系統:儲存和分發機密資訊的系統應該得到很好的保護。如果將所有機密資訊存放在一個保險函式庫中,然後將保險函式庫的鑰匙分發給許多人,這是一個問題。
限制機密資訊的許可權:機密資訊應該盡可能地對攻擊者無用,同時仍然允許系統正常運作。這是最小許可權原則的一個應用;盡量避免保留像提供對所有系統的根存取許可權這樣的「王國鑰匙」,而是使用有限的機密資訊,例如允許對特定資料函式庫進行唯讀存取的機密資訊。
記錄所有存取和變更:所有對機密資訊的存取和變更都應該被記錄下來。
實踐中的挑戰
許多組織在身份驗證和授權方面做得很好,但往往忽略了機密資訊管理。例如,您可能很好地跟蹤了哪些人擁有對資料函式庫的個人存取許可權,但有多少人知道應用程式伺服器用於與資料函式庫通訊的密碼?當有人離開組織時,這個密碼是否會被更改?
一個典型的錯誤是將機密資訊直接放在應用程式伺服器程式碼中,並將其檢入公共儲存函式庫,如 GitHub。2016 年,Uber 發生了一起涉及 5700 萬名司機和客戶的資料洩露事件,就是因為其原始碼中包含了 AWS 憑據。
改善機密資訊管理的方法
將機密資訊從原始碼中移除,並將其存放在其他地方,例如佈署工具中的安全位置或專用的機密資訊伺服器,是解決這個問題的一種方法。應用程式的佈署通常由三部分組成:應用程式碼、特定佈署的組態和特定佈署所需的機密資訊。將這三者存放在一起是一個壞主意,因為原始碼儲存函式庫主要不是為了保密資訊而設計的。
以下是四種合理的機密資訊管理方法,從最低安全性到最高安全性:
使用現有的組態管理系統和佈署系統:許多流行的系統現在具有儲存機密資訊的能力,例如 Ansible Vault 和 Chef 加密資料包。如果佈署工具小心處理機密資訊,並且對佈署系統和加密金鑰的存取受到嚴格控制,這可以是一種合理的方法。
使用專用的機密資訊管理工具:有專門的工具設計用於安全地儲存和管理機密資訊,例如 HashiCorp 的 Vault。
使用現有組態管理系統範例程式碼
# 使用Ansible Vault加密變數檔案
ansible-vault encrypt vars.yml
內容解密:
此範例展示瞭如何使用 ansible-vault 命令加密包含機密資訊的變數檔案 vars.yml。首先,確保您已經安裝了 Ansible 並且組態正確。然後,使用 ansible-vault 命令對檔案進行加密。這樣可以確保即使未經授權的人員存取了該檔案,也無法讀取其內容,從而提高了機密資訊的安全性。
身份驗證與存取管理中的秘密管理
在身分驗證的過程中,如何安全管理機密資訊(secrets)是至關重要的。機密資訊可能包括 API 金鑰、資料函式庫密碼、憑證等敏感資料。以下是四種常見的秘密管理方法,每種方法都有其優缺點和適用場景。
四種秘密管理方法
第一種方法:將秘密儲存在佈署系統中
第一種方法是將所有秘密儲存在佈署系統中,利用其內建的安全功能來保護這些秘密。這種方法的優點是預設情況下沒有人可以看到這些秘密,只有授權的人員才能夠在佈署系統中檢視或修改它們。然而,這種方法需要嚴格控制對佈署系統的存取許可權。
第二種方法:使用秘密伺服器
第二種方法是使用一個獨立的秘密伺服器來儲存和管理機密資訊。佈署系統或應用程式需要與秘密伺服器進行通訊,以取得所需的機密資訊。這種方法的優點包括:
- 可以記錄對秘密伺服器的請求,從而檢測和防止未授權的存取。
- 可以使用多種身份驗證方法,例如 IP 白名單,來控制對秘密伺服器的存取。
- 可以輕鬆更新機密資訊,所有檢索這些資訊的系統都會自動取得新的值。
然而,這種方法仍然需要管理對秘密伺服器的存取密碼,這本身也是一個需要保護的機密資訊。
第三種方法:結合安全引導和秘密伺服器
第三種方法結合了第二種方法的優點,並透過安全引導(secure introduction)來降低攻擊者取得秘密伺服器憑證的風險。具體步驟如下:
- 佈署工具與秘密伺服器通訊,取得一次性使用的機密資訊,並將其傳遞給應用程式。
- 應用程式使用這個一次性機密資訊換取真正的機密資訊,並將其儲存在記憶體中。如果有人已經使用過這個一次性機密資訊,這一步驟將會失敗,應用程式可以發出警示。
這種方法限制了佈署工具的許可權,使其只能取得一次性金鑰,而無法直接檢視機密資訊,從而提高了安全性。
第四種方法:利用雲端平台的內建功能
第四種方法是利用雲端平台提供的安全功能,例如例項後設資料或身份檔案,來進行身份驗證和授權。應用程式可以檢索由雲端提供者加密簽署的身份檔案,證明其身份。秘密伺服器根據這個身份檔案以及其他後設資料(如標籤)來決定是否向應用程式提供所需的機密資訊。
授權
完成身份驗證階段後,接下來需要確保使用者只能執行他們被允許執行的操作。這就是授權(Authorization)的範疇。授權的例子包括控制使用者對特定資源的存取許可權等。有效的授權機制能夠防止未授權的操作,從而保護系統和資料的安全。
秘密管理工具與服務
目前市場上有多種工具和服務可以幫助管理機密資訊,例如 HashiCorp Vault、Keywhiz 和 AWS Secrets Manager 等。這些工具和服務提供了不同的功能和佈署選項,可以根據組織的需求進行選擇。
內容解密:
上述四種秘密管理方法各有千秋,但都旨在解決如何安全地管理和分發機密資訊的問題。選擇合適的方法需要綜合考慮安全性、可操作性和成本等因素。同時,利用現有的安全工具和服務,可以進一步簡化秘密管理的過程,提高整體的安全性。
身份與存取管理中的授權機制
在雲端運算環境中,授權(Authorization)是指決定使用者或系統是否有許可權執行特定操作或存取特定資源的過程。授權機制對於確保系統安全和資料保護至關重要。
最小許可權原則與職責分離
在授權機制中,有兩個重要的概念:最小許可權原則(Least Privilege)和職責分離(Separation of Duties)。最小許可權原則意味著使用者、系統或工具只能存取執行其任務所需的資源,而不能存取其他不必要的資源。這通常需要實施「預設拒絕」(Deny by Default)政策,除非明確授權,否則一律不允許存取。
職責分離則源自金融控制領域,強調將許可權分散,以避免單一人員擁有過多的控制權。在雲端安全領域,這意味著需要確保沒有任何一個人能夠完全破壞整個環境的安全。例如,具有系統變更許可權的人員不應同時具有修改或審查該系統日誌的許可權。
集中式授權
過去,不同的應用程式各自管理其授權記錄,導致授權管理分散。集中式授權(Centralized Authorization)可以解決這個問題,提供單一的檢視來管理和控制使用者的存取許可權。
在集中式授權系統中,應用程式和授權系統共同承擔授權責任。主要元件包括:
策略執行點(Policy Enforcement Point, PEP)
由應用程式實作,控制對特定功能的存取。應用程式會向策略決策點(PDP)查詢是否允許存取。
策略決策點(Policy Decision Point, PDP)
由集中式授權系統實作,根據應用程式提供的資訊(如身份和請求的功能)和策略,決定是否允許存取。
策略管理點(Policy Administration Point, PAP)
同樣由集中式授權系統實作,通常是一個網頁使用者介面和相關的API,用於設定和管理存取規則。
大多數雲端服務提供商都提供集中式的存取管理解決方案,應用程式會向這些解決方案查詢存取決策。使用這些機制可以讓管理員在單一地方檢視授予特定管理員的所有存取許可權。
角色
許多雲端服務提供商提供角色(Roles)功能,類別似於共用ID的使用者可以假設某種角色,執行該角色允許的操作,然後放棄該角色。與傳統的角色實作不同,雲端服務提供商的角色不是一個完整的身份,而是一種特殊的狀態,由另一個被授權存取該角色的身份承擔,並被分配臨時憑證以存取該角色。
根據角色的存取控制可以增加額外的安全層,要求使用者或服務明確承擔特定角色以執行更具特權的操作,遵循最小許可權原則。大多數情況下,使用者除非明確承擔該角色,否則無法執行那些特權操作。系統也可以記錄每次承擔角色的請求,以便管理員稍後能夠確定在特定時間內誰具有該角色,並將該資訊與系統上具有安全影響的操作進行比較。
不僅人員可以承擔角色,一些元件(如虛擬機器)也可以在建立時承擔角色,並使用分配給該角色的特權執行操作。
程式碼例項
以下是一個簡單的例子,用於示範如何使用Python實作根據角色的存取控制:
class Role:
def __init__(self, name, permissions):
self.name = name
self.permissions = permissions
class User:
def __init__(self, name):
self.name = name
self.role = None
def assume_role(self, role):
self.role = role
def has_permission(self, permission):
if self.role is None:
return False
return permission in self.role.permissions
# 定義角色和許可權
admin_role = Role('admin', ['read', 'write', 'delete'])
read_only_role = Role('read_only', ['read'])
# 建立使用者並承擔角色
user1 = User('User1')
user1.assume_role(admin_role)
user2 = User('User2')
user2.assume_role(read_only_role)
# 檢查使用者許可權
print(user1.has_permission('write')) # True
print(user2.has_permission('write')) # False
內容解密:
Role類別用於定義不同的角色及其對應的許可權。User類別代表使用者,可以承擔某個角色,並檢查是否具有特定許可權。assume_role方法允許使用者承擔一個角色。has_permission方法檢查使用者是否具有特定的許可權,這取決於他們當前承擔的角色。- 程式碼示範瞭如何建立不同角色的使用者,並檢查他們的許可權,從而實作根據角色的存取控制。
此圖示展示了根據角色的存取控制的基本流程:
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 內容解密:
rectangle "承擔" as node1
rectangle "具有" as node2
rectangle "用於" as node3
rectangle "決定" as node4
node1 --> node2
node2 --> node3
node3 --> node4
@enduml此圖示說明瞭使用者如何透過承擔角色來獲得特定的許可權,並利用這些許可權進行存取控制,最終決定是否允許執行某個操作。
身份與存取管理的角色與群組差異
許多人在某個時候都會問:“角色(Role)和群組(Group)之間有什麼區別?” 在純粹的形式下,它們之間的差異可以歸納如下:
- 群組是一組實體的集合,例如使用者,但不包含任何關於這些實體在該群組中被授予的授權資訊。舉例來說,
VMAdminGroup可能包含Chris和Barbara,但你不知道他們被允許做什麼。 - 角色是一組許可權的集合,這些許可權可以被授予使用者、群組或其他實體,例如虛擬機器。然而,一個「純粹」的角色並不固有地包含任何關於誰被授予這些許可權的資訊。一個名為
VMAdminRole的角色可能授予你建立和刪除虛擬機器的許可權,但角色定義本身並沒有告訴你誰實際獲得了這些許可權。在某些情況下,角色會永久分配給特定的使用者或群組,而在某些情況下,使用者可能會被授權明確「承擔」某個角色,並在不再需要時放棄該角色。
在實踐中,許多角色也會指定它們適用的使用者(或群組),而在許多情況下,群組成員資格會為群組成員提供一個永久性的許可權集合(單一角色)。這些術語經常被互換使用,但在某些雲端服務供應商中(如AWS IAM 群組和角色),這種區分非常重要。
重新驗證的重要性
此時,你的使用者和自動化應該已經具備了身份,並且只被授權做他們需要做的事情。你需要確保這一點能夠經得起時間的考驗。
如同之前提到的,重新驗證的步驟在傳統環境和雲端環境中都非常重要,但在雲端環境中,如果你忘記復原存取許可權,你可能沒有額外的控制措施(如實體建築物存取或網路控制)來挽救你。你需要定期檢查每個授權,以確保它仍然是必要的。
自動化重新驗證
第一種型別的重新驗證是根據某些引數的自動化重新驗證。例如,你應該有一個系統,在有人離開組織時自動提出復原所有存取許可權的請求。請注意,簡單地刪除使用者的身份可能是不夠的,因為使用者可能擁有快取的憑據,例如即使無法登入也可以使用的存取令牌。在這種情況下,你需要一個「離職名單」(offboarding feed),這是一個應該復原其存取許可權的實體清單。任何發放長期憑據(如存取令牌)的系統都必須至少每天處理一次這個離職名單,並復原所有存取許可權。
需要人為判斷的重新驗證
第二種型別的重新驗證需要人為判斷,以確定某個特定實體是否仍然需要存取許可權。一般來說,有兩種根據判斷的重新驗證方式:
積極確認
這是一種更強的方法——除非有人明確表示「仍然需要此存取許可權」,否則將失去存取許可權。
消極確認
這是一種較弱的方法——除非有人表示「不再需要此存取許可權」,否則將保留存取許可權。
對於較低影響的授權級別,消極確認是合適的,但對於對業務有重大影響的存取型別,你應該使用積極確認。積極確認的缺點是它需要更多的工作,而且如果請求未及時處理,存取許可權可能會被意外復原(這可能會導致操作問題)。
重新驗證所解決的最大風險是,離開組織的人(可能是在有爭議的情況下)仍然保留對系統的存取許可權。除此之外,隨著時間的推移,存取許可權往往會像廚房抽屜裡的雜物一樣積累起來(你知道的那種)。重新驗證可以清除這些雜物。
然而,請注意,如果很難獲得存取許可權,你的使用者往往會聲稱他們仍然需要存取許可權,即使他們不再需要。如果您還有一個快速、簡單的流程來授予需要的存取許可權,那麼您的重新驗證工作將會更有效地修剪不必要的存取許可權。如果這不可能,那麼自動復原一段時間內未使用的存取許可權可能比詢問是否仍需要更有效。這也有風險,因為你可能會發現當需要時沒有人有存取許可權!
雲端身份即服務供應商越來越多地提供整個身份生命週期的管理,以及身份驗證和授權服務。換句話說,供應商正在認識到關係結束和關係開始同樣重要,並且正在幫助簡化和規範結束流程。
將所有內容整合到範例應用程式中
還記得我們的簡單網頁應用程式嗎?讓我們將身份和存取管理資訊新增到圖表中,如圖4-3所示。我刪除了整個應用程式信任邊界以簡化圖表。
圖4-3:具有IAM的範例應用程式圖表
不幸的是,這使得圖表變得相當複雜!讓我們仔細看看一些新的互動:
- 終端使用者嘗試存取應用程式,並透過具有有效身份自動獲得批准,並可選地透過一些反欺詐測試。終端使用者使用SSO登入,因此應用程式身份與使用者的外部身份提供者聯合,應用程式無需驗證密碼。從使用者的角度來看,他們正在使用與公司或最喜歡的社交媒體網站相同的身份。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 圖4-3:具有IAM的範例應用程式圖表
rectangle "請求存取" as node1
rectangle "驗證身份" as node2
rectangle "傳回驗證結果" as node3
rectangle "授予存取許可權" as node4
node1 --> node2
node2 --> node3
node3 --> node4
@enduml此圖示說明
此圖示呈現了終端使用者如何透過SSO(單一登入)機制存取應用程式,並且應用程式如何與身份提供者進行驗證互動作用以確認使用者的身份,最終授予存取許可權。這個過程展示了現代網頁應用程式中常見的身份驗證流程。
身份識別與存取管理在雲端環境中的重要性
在本地佈署環境中,由於實體安全和網路控制等其他緩解措施的存在,人們可能會對身份識別和存取管理(IAM)有所放鬆。然而,在雲端環境中,IAM 變得極為重要。雖然雲端和本地佈署中的概念相似,但雲端提供了新的技術和服務來提升安全性和簡化管理工作。
身份識別與存取管理的生命週期
在整個身份識別和存取管理的生命週期中,人們很容易忘記請求、批准和重新驗證的步驟。雖然這些步驟可以手動執行,但許多作為服務(as-a-Service)的產品最初只處理身份驗證和授權步驟,現在也提供批准步驟的工作流程,而且這種趨勢可能會加速。
集中式身份驗證系統
集中式身份驗證系統為管理員和終端使用者提供了一個單一的身份,可以跨多個不同的應用程式和服務使用。雖然這種系統已經以不同的形式存在很長時間了,但在雲端環境中,它們變得更加必要,因為它們預設可用。由於雲端系統和服務的普及,如果不使用集中式身份驗證,管理每個系統和服務的身份可能會迅速變成一場噩夢,尤其是在大型佈署中。舊的、被遺忘的身份可能會被其前使用者或攻擊者用來作為進入系統的捷徑。
強大的密碼和多因素身份驗證
即使用集中式身份驗證,仍然需要使用強大的密碼和多因素身份驗證。雲端管理員和終端使用者通常透過不同的系統進行身份驗證。
集中式授權系統
與身份驗證系統類別似,集中式授權系統允許您在一個地方檢視和修改實體被授權執行的所有操作。這可以使授予和重新驗證存取許可權變得更容易,並使職責分離的衝突更加明顯。在為人員和自動化任務授權時,請務必遵循最小許可權原則和職責分離原則,避免擁有超級許可權的身份和憑證。
秘密管理
秘密管理是一個快速成熟的領域,用於系統間存取的秘密與其他組態資料分開維護,並根據嚴格的保密性和稽核原則進行處理。現有的組態管理產品、獨立的秘密伺服器產品以及作為雲端服務的產品都提供了秘密管理功能。