Fabric 权限管理(ACL)

什么是访问控制列表

Fabric使用访问控制列表通过策略(再给定一组身份的情况下指定评估为“真”或“假”的规则)与资源关联来管理对资源的访问。在这篇文章中,我们将讨论如何格式化访问控制列表以及如何覆盖默认值

资源

用过通过定位用户链码、系统链码、或者事件流源与fabric进行交互。 应用程序开发人员,需要了解这些资源以及与之关联的默认策略。在configtx.yaml文件中有完整的资源列表。这里有一份configtx.yaml的样例。 在configtx.yaml文件中指定的资源是fabric当前定义的所有内部资源的详尽列表。资源被定义为<组件>/<资源>。例如,`cscc/GetConfigBlock` 就是表达`cscc`组件中的资源`GetConfigBlock`。

策略

策略是fabric工作方式的基础,因为它们允许根据与完成请求所需资源相关联的策略来检查与请求关联的身份(或身份集合)。背书策略用于确定交易是否得到适当认可。通道配置中定义的策略被引用为修改策略以及访问控制,并在通道配置本身中定义。 策略类型分为

  • Signature策略
  • ImplicitMeta策略

签名策略

这些策略表示必须签署的特定用户才能满足策略。如:

Policies:
  MyPolicy:
    Type: Signature
    Rule: “Org1.Peer OR Org2.Peer”

样例中的策略构造可以解释为:命名为 MyPolicy的策略需要满足组织Org1或者Org2中的peer节点身份的签名。 签名策略支持”AND、OR、NOutOf”的任意组合,允许建立极其强大的规则,比如:组织A的管理员和另外两名管理员,或者20位组织管理员中的11位。

ImplicitMeta 策略

ImplicitMeta策略聚合配置层次结构中更深层次的策略结果,这些策略最终由签名策略定义。它们支持默认规则,例如“大多数组织管理员”。与签名策略相比,这些策略使用不同但任然非常简单的语法:

Policies:
  AnotherPolicy:
    Type: ImplicitMeta
    Rule: "MAJORITY Admins"
    

这里的策略AnotherPolicy可以由MAJORITY of Admins 满足,其中管理员最终由较低级别的签名策略制定。

访问控制在哪被指定

访问控制默认定义在configtx.yaml,configtxgen使用该文件构建通道配置。 访问控制升级有两种方法:

  • 通过编辑configtx.yaml本身,可以将ACL修改传播到任何新通道
  • 通过更新特定通道的通道配置中的访问控制来更新访问控制

如何在configtx.yaml中格式化ACL

ACL被格式化为键值对,由资源函数名称后跟字符串组成。这里有个configtx.yaml的例子 这里有两个样例:

#在peer节点提交链码的ACL策略
peer/Propose: /Channel/Application/Writers


# 发送区块事件的ACL策略
event/Block: /Channel/Application/Readers

这些ACL定义对”peer/Propose”和”event/Block”资源的访问限制为分别满足在规范路径”Channel/Application/Writers”和”/Channel/Application/Readers”中定义的策略的身份。相应的路径在configtx.yaml中注释中可以了解到。

在configtx.yaml中更新ACL默认值

如果在引导网络时需要覆盖ACL默认值,或者在引导通道之前更改ACL,最佳做法是更新configtx.yaml。 假设你需要修改”peer/Propose”ACL默认值(在peer节点调用链码的特点策略),在路径”/Channel/Application/Writers”下名为MyPolicy的策略。 这是通过添加名为MyPolicy(这里只是个举例命名)的策略来完成的。该策略在configtx.yaml内的Application.Policies部分中定义,并指定要检查以授权或拒绝用户访问权限的规则。对于这个例子,我们将要创建一个标识SampleOrg.admin的签名策略。

Policies: &ApplicationDefaultPolicies
    Readers:
        Type: ImplicitMeta
        Rule: "ANY Readers"
    Writers:
        Type: ImplicitMeta
        Rule: "ANY Writers"
    Admins:
        Type: ImplicitMeta
        Rule: "MAJORITY Admins"
    MyPolicy:
        Type: Signature
        Rule: "OR('SampleOrg.admin')"
        

然后,在configtx.yaml文件中编辑Application:ACLs部分,编辑资源

”peer/Propose”从 “peer/Propose: /Channel/Application/Writers”

修改为 “peer/Propose: /Channel/Application/MyPolicy”

控制组织添加权限

除了上面的自定义策略之外,同时还可以修改系统原有的策略,因为组织3加入当前用户channel的时候,属于channel权限控制范围。所以修改configtx.yaml中的channel部分为:

 Channel: &ChannelDefaults
    #   /Channel/<PolicyName>
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: Signature
            Rule: "OR('Org1MSP.admin')"
    Capabilities:
        <<: *ChannelCapabilities
 

同时修改:

 Application: &ApplicationDefaults
    Organizations:
    #   /Channel/Application/<PolicyName>
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: Signature
            Rule: "OR('Org1MSP.admin')"
 
 

上面的策略,当组织三申请加入的时候,需要有Org1的签名,才可以加入成功。

注意:当对修改策略测试的时候,每次注意关闭first-network网络,关闭命令端,然后重新启动,再检查结果。

组织加入系统链

业务场景:新来的Org3可以自己创建一个channel,没有其他组织参与,保证自己组织的私密性。但是在Fabric中如果生成genesis.block的时候,configtx.yaml中没有加入Org3策略配置的时候,Org3是不被允许创建channel的。因此考虑将Org3的策略更新到系统链的genesis.block中。

受到Org3加入mychannel应用链的启发,Org3是可以fetch到mychannel中的mychannel.block的。因此同样可以使用指定组织Org1来fetch下来系统链的genesis.block,就可以将Org3的策略配置加入到系统链上。在Fabric中系统链如果没有指定名称的话,默认的名字是testchainid。因为fetch是向Order请求,所以应该更改configtx.yaml文件中的-&OrdererOrg权限,如下:

 - &OrdererOrg
        Name: OrdererOrg
        ID: OrdererMSP
        MSPDir: crypto-config/ordererOrganizations/example.com/msp
        #   /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin')"

更改后:

 - &OrdererOrg
        Name: OrdererOrg
        ID: OrdererMSP
        MSPDir: crypto-config/ordererOrganizations/example.com/msp
        #   /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('OrdererMSP.member','Org1MSP.admin')"
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member','Org1MSP.admin')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin','Org1MSP.admin')"

将Order的读写权限和Admin权限同时也付给Org1,这时Org1就可以从Order中Fetch下来创世区块。

对组织3的操作

打开org3-artifacts

$ cd ~/hyfa/fabric-samples/first-network/org3-artifacts

首先配置Org3的configtx.yaml文件

Organizations:
    - &Org3
        Name: Org3MSP
        ID: Org3MSP
        Policies:
          Readers:
              Type: Signature
              Rule: "OR('Org3MSP.admin', 'Org3MSP.peer', 'Org3MSP.client')"
          Writers:
              Type: Signature
              Rule: "OR('Org3MSP.admin', 'Org3MSP.client')"
          Admins:
              Type: Signature
              Rule: "OR('Org3MSP.admin')"
        MSPDir: crypto-config/peerOrganizations/org3.example.com/msp
        AnchorPeers:
            - Host: peer0.org3.example.com
              Port: 7051

生成Org3加密材料

$sudo ../../bin/cryptogen generate --config=./org3-crypto.yaml

生成Org3.json文件


$export FABRIC_CFG_PATH=$PWD

$sudo ../../bin/configtxgen -printOrg Org3MSP > ../channel-artifacts/Org3.json

将Orderer Org的MSP材料移植到Org3 crypto-config 目录中


$cd ../

$sudo cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/

将Org3的MSP材料copy到peerOrgnization中


$sudo cp -r org3-artifacts/crypto-config/peerOrganizations/org3.example.com/  crypto-config/peerOrganizations/

打开


$cd ../channel-artifacts/

将宿主机的Org3.json转移到docker的相应的目录


docker cp Org3.json cli:/opt/gopath/src/github.com/hyperledger/fabric/peer

  • Org3.json:宿主机的文件
  • cli : docker容器的name
  • /opt…/peer: docker中路径

进入docker 容器


$ sudo docker exec -it cli bash


导入相应的环境变量

$export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  && export CHANNEL_NAME=testchainid

抓取genesis.block

$peer channel fetch config genesis_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA


成功会发现peer目录下多了一个genesis_block.pb文件,这就是genesis.block的二进制形式。

转换配置为json

$configtxlator proto_decode --input genesis_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json

使用jq将Org3配置定义追加Org3.json到系统通道的groups字段,并输出modified_config.json

$jq -s '.[0] * {"channel_group":{"groups":{"Consortiums":{"groups":{"SampleConsortium":{"groups":{"Org3MSP":.[1]}}}}}}}' config.json Org3.json >modified_config.json

将 config.json 中的内容输出为 config.pb

$configtxlator proto_encode --input config.json --type common.Config --output config.pb

将 modified_config.json 中的内容输出为 modified_config.pb

$configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

利用这两个配置文件, 使用 configtxlator 计算出更新配置时的更新量信息。该命 令将输出一个新的二进制文件,命名为 org3_update.pb

$configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb

将 org3_update.pb 中的内容解码为可编辑的JSON格式并将其称为 org3_update.json


$configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json


对通道配置进行更新时, 还需要封装为 org3_update_in_envelope 结构的配置更新 交易. 因此, 需要将 org3_update 结构数据进行补全

$echo '{"payload":{"header":{"channel_header":{"channel_id":"testchainid","type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json

将其转换为Fabric所需的二进制交易配置文件。命名为最终更新对象 org3_update_in_envelope.pb


$configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb

签署并提交配置更新

$peer channel signconfigtx -f org3_update_in_envelope.pb

更新通道

$peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA 

当出现Successfully submitted channel update的时候,更新成功! 此时系统链配置更新。

启动Org3 docker compose

打开一个新的终端,从first-network中启动Org3 docker compose


$cd ~/hyfa/fabric-samples/first-network/

$sudo docker-compose -f docker-compose-org3.yaml up -d

新的组织创建链

修改configtx.yaml ,作为创建应用通道channel.tx的模版文件

$vim configtx.yaml

添加Org3


- &Org3
        Name: Org3MSP
        ID: Org3MSP
        Policies:
          Readers:
              Type: Signature
              Rule: "OR('Org3MSP.admin', 'Org3MSP.peer', 'Org3MSP.client')"
          Writers:
              Type: Signature
              Rule: "OR('Org3MSP.admin', 'Org3MSP.client')"
          Admins:
              Type: Signature
              Rule: "OR('Org3MSP.admin')"
        MSPDir: crypto-config/peerOrganizations/org3.example.com/msp
        AnchorPeers:
            - Host: peer0.org3.example.com
              Port: 7051

Profiles 修改后的:

Profiles:

    TwoOrgsOrdererGenesis:
        <<: *ChannelDefaults
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Consortiums:
            SampleConsortium:
                Organizations:
                    - *Org1
                    - *Org2
                    - *Org3
    TwoOrgsChannel:
        Consortium: SampleConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1
                - *Org2
            Capabilities:
                <<: *ApplicationCapabilities
    ThirdOrgChannel:
        Consortium: SampleConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org3
            Capabilities:
                <<: *ApplicationCapabilities

创建一个应用通道的配置交易

$ export CHANNEL_NAME=org3channel

指定使用configtx.yaml配置文件中的ThirdOrgChannel模版,来生成新建通道的配置交易文件。


$sudo ../bin/configtxgen -profile ThirdOrgChannel -outputCreateChannelTx ./channel-artifacts/org3channel.tx -channelID $CHANNEL_NAME

将宿主机的org3channel.tx转移到docker的相应的目录


$cd channel-artifacts


$docker cp org3channel.tx Org3cli:/opt/gopath/src/github.com/hyperledger/fabric/peer

进入docker容器


$docker exec -it Org3cli bash


导入环境

$export CHANNEL_NAME=org3channel

$peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f org3channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

加入链

$ peer channel join -b org3channel.block 

检验当前节点加入通道

$peer channel list

当出现如下,则成功!

Channels peers has joined: 
org3channel

参考文章

fabric1.2.1新特性-访问控制列表

超级账本(Hyperledger Fabric)之权限管理浅析

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦