fabric 中证书的生成可以采用官方提供的工具cryptogen
命令生成,一种是通过fabric-ca服务
生成。
fabric 环境中有一个order,两个org,每个org 中有两个peer(同fabric exmaples/e2e-cli)
备注:后面涉及到的/opt/gopath/src/github.com/hyperledger/fabric 都替换成自己fabric源码的地址
编译fabric-ca
$ sudo apt install libtool libltdl-dev
$ go get -u github.com/hyperledger/fabric-ca/cmd/...
$ cd $GOPATH/bin
该命令执行完毕后,我们应该在~/go/bin下面看到生成的2个文件:
fabric-ca-client fabric-ca-server
这里将fabric-ca部署在/opt/app/fabric-ca/server
目录中:
$ mkdir -p /opt/app/fabric-ca/server
$ cp -rf /opt/gopath/bin/* /opt/app/fabric-ca/server
$ ln -s /opt/app/fabric-ca/server/fabric-ca-client /usr/bin/fabric-ca-client
直接启动ca,fabric-ca admin的名称为admin,密码为pass。(这里只是演示,生产中使用,你需要根据实际的情况配置)
cd /opt/app/fabric-ca/server
./fabric-ca-server start -b admin:pass --cfg.affiliations.allowremove --cfg.identities.allowremove &
注意:这里只是演示用法,直接用sqlite存储用户信息,生产中,请根据情况配置ldap或者mysql等数据库:HyperLedger FabricCA Config Database and LDAP。
cd ~
mkdir fabriccert
mkdir fabric-ca-files
生成fabric-ca admin的凭证,用-H
参数指定client目录:
mkdir -p `pwd`/fabric-ca-files/admin
fabric-ca-client enroll -u http://admin:pass@localhost:7054 -H `pwd`/fabric-ca-files/admin
也可以用环境变量FABRIC_CA_CLIENT_HOME
指定了client的工作目录,生成的用户凭证将存放在这个目录中。
export FABRIC_CA_CLIENT_HOME=`pwd`/fabric-ca-files/admin
mkdir -p $FABRIC_CA_CLIENT_HOME
fabric-ca-client enroll -u http://admin:pass@localhost:7054
为了防止混乱,后面的演示操作中,都直接用-H
指定目录。
上面的启动方式默认会创建两个组织:
$ fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation list
2018/05/07 02:36:46 [INFO] [::1]:56148 GET /affiliations 200 0 "OK"
affiliation: .
affiliation: org2
affiliation: org2.department1
affiliation: org1
affiliation: org1.department1
affiliation: org1.department2
为了查看信息的时候,看到的输出比较简洁,用下面的命令将其删除:
fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation remove --force org1
fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation remove --force org2
执行下面命令创建联盟:
fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation add com
fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation add com.example
fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation add com.example.org1
fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation add com.example.org2
创建联盟如下:
$ fabric-ca-client -H `pwd`/fabric-ca-files/admin affiliation list
2018/04/28 15:19:34 [INFO] 127.0.0.1:38160 GET /affiliations 201 0 "OK"
affiliation: com
affiliation: com.example
affiliation: com.example.org1
affiliation: com.example.org2
为example.com准备msp,将ca证书等存放example.com组织的目录中:
mkdir -p ./fabric-ca-files/example.com/msp
fabric-ca-client getcacert -M `pwd`/fabric-ca-files/example.com/msp
命令执行结束后,会在
fabric-ca-files/example.com/msp
得到文件:
$ tree fabric-ca-files/example.com/msp/
example.com/msp/
|-- cacerts
| `-- localhost-7054.pem
|-- intermediatecerts
| `-- localhost-7054.pem
|-- keystore
`-- signcerts
注意通过getcacert得到msp目录中只有CA证书。
同样的方式为org1.example.com获取msp:
mkdir -p fabric-ca-files/org1.example.com/msp
fabric-ca-client getcacert -M `pwd`/fabric-ca-files/org1.example.com/msp
为org2.example.com准备msp:
mkdir -p ./fabric-ca-files/org2.example.com/msp
fabric-ca-client getcacert -M `pwd`/fabric-ca-files/org2.example.com/msp
这里是用getcacert
为每个组织准备需要的ca文件,在生成创始块的时候会用到。
在1.1.0版本的fabric-ca中,只会生成组件或用户在操作区块链的时候用到的证书和密钥,不会生成用来加密grpc通信的证书(tls证书)。这里继续沿用之前cryptogen生成的tls证书,在最后的重新部署操作,只会替换msp目录。
但是需要将验证tls证书的ca添加到msp目录中,如下:
cp -rf /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/ordererOrganizations/example.com/msp/tlscacerts fabric-ca-files/example.com/msp/
cp -rf /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/msp/tlscacerts/ fabric-ca-files/org1.example.com/msp/
cp -rf /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org2.example.com/msp/tlscacerts/ fabric-ca-files/org2.example.com/msp/
如果在你的环境中,各个组件域名的证书,是由第三方CA签署的,就将第三方CA的根证书添加到tlscacerts目录中。
fabric-ca-files/admin/fabric-ca-client-config.yaml
其中的
id
部分修改为:
id:
name: [email protected]
type: client
affiliation: com.example
maxenrollments: 0
attributes:
- name: hf.Registrar.Roles
value: client,orderer,peer,user
- name: hf.Registrar.DelegateRoles
value: client,orderer,peer,user
- name: hf.Registrar.Attributes
value: "*"
- name: hf.GenCRL
value: true
- name: hf.Revoker
value: true
- name: hf.AffiliationMgr
value: true
- name: hf.IntermediateCA
value: true
- name: role
value: admin
ecert: true
注意最后一行role属性,是我们自定义的属性,在配置文件中是单独设置ecert属性为true或者false,如果在命令行中,添加后缀:ecert
表示true
直接执行下面的命令,即可完成用户[email protected]
注册,注意这时候的注册使用fabricCA的admin账号完成的:
fabric-ca-client register -H `pwd`/fabric-ca-files/admin --id.secret=password
如果不用--id.secret
指定密码,会自动生成密码。
其它配置的含义是用户名为[email protected]
,类型是client
,它能够管理com.example.*
下的用户,如下:
--id.name [email protected] //用户名
--id.type client //类型为client
--id.affiliation "com.example" //权利访问
hf.Registrar.Roles=client,orderer,peer,user //能够管理的用户类型
hf.Registrar.DelegateRoles=client,orderer,peer,user //可以授权给子用户管理的用户类型
hf.Registrar.Attributes=* //可以为子用户设置所有属性
hf.GenCRL=true //可以生成撤销证书列表
hf.Revoker=true //可以撤销用户
hf.AffiliationMgr=true //能够管理联盟
hf.IntermediateCA=true //可以作为中间CA
role=admin:ecert //自定义属性
生成[email protected]凭证:
$ mkdir -p ./fabric-ca-files/example.com/admin
$ fabric-ca-client enroll -u http://[email protected]:password@localhost:7054 -H `pwd`/fabric-ca-files/example.com/admin
$ ls ./fabric-ca-files/example.com/admin
fabric-ca-client-config.yaml msp/
这时候可以用[email protected]的身份查看联盟:
$ fabric-ca-client affiliation list -H `pwd`/fabric-ca-files/example.com/admin
2018/04/28 15:35:10 [INFO] 127.0.0.1:38172 GET /affiliations 201 0 "OK"
affiliation: com
affiliation: com.example
affiliation: com.example.org1
affiliation: com.example.org2
最后需要将[email protected]的证书复制到example.com/msp/admincerts/
mkdir fabric-ca-files/example.com/msp/admincerts/
cp fabric-ca-files/example.com/admin/msp/signcerts/cert.pem fabric-ca-files/example.com/msp/admincerts/
只有这样,才能具备管理员权限。
为org1.example.com的管理员[email protected]准备一个目录:
cd ~/fabriccert
mkdir -p ./fabric-ca-files/org1.example.com/admin
将fabric-ca-files/admin/fabric-ca-client-config.yaml
其中的id
部分修改为:
id:
name: [email protected]
type: client
affiliation: com.example.org1
maxenrollments: 0
attributes:
- name: hf.Registrar.Roles
value: client,orderer,peer,user
- name: hf.Registrar.DelegateRoles
value: client,orderer,peer,user
- name: hf.Registrar.Attributes
value: "*"
- name: hf.GenCRL
value: true
- name: hf.Revoker
value: true
- name: hf.AffiliationMgr
value: true
- name: hf.IntermediateCA
value: true
- name: role
value: admin
ecert: true
注册:
fabric-ca-client register -H `pwd`/fabric-ca-files/admin --id.secret=password
生成凭证:
$ fabric-ca-client enroll -u http://[email protected]:password@localhost:7054 -H `pwd`/fabric-ca-files/org1.example.com/admin
$ ls ./fabric-ca-files/org1.example.com/admin
fabric-ca-client-config.yaml msp/
查看联盟:
$ fabric-ca-client affiliation list -H `pwd`/fabric-ca-files/org1.example.com/admin
2018/05/04 15:42:53 [INFO] 127.0.0.1:51298 GET /affiliations 201 0 "OK"
affiliation: com
affiliation: com.example
affiliation: com.example.org1
注意与[email protected]
的区别,这里只能看到组织com.example.org1
将[email protected]的证书复制到org1.example.com的msp/admincerts中:
mkdir fabric-ca-files/org1.example.com/msp/admincerts/
cp fabric-ca-files/org1.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org1.example.com/msp/admincerts/
在[email protected]中也需要创建msp/admincerts目录,通过peer命令操作fabric的时候会要求admincerts存在:
mkdir fabric-ca-files/org1.example.com/admin/msp/admincerts/
cp fabric-ca-files/org1.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org1.example.com/admin/msp/admincerts/
另外,这里没有使用中间CA,将intermediatecerts中的空文件删除,否则peer会提示Warning:
rm fabric-ca-files/org1.example.com/admin/msp/intermediatecerts/*
为org2.example.com的管理员[email protected]准备一个目录:
cd ~/fabriccert
mkdir -p ./fabric-ca-files/org2.example.com/admin
将fabric-ca-files/admin/fabric-ca-client-config.yaml
其中的id
部分修改为:
id:
name: [email protected]
type: client
affiliation: com.example.org2
maxenrollments: 0
attributes:
- name: hf.Registrar.Roles
value: client,orderer,peer,user
- name: hf.Registrar.DelegateRoles
value: client,orderer,peer,user
- name: hf.Registrar.Attributes
value: "*"
- name: hf.GenCRL
value: true
- name: hf.Revoker
value: true
- name: hf.AffiliationMgr
value: true
- name: hf.IntermediateCA
value: true
- name: role
value: admin
ecert: true
注册:
fabric-ca-client register -H `pwd`/fabric-ca-files/admin --id.secret=password
生成凭证:
$ fabric-ca-client enroll -u http://[email protected]:password@localhost:7054 -H `pwd`/fabric-ca-files/org2.example.com/admin
$ ls ./fabric-ca-files/org2.example.com/admin
fabric-ca-client-config.yaml msp/
查看联盟:
$ fabric-ca-client affiliation list -H `pwd`/fabric-ca-files/org2.example.com/admin
2018/05/02 16:49:00 [INFO] 127.0.0.1:50828 GET /affiliations 201 0 "OK"
affiliation: com
affiliation: com.example
affiliation: com.example.org2
[email protected]只能看到组织com.example.org2
。
将[email protected]的证书复制到org2.example.com的msp/admincerts中:
mkdir fabric-ca-files/org2.example.com/msp/admincerts/
cp fabric-ca-files/org2.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org2.example.com/msp/admincerts/
在[email protected]中也需要创建msp/admincerts目录,通过peer命令操作fabric的时候会要求admincerts存在:
mkdir fabric-ca-files/org2.example.com/admin/msp/admincerts/
cp fabric-ca-files/org2.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org2.example.com/admin/msp/admincerts/
另外,这里没有使用中间CA,将intermediatecerts中的空文件删除,否则peer会提示Warning:
rm fabric-ca-files/org2.example.com/admin/msp/intermediatecerts/*
example.com、org1.example.com、org2.example.com三个组织这时候可以分别使用自己的Admin账号创建子账号。
使用[email protected]
注册账号orderer.example.com。注意这时候指定的目录是fabric-ca-files/example.com
/admin/。
修改fabric-ca-files/example.com/admin/fabric-ca-client-config.yaml:
id:
name: orderer.example.com
type: orderer
affiliation: com.example
maxenrollments: 0
attributes:
- name: role
value: orderer
ecert: true
注册以及生成凭证:
fabric-ca-client register -H `pwd`/fabric-ca-files/example.com/admin --id.secret=password
mkdir ./fabric-ca-files/example.com/orderer
fabric-ca-client enroll -u http://orderer.example.com:password@localhost:7054 -H `pwd`/fabric-ca-files/example.com/orderer
将[email protected]
的证书复制到fabric-ca-files/example.com/orderer/msp/admincerts:
mkdir fabric-ca-files/example.com/orderer/msp/admincerts
cp fabric-ca-files/example.com/admin/msp/signcerts/cert.pem fabric-ca-files/example.com/orderer/msp/admincerts/
使用[email protected]
注册账号peer0.org1.example.com。这时候指定的目录是fabric-ca-files/org1.example.com
/admin/。
修改fabric-ca-files/org1.example.com/admin/fabric-ca-client-config.yaml:
id:
name: peer0.org1.example.com
type: peer
affiliation: com.example.org1
maxenrollments: 0
attributes:
- name: role
value: peer
ecert: true
注册以及生成凭证:
fabric-ca-client register -H `pwd`/fabric-ca-files/org1.example.com/admin --id.secret=password
mkdir ./fabric-ca-files/org1.example.com/peer0
fabric-ca-client enroll -u http://peer0.org1.example.com:password@localhost:7054 -H `pwd`/fabric-ca-files/org1.example.com/peer0
将[email protected]
的证书复制到fabric-ca-files/org1.example.com/peer0/msp/admincerts:
mkdir fabric-ca-files/org1.example.com/peer0/msp/admincerts
cp fabric-ca-files/org1.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org1.example.com/peer0/msp/admincerts/
使用[email protected]
注册账号peer1.org1.example.com。这时候指定的目录是fabric-ca-files/org1.example.com
/admin/。
修改fabric-ca-files/org1.example.com/admin/fabric-ca-client-config.yaml:
id:
name: peer1.org1.example.com
type: peer
affiliation: com.example.org1
maxenrollments: 0
attributes:
- name: role
value: peer
ecert: true
注册以及生成凭证:
fabric-ca-client register -H `pwd`/fabric-ca-files/org1.example.com/admin --id.secret=password
mkdir ./fabric-ca-files/org1.example.com/peer1
fabric-ca-client enroll -u http://peer1.org1.example.com:password@localhost:7054 -H `pwd`/fabric-ca-files/org1.example.com/peer1
将[email protected]
的证书复制到fabric-ca-files/org1.example.com/peer1/msp/admincerts:
mkdir fabric-ca-files/org1.example.com/peer1/msp/admincerts
cp fabric-ca-files/org1.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org1.example.com/peer1/msp/admincerts/
使用[email protected]
注册账号peer0.org2.example.com。这时候指定的目录是fabric-ca-files/org2.example.com
/admin/。
修改fabric-ca-files/org2.example.com/admin/fabric-ca-client-config.yaml:
id:
name: peer0.org2.example.com
type: peer
affiliation: com.example.org2
maxenrollments: 0
attributes:
- name: role
value: peer
ecert: true
注册以及生成凭证:
fabric-ca-client register -H `pwd`/fabric-ca-files/org2.example.com/admin --id.secret=password
mkdir ./fabric-ca-files/org2.example.com/peer0
fabric-ca-client enroll -u http://peer0.org2.example.com:password@localhost:7054 -H `pwd`/fabric-ca-files/org2.example.com/peer0
将[email protected]
的证书复制到fabric-ca-files/org2.example.com/peer0/msp/admincerts:
mkdir fabric-ca-files/org2.example.com/peer0/msp/admincerts
cp fabric-ca-files/org2.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org2.example.com/peer0/msp/admincerts/
使用[email protected]
注册账号peer1.org2.example.com。这时候指定的目录是fabric-ca-files/org2.example.com
/admin/。
修改fabric-ca-files/org2.example.com/admin/fabric-ca-client-config.yaml:
id:
name: peer1.org2.example.com
type: peer
affiliation: com.example.org2
maxenrollments: 0
attributes:
- name: role
value: peer
ecert: true
注册以及生成凭证:
fabric-ca-client register -H `pwd`/fabric-ca-files/org2.example.com/admin --id.secret=password
mkdir ./fabric-ca-files/org2.example.com/peer1
fabric-ca-client enroll -u http://peer1.org2.example.com:password@localhost:7054 -H `pwd`/fabric-ca-files/org2.example.com/peer1
将[email protected]
的证书复制到fabric-ca-files/org2.example.com/peer1/msp/admincerts:
mkdir fabric-ca-files/org2.example.com/peer1/msp/admincerts
cp fabric-ca-files/org2.example.com/admin/msp/signcerts/cert.pem fabric-ca-files/org2.example.com/peer1/msp/admincerts/
修改configtx.yaml
,将其中的msp路径修改为通过fabric-ca创建的msp目录:
Profiles:
TwoOrgsOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: /root/fabriccert/fabric-ca-files/example.com/msp
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: /root/fabriccert/fabric-ca-files/org1.example.com/msp
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: /root/fabriccert/fabric-ca-files/org2.example.com/msp
AnchorPeers:
- Host: peer0.org2.example.com
Port: 7051
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.example.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Kafka:
Brokers:
- 127.0.0.1:9092
Organizations:
Application: &ApplicationDefaults
Organizations:
注意configtx.yaml
中使用的每个组织的msp,不是组件的或者用户的。这个文件备用。
更新orderer.example.com/中的msp:
rm -rf orderer.example.com/msp/
cp -rf fabric-ca-files/example.com/orderer/msp orderer.example.com/
更新peer0.org1.example.com的msp:
rm -rf peer0.org1.example.com/msp/
cp -rf fabric-ca-files/org1.example.com/peer0/msp peer0.org1.example.com/
更新peer1.org1.example.com的msp:
rm -rf peer1.org1.example.com/msp/
cp -rf fabric-ca-files/org1.example.com/peer1/msp peer1.org1.example.com/
更新peer0.org2.example.com的msp:
rm -rf peer0.org2.example.com/msp/
cp -rf fabric-ca-files/org2.example.com/peer0/msp peer0.org2.example.com/
更新peer1.org2.example.com的msp:
rm -rf peer1.org2.example.com/msp/
cp -rf fabric-ca-files/org2.example.com/peer0/msp peer1.org2.example.com/
更新org1.example.com 的 admin
cd /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org1.example.com/users
rm -rf [email protected]/ msp
cp -rf /root/fabriccert/fabric-ca-files/org1.example.com/admin/msp [email protected]
更新org2.example.com的admin
cd /opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli/crypto-config/peerOrganizations/org2.example.com/users
rm -rf [email protected]/ msp
cp -rf /root/fabriccert/fabric-ca-files/org2.example.com/admin/msp [email protected]
fabric-ca 部署证书过程完成,可以启动网络,执行其他的操作了,
在执行创建channel过程中报错,Error: got unexpected status: BAD_REQUEST -- error authorizing update: error validating DeltaSet: policy for [Group] /Channel/Application not satisfied: Failed to reach implicit threshold of 1 sub-policies, required 1 remaining
错误原因是cli 连接的[email protected] 本地admin没有设置成ca生成的证书,还是使用之前的证书,替换之后不再报错。
在执行替换证书的过程中,一定要清楚要替换的证书的目录,否则很容易出现替换不完全,报错的情况