Pinvon's Blog

所见, 所闻, 所思, 所想

七 MSP

概述

Fabric网络提供的是联盟链服务, 联盟由多个组织构成, 组织中的成员提供了节点服务来维护网络, 并且通过身份来进行权限管理.

MSP是一个组件, 其中定义了身份验证, 鉴权和网络准入的规则.

MSP管理用户ID, 对想加入网络的客户端进行鉴权, 包括为提出交易的客户端分配密钥工作.

MSP会使用CA, 由CA来验证和销毁用户的证书.

MSP默认使用的是Fabric-CA API, 当然, 我们也可以使用其他的第三方CA. 因此, Fabric-CA不是必须的.

一个Fabric网络可以包含多个MSP, 对应每个组织.

msp目录

根据 crypto-config.yaml 的定义, 生成的目录结构如下图所示:

67.png

其中, 最重要的是 msp目录, 该目录下的内容代表了实体的身份信息.

68.png

工作流程

User使用CA进行鉴权. CA为应用, Peer, Orderer等节点标记身份, 验证他们的密钥. 通过签名算法和签名验证算法生成签名.

  1. 签名的生成始于签名算法, 各实体使用跟各自身份相关的密钥生成背书信息. 生成的签名是一串字节, 绑定到具体的身份.
  2. 使用签名认证算法, 根据身份, 背书信息和签名, 进行认证.
  3. 如果签名字节串包含输入背书信息的有效签名, 则验证通过.
  4. 用户可以看到网络中的交易, 与网络中的其他角色进行交易.

MSP的配置

组织与MSP之间建立映射关系

一个MSP可以和一个组织对应, 也可以和多个组织对应, 还可以和一个组织内的多个部门对应. 根据MSP配置好Peer节点后, 数据同步就限制在MSP定义的范围内.

一个组织对应多个MSP

这种情况下, 一个组织有多个部门, 从方便管理, 保护隐私的角度, 每个部门要设置不同的MSP. 每个Peer节点只设置一个MSP, 同一组织内不同MSP的Peer节点之间不能相互认证, 这样相同组织的不同部门之间不会同步数据.

多个组织对应一个MSP

这种情况是同一个联盟的不同组织之间采用相同的成员管理架构, 数据会在不同组织之间同步.

一个组织内部实现不同的权限控制

不同类型的节点使用不同的MSP

可能会有这样的需求, 希望给客户端, Peer节点, Orderer节点分别设置不同的MSP, 因为身份信息会包含MSP标识, 设置不同的MSP能确定身份类型.

管理员证书和CA证书

不要把CA证书设置成MSP管理员证书, 这样能把成员管理, 签发证书和验证证书等不同职责拆分开来, 方便管理与问题定位.

MSP的CA根证书与TLS的CA根证书

MSP的CA根证书和TLS的CA根证书以及相关的中间CA证书需要存放在不同的文件夹中, 避免混淆不同类别的证书.

吊销已经颁发的证书

Fabric CA

概述

用户信息的注册; 数字证书的发行; 数字证书的延期与吊销;

Fabric CA架构如图所示:

49.png

Fabric CA服务端提供用户登记和注册的数字证书管理功能, 数据存储后端可以是MySQL, PostgreSQL, LDAP等. Fabric CA服务能够采用无状态的集群部署, 通过HAProxy等软件实现负载均衡功能, 实现服务的高可用.

Fabric CA服务端提供了RESTful的接口供客户端工具和SDK访问. 手工部署的方式可以采用客户端工具来实现, 如果集成到应用程序中, 可以采用SDK来实现. 通过SDK注册的证书有多种类型, 包括user, app, peer, orderer等.

部署Fabric CA服务端

安装Go, 设置GOPATH, 安装libtool, libtdhl-dev

安装Fabric CA服务端和客户端

本地编译Fabric-CA:

# 配置GOPATH
# 安装 libtool 和 libltdl-dev
go get -u -ldflags "-linkmode external -extldflags '-static -lpthread'" github.com/hyperledger/fabric-ca/cmd/...

也可以直接到Docker Hub下载Fabric-CA的镜像:

docker pull hyperledger/fabric-ca

启动Fabric CA服务

通过如下命令进入容器, 执行服务端或客户端命令:

docker run -it hyperledger/fabric-ca bash

# 查看fabric-ca-server使用方法
fabric-ca-server -h

# 查看fabric-ca-client使用方法
fabric-ca-client -h

# 初始化
fabric-ca-server init -b admin:adminpw

挂载本地配置文件

镜像中已经将配置目录 FABRIC_CA_SERVER_HOMEFABRIC_CA_CLIENT_HOME 指定为Volume资源. 用户在启动容器时, 可以将本地存放配置文件的目录挂载到容器中, 以方便对证书文件和数据库进行备份和管理:

docker run -it -v LOCAL_PATH:/etc/hyperledger/fabric-ca-server hyperledger/fabric-ca bash

暴露RESTful服务

容器作为CA服务使用时, 默认暴露的服务端口为7054, 为了让其他物理机能访问到容器内的服务, 可以将该端口映射到本地宿主机. 格式为 宿主端口:容器端口:

docker run -it -v LOCAL_PATH:/etc/hyperledger/fabric-ca-server -p 7054:7054 hyperledger/fabric-ca bash

启动CA服务

配置读取

fabric-ca-server服务所需要的相关配置项会依次尝试从命令行参数, 环境变量, 主配置目录这三个位置来读取. 这三个位置的优先级也是由高到低. 如果都没有配置, 则采用内置的默认值.

主配置目录

主配置目录的具体路径如何获取? fabric-ca-server服务会依次尝试从环境变量FABRIC_CA_SERVER_HOME, FABRIC_CA_HOME, CA_CFG_PATH中读取.

一般推荐使用默认的 /etc/hyperledger/fabric-ca-server 路径作为主配置目录环境变量的指向路径.

如果这三个环境变量都没有指定, 则使用当前目录作为主配置目录, 来搜索相关的配置文件.

初始化fabric-ca-server

69.png

初始化后, 会生成配置文件 fabric-ca-server-config.yaml, 放进配置主目录.

此时, 配置主目录下会生成4个文件.

  • ca-cert.pem: PEM格式的CA证书文件, 自签名
  • fabric-ca-server-config.yaml: 默认配置文件
  • fabric-ca-server.db: 存放数据的sqlite数据库
  • msp/keystore: 存放个人身份的私钥文件, 对应签名证书

默认情况下, fabric-ca-server-config.yaml 配置文件中未启用TLS, 如果要启用TLS, 需要修改tls.enabled为true, 同时修改csr.cn以匹配实际主机名, 之后 可以删掉证书和私钥文件, 重新生成对应文件.

启动fabric-ca-server

fabric-ca-server start -b admin:adminpw -n test_ca

初始化fabric-ca-server之后, 还要启动, fabric-ca-server才会监听7054端口. 如果之前没有初始化, 这一步也会去完成初始化的工作.

未来学习

学习如何存储到MySQL, 如何存储到PostgreSQL, 如何存储到LDAP.

这三种存储方式的优劣比较, 最终根据自己的情况, 应选择哪个来存储.

Fabric CA操作

访问Fabric CA服务端的方法有两种:

  1. Fabric CA 客户端
  2. RESTful API

其实, Fabric CA 客户端也是调用RESTful API来访问服务端的. 本质上说只有RESTful API这种方式.

Fabric CA 客户端

完整教程: 链接

这边举个例子. 在开启fabric-ca-server后, 再开一个终端, 进入fabric-ca容器, 发送登记命令:

docker exec -it 容器ID bash
fabric-ca-client enroll -u http://admin:adminpw@localhost:7054

Fabric CA的Restful API

默认的RESTful服务监听在0.0.0.0:7054地址, 服务前缀为/api/v1

接口定义在fabric-ca代码的 swagger/swagger-fabric-ca.json 文件中. 在v1.1.0版本中, 链接地址为: RESTFUL API

主要的接口有:

POST/cainfo: 获取CA的基本信息.

POST/enroll: 用户登记.

POST/reenroll: 用户重新登记.

POST/register: 用户注册.

POST/revoke: 撤销证书.

POST/tcert: 申请获取一批交易证书.

使用方法: 重开一个终端, 使用curl发送请求.

curl -X POST -d '{"caname":"test_ca"}' http://0.0.0.0:7054/api/v1/cainfo

Comments

使用 Disqus 评论
comments powered by Disqus