Fabric权限管理和策略
權限管理是區塊鏈網絡十分重要的功能,負責控制某個身份在某個場景下是否允許采取某個操作(如讀寫某個資源)。
超級賬本 Fabric 項目通過策略(Policy)來靈活指定各場景下的操作權限。
策略應用場景
具體來看,常見的策略場景包括如下表所示。其中,大部分都與系統配置鏈碼相關,可以在通道配置中進行指定;部分為代碼中的規定。
對于存儲在通道配置中的策略,可以利用 configtx.yaml 指定,在生成新建通道交易時初始化到通道配置內。
操作場景??? 策略檢查??? 相關實現文件
調用 Broadcast() 接口向 Orderer 發送交易信息??? Orderer 會檢查是否滿足通道的 Writers 策略??? orderer/multichain/chainsupport.go
調用 Deliver() 接口從 Orderer 獲取區塊結構??? Orderer 會檢查是否滿足通道的 Readers 策略??? orderer/common/deliver/deliver.go
新建應用通道??? Orderer 會檢查是否申請者滿足系統通道的 Writers 策略??? orderer/multichain/chainsupport.go
修改通道配置??? Orderer 會檢查所有的修改項需滿足對應的 modPolicy 策略,默認為 Admins??? common/configtx/update.go
Peer 加入應用通道??? 配置管理系統鏈碼(CSCC)會檢查申請者是否為某個 MSP 的管理員身份??? core/scc/cscc/configure.go
Peer 獲取所加入通道列表??? 配置管理系統鏈碼(CSCC)會檢查申請者是否為某個 MSP 的成員身份??? core/scc/cscc/configure.go
獲取某應用通道的區塊??? 配置管理系統鏈碼會檢查是否滿足應用通道的 Readers 策略??? core/scc/cscc/configure.go
安裝鏈碼??? 鏈碼生命周期管理系統鏈碼(LSCC)會檢查安裝提案中簽名者是否為本地 MSP 的 Admin 身份??? core/scc/lscc/lscc.go
實例化部署鏈碼??? 鏈碼生命周期管理系統鏈碼(LSCC)默認會檢查提案者是否是通道內成員??? core/scc/lscc/lscc.go 和 core/committer/txvalidator/v20/plugindispatcher/dispatcher.go
調用鏈碼??? 背書節點在背書過程中會檢查鏈碼是否滿足應用通道的 Writers 策略和 Readers 策略;確認節點也會檢查交易是否滿足背書策略??? core/endorser/endorser.go 和 core/scc/lscc/lscc.go
Peer 通過 Gossip 協議獲取到區塊??? 對區塊進行校驗,檢查需要滿足 BlockValidation 策略??? peer/gossip/mcs.go
監聽事件??? Peer 會檢查是否滿足應用通道的 Readers 策略??? core/peer/deliverevents.go
注:Readers、Writers、Admins、管理員、成員等都代表了一組事先定義的身份。
身份證書
實現權限管理的基礎是身份證書機制。
通過基于 PKI 的成員身份管理,Fabric 網絡可以對接入的節點和用戶的各種能力進行限制。
Fabric 設計中考慮了三種類型的證書:登記證書(Enrollment Certificate)、交易證書(Transaction Certificate),以及保障通信鏈路安全的 TLS 證書。證書的默認簽名算法為 ECDSA,Hash 算法為 SHA-256。
登記證書(ECert):頒發給提供了注冊憑證的用戶或節點等實體,代表網絡中身份。一般長期有效。
交易證書(TCert):頒發給用戶,控制每個交易的權限,不同交易可以不同,實現匿名性。短期有效。
通信證書(TLSCert):控制對網絡層的接入訪問,可以對遠端實體身份進行校驗,防止竊聽。
目前,在實現上,主要通過 ECert 來對實體身份進行檢驗,通過檢查簽名來實現權限管理。TCert 功能暫未實現,用戶可以使用 idemix 機制來實現部分匿名性。
身份集合
基于證書機制,Fabric 設計了身份集合(MSP Principal)來靈活標記一組擁有特定身份的個體,如下圖所示。
?
對應的 MSP Principal 的數據結構如下圖所示。
身份集合支持從不同維度上對身份進行分類:
Role:根據證書角色來區分,如 Admin、Member、Client、Peer 等;
OrganizationUnit:根據身份中的 OU 信息來區分,如某個特定部門。實際上 Client 和 Peer 角色也是通過證書中的 OU 域來指定的;
Identity:具體指定某個個體的證書,只有完全匹配才認為合法;
Anonymity:證書是否是匿名的,用于 idemix 類型的 MSP;
Combined:由其他多個子身份集合組成,需要符合所有的子集合才認為合法。
基于不同維度可以靈活指定符合某個身份的個體,例如某個 MSP 的特定角色(如成員或管理員),或某個 MSP 特定單位(OrganizationUnit),當然也可以指定為某個特定個體。
需要注意目前角色定義是在代碼中實現。對于管理員角色,除安裝鏈碼操作是將簽名的證書跟節點 msp/admincerts 路徑下的證書列表進行查找匹配,其它操作依賴于通道配置中對應組織 MSP 結構中 MSP.value.admins 中定義;對于成員角色,則需要所簽名證書是被節點同一 MSP 根簽發即可。具體實現可參考 msp/mspimpl.go 文件中 satisfiesPrincipalInternal 相關方法。Client 和 Peer 角色認定則通過檢查證書中 OU 域信息。
權限策略的實現
權限策略會具體指定可以執行某項操作的身份集合。
以通道相關的策略為例,一般包括對讀操作(例如獲取通道的交易、區塊等數據)、寫操作(例如向通道發起交易)、管理操作(例如加入通道、修改通道的配置信息)等進行權限限制。對策略自身的修改通過額外指定的修改策略(mod_policy)來進行管理。
操作者在發起操作時,其簽名組合需要滿足策略指定的身份結合規則,才可以被允許執行相應的操作。
實現上,每種策略結構都要實現 Evaluate(signatureSet []*cb.SignedData) error 方法。該方法中會對于給定的一組簽名數據,按照給定規則進行檢驗,看是否符合約定的條件。符合則說明滿足了該策略;反之則拒絕。
策略相關數據結構
策略相關的數據結構定義在 protos/common/policies.proto 文件中,其中主要包括 Policy、SignaturePolicyEnvelope(內嵌 SignaturePolicy 結構)和 ImplicitMetaPolicy 三種數據結構,如下圖所示。
Policy 消息的定義如下。
message Policy {
??? enum PolicyType {
??????? UNKNOWN = 0; // 初始化保留類型
??????? SIGNATURE = 1; // 簡單基于簽名的規則
??????? MSP = 2; // 基于 MSP
??????? IMPLICIT_META = 3; // 隱式規則
??? }
??? int32 type = 1; //類型
??? bytes value = 2; //規則
}
其中,PolicyType 的數值代表策略的類型,具體含義為:
UNKNOWN:保留值,用于初始化;
SIGNATURE:通過匹配基于簽名的組合,如某個 MSP 中至少三個簽名;
MSP:代表策略必須要匹配某 MSP 下的指定身份身份,如 MSP 的管理員身份;
IMPLICIT_META:隱式類型,包括若干子策略,并通過 Rule 來指定具體的規則,包括 ANY、ALL、MAJORITY 三種。
ANY:滿足任意子組的對應策略。
ALL:滿足所有子組的對應策略。
MAJORITY:滿足大多數(過半)子組的對應策略。
目前已經實現支持的策略類型主要包括 SignaturePolicy 和 ImplicitMetaPolicy 兩種。
SIGNATURE 策略
SIGNATURE 策略指定通過簽名來對數據進行認證,例如必須滿足給定身份的簽名組合,結構如下圖所示。
相關數據結構主要包括 SignaturePolicy 消息體和封裝后使用的 SignaturePolicyEnvelope,兩者定義如下所示。
message SignaturePolicy {
??? message NOutOf {
??????? int32 n = 1;
??????? repeated SignaturePolicy rules = 2;
??? }
??? oneof Type {
??????? int32 signed_by = 1; // 指定所需簽名者在身份集合列表中的序號
??????? NOutOf n_out_of = 2;
??? }
}
?
type SignaturePolicyEnvelope struct {
??? Version??? int32? `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
??? Rule???? *SignaturePolicy `protobuf:"bytes,2,opt,name=policy" json:"policy,omitempty"`
??? Identities []*common1.MSPPrincipal `protobuf:"bytes,3,rep,name=identities" json:"identities,omitempty"`
}
其中,SignaturePolicy 結構體代表了一個策略的規則(Rule)。支持指定某個特定簽名,或者滿足給定策略集合中的若干個(NOutOf)即可。NOutOf 用法十分靈活,基于它可以遞歸地構建任意復雜的策略語義,指定多個簽名規則的與、或組合關系。
SignaturePolicyEnvelope 結構體代表了一個完整的策略,包括版本號(Version)、策略規則(Rule)和策略關聯的身份集合(Identities)。
例如,某個策略要求滿足 MP1 身份集合中簽名,或者 MP2 集合和 MP3 集合同時簽名,則可以表達為 MP1 || (MP2 && MP3))。對應的策略結構如下所示。
SignaturePolicyEnvelope{
??? version: 0,
??? rule: SignaturePolicy{
??????? n_out_of: NOutOf{
??????????? N: 1,
??????????? rules: [
??????????????? SignaturePolicy{ signed_by: 0 },
??????????????? SignaturePolicy{
??????????????????? n_out_of: NOutOf{
??????????????????????? N: 2,
??????????????????????? rules: [
??????????????????????????? SignaturePolicy{ signed_by: 1 },
??????????????????????????? SignaturePolicy{ signed_by: 2 },
??????????????????????? ],
??????????????????? },
??????????????? },
??????????? ],
??????? },
??? },
??? identities: [MP1, MP2, MP3] // 身份集合列表
}
需要注意,對簽名策略的匹配過程是順序敏感的(參考 FAB-4749)。進行策略檢查時,給定的多個簽名會依次按照策略順序依次跟身份集合進行匹配,簽名一旦匹配則會被消耗掉,再檢查下一個簽名。例如上述例子中,假如 MP1 代表組織 A 的管理員,MP2 代表組織 B 的成員,MP3 代表組織 B 的管理員,那么對于簽名組合 [S1={組織 B 的管理員},S2={組織 B 的成員}],并不會匹配成功。因為,S1 在匹配 MP2 后會被消耗掉,剩下的 S2 在匹配 MP3 時會失敗。為了避免這種情況,進行簽名時要將優先級較低的簽名放到前面,比如代表成員身份的簽名應當放到管理員身份前。同時,對于策略的身份集合列表,則應該將高優先級的放到前面。
對于策略的檢查主要實現在 msp/mspimpl.go 代碼文件的 SatisfiesPrincipal(id Identity, principal *m.MSPPrincipal) error 方法中。
IMPLICIT_META 策略
IMPLICIT_META 策略并不直接進行簽名檢查,而是通過引用其它子策略(最終還是通過 SIGNATURE 策略)來實現。檢查結果通過策略規則來進行約束,如下圖所示。
相關的結構體主要為 ImplicitMetaPolicy(位于 protos/common/policies.proto),定義如下。
message ImplicitMetaPolicy {
??? enum Rule {
??????? ANY = 0;????? // 任意子策略被滿足即可
??????? ALL = 1;????? // 所有的子策略都必須被滿足
??????? MAJORITY = 2; // 超過一半的子策略被滿足
??? }
??? string sub_policy = 1; // 在子元素中查找的子策略類型名稱
??? Rule rule = 2; //限制規則類型
}
其中,sub_policy 限定查找的子策略的類型(Readers、Writers、Admins 或自定義),rule 指定約束的規則類型。
例如,對于應用通道,如果包括兩個組織 Org1 和 Org2,那么如下的通道讀策略(/Channel/Application/Reader)實際上意味著 Org1 和 Org2 中任意讀權限的擁有者都對擁有通道讀權限。
ImplicitMetaPolicy{
??? sub_policy: "Readers",
??? rule: ANY,
}
Org1 和 Org2 可以在各自結構中具體規定 Readers 策略的具體內容,如默認的為任意合法成員即可。
通道策略
權限策略的主要應用場合之一便是通道策略(Channel Policy)。通道策略采用了層級化樹形結構,最上層為 /Channel 組,下面是各級子組。在每一級別都可以指定策略,作為本層級的默認策略。
通道配置可以包括聯盟組(僅當系統通道,包括聯盟組織信息)、應用組(一般僅當應用通道,包含使用通道的組織信息)和排序組(包括排序組織信息)等不同的元素。
一個典型的例子如下圖所示,包括一個排序組織和一個應用組織。
默認情況下,通道內的策略如下所示。
# 通道默認全局策略
/Channel/Readers: ImplicitMetaPolicy-ANY Readers
/Channel/Writers: ImplicitMetaPolicy-ANY Writers
/Channel/Admins : ImplicitMetaPolicy-MAJORITY Admins
?
# 通道內應用組默認策略(僅當應用通道)
/Channel/Application/Readers: ImplicitMetaPolicy-ANY Readers
/Channel/Application/Writers: ImplicitMetaPolicy-ANY Writers
/Channel/Application/Admins : ImplicitMetaPolicy-MAJORITY Admins
/Channel/Application/Endorsement: ImplicitMetaPolicy-MAJORITY Endorsement
/Channel/Application/LifecycleEndorsement: ImplicitMetaPolicy-MAJORITY LifecycleEndorsement
?
# 通道內應用組各組織的默認策略(僅當應用通道)
/Channel/Application/Org/Readers: SignaturePolicy for 1 of Org Member
/Channel/Application/Org/Writers: SignaturePolicy for 1 of Org Member
/Channel/Application/Org/Admins : SignaturePolicy for 1 of Org Admin
/Channel/Application/Org/Endorsement: SignaturePolicy for 1 of Org Member
?
# 通道內排序組的默認策略
/Channel/Orderer/Readers: ImplicitMetaPolicy-ANY Readers
/Channel/Orderer/Writers: ImplicitMetaPolicy-ANY Writers
/Channel/Orderer/Admins : ImplicitMetaPolicy-MAJORITY Admins
/Channel/Orderer/BlockValidation : ImplicitMetaPolicy-ANY Writers
?
# 通道內排序組中各組織的默認策略
/Channel/Orderer/Org/Readers: SignaturePolicy for 1 of Org Member
/Channel/Orderer/Org/Writers: SignaturePolicy for 1 of Org Member
/Channel/Orderer/Org/Admins : SignaturePolicy for 1 of Org Admin
?
# 通道內聯盟組的默認策略(僅當系統通道)
/Channel/Consortiums/Admins: SignaturePolicy for ANY
?
# 通道內聯盟組中某聯盟的默認策略(僅當系統通道)
/Channel/Consortiums/Consortium/ChannelCreationPolicy: ImplicitMetaPolicy-ANY for Admin
?
# 通道內聯盟組中某聯盟組織的默認策略(僅當系統通道)
/Channel/Consortiums/Consortium/Org/Readers: SignaturePolicy for 1 of Org Member: ImplicitMetaPolicy-ANY for Admin
/Channel/Consortiums/Consortium/Org/Writers: SignaturePolicy for 1 of Org Member
/Channel/Consortiums/Consortium/Org/Admins : SignaturePolicy for 1 of Org Admin
背書策略
用戶在實例化鏈碼時,可以指定背書策略(Endorsement Policy)。
背書策略采用了 SignaturePolicy 結構進行指定,同樣可以利用身份集合結構構建十分靈活的簽名校驗組合。
例如,指定某幾個組織內的任意成員身份進行背書,或者至少有一個管理員身份進行背書等。
語法上,背書策略支持通過 -P 指定哪些 SignaturePolicy 會被需要;通過 -T 指定所需要的 SignaturePolicy 個數。
目前,客戶端已經實現了對背書策略的初步支持,通過 -P 來指定通過 AND、OR 組合的成員身份(admin,member)集合。
下面的命令可以指定要么 Org1 的管理員進行背書,或者 Org2 和 Org3 的成員同時進行背書,才滿足背書策略。
OR('Org1.admin', AND('Org2.member', 'Org3.member'))
背書策略的檢查發生在 Peer 提交區塊階段,位于 core/committer/txvalidator/v20/plugindispatcher/dispatcher.go。
實例化策略
實例化策略(Instantiation Policy)一般用于最終確認階段,Committer 利用 VSCC 對網絡中進行鏈碼部署的操作進行權限檢查。
目前,實例化策略同樣采用了 SignaturePolicy 結構進行指定,可以基于身份集合結構構建復雜的簽名校驗組合。
默認情況下,會以當前 MSP 的管理員身份作為默認的策略,即只有當前 MSP 管理員可以進行鏈碼實例化操作。這可以避免鏈碼被通道中其他組織成員私自在其它通道內進行實例化。
實例化策略的檢查發生在 Peer 的背書階段,位于 core/endorser/endorser.go。
?————————————————
版權聲明:本文為CSDN博主「yeasy」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yeasy/article/details/88536882
總結
以上是生活随笔為你收集整理的Fabric权限管理和策略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Gossip数据传播协议
- 下一篇: Hyperledger Fabric权限