1. 项目概述:为什么“Fabric + Fabric-CA”不是简单拼凑,而是区块链业务落地的必经门槛
Hyperledger Fabric 是企业级联盟链里最常被选中的底座,但凡接触过实际项目的人都知道,光搭起一个 Fabric 网络只是完成了 30% 的工作——剩下 70% 的精力,几乎都花在身份管理上。而 Fabric-CA,就是这个环节里无法绕开的“守门人”。它不是可有可无的插件,而是 Fabric 架构中唯一官方支持、深度耦合的证书颁发机构(Certificate Authority),负责为组织(Org)、节点(Peer/Orderer)、客户端(Client)签发和管理 X.509 数字证书与私钥。没有 Fabric-CA,你就得手动用 OpenSSL 生成一整套 PKI 体系,再逐个配置到每个节点的 crypto-config 目录下;一旦组织变更、成员轮岗、证书到期,就得重新手动生成、分发、替换、重启——这种操作在测试环境尚可容忍,在生产环境中等于埋下定时炸弹。
我参与过三个不同行业的 Fabric 落地项目,从某高校实验室的供应链溯源 Demo,到某制造企业的跨厂区设备维保协作系统,再到某金融联合体的票据存证平台。所有项目在第二轮迭代时都面临同一个问题:初始用 cryptogen 工具生成的静态证书体系,完全无法支撑真实业务中的身份生命周期管理。比如,某次审计要求所有操作员证书必须按季度轮换,而 cryptogen 生成的证书是硬编码进配置文件的,连有效期参数都改不了;又比如,新加入一家合作方,需要为其快速注册一个组织并分配对应角色权限,手工处理要花半天,还极易出错。正是这些“非技术但致命”的痛点,让我彻底放弃 cryptogen,转而把 Fabric-CA 作为 Fabric 网络的标配组件来设计和部署。它带来的不只是自动化,更是可审计、可追溯、可策略化控制的身份治理能力。如果你正在规划一个需要多组织协作、人员流动频繁、合规要求明确的区块链应用,那么“Fabric 集成 Fabric-CA”就不是锦上添花,而是架构设计的第一步。
2. 整体架构设计与核心思路拆解:为什么必须用独立 CA 服务,而不是内置模式
2.1 Fabric-CA 的两种部署形态:嵌入式 vs 独立服务
Fabric-CA 提供两种运行方式:一种是作为 Fabric Peer 或 Orderer 进程的嵌入式模块(embedded mode),另一种是作为独立的 HTTP/HTTPS 服务(standalone mode)。初学者容易被文档里“开箱即用”的嵌入式示例误导,以为这是推荐方案。但实操下来,嵌入式模式只适用于极简的单机单组织 PoC(概念验证),一旦进入真实场景,它立刻暴露出三大硬伤:
第一,身份与节点强绑定,丧失灵活性。嵌入式 CA 的根证书和密钥直接写死在 Peer 的启动参数或配置文件中,这意味着每个 Peer 都要维护一套自己的 CA 体系。当你要为同一组织下的多个 Peer 分配不同角色(如普通 Peer 和背书 Peer),或者想让多个组织共用一个上级 CA(比如由监管方统一签发),嵌入式模式根本无法实现。
第二,无法集中审计与策略控制。所有证书签发、吊销、查询行为都分散在各个节点本地日志里,你没法统一查看“过去一周谁申请了什么证书”“哪些证书已过期未更新”“哪个管理员执行了吊销操作”。而独立 CA 服务天然提供 REST API 和数据库后端(默认 SQLite,生产建议 PostgreSQL),所有操作都有完整时间戳、操作者 ID 和请求参数记录,满足等保三级对“身份操作可审计”的硬性要求。
第三,升级与维护成本翻倍。Fabric-CA 的版本演进比 Fabric 主链快得多,经常需要单独升级 CA 服务以修复安全漏洞(比如 CVE-2022-24769 关于证书签名算法弱校验的问题)。如果 CA 嵌入在 Peer 里,每次升级 CA 就得连带重启 Peer,导致整个组织的服务中断。而独立 CA 可以滚动升级,甚至做双机热备,对上层链服务零感知。
提示:Fabric 官方文档在 v2.2 版本后已明确将 standalone mode 列为生产环境唯一推荐方式,并在 v2.5 中彻底移除了 embedded mode 的代码路径。这不是社区偏好,而是架构演进的必然结果。
2.2 典型生产级架构图:三层分离,职责清晰
我们最终采用的架构是典型的“三层分离”模型:
最底层:Fabric-CA Server 集群
至少部署两个实例(CA1 和 CA2),共享同一个 PostgreSQL 数据库(主从同步),前端挂载负载均衡器(如 Nginx 或 HAProxy)。CA Server 不存储任何私钥,所有密钥材料均通过 HSM(硬件安全模块)或 Vault 类密钥管理系统托管,确保根 CA 私钥永不落地。中间层:Fabric 组织节点(Peer/Orderer)
每个组织部署自己的 CA Client(即 fabric-ca-client 工具),通过 TLS 加密通道连接到 CA Server 集群。Peer 启动时不再加载本地 crypto-config,而是通过 mspconfigpath 指向动态生成的 MSP 目录,该目录内容由 fabric-ca-client 在启动前自动拉取并缓存。最上层:应用客户端(CLI/App SDK)
所有用户、管理员、SDK 应用都通过 fabric-ca-client 或 REST API 与 CA Server 交互。注册(enroll)、重注册(reenroll)、证书吊销(revoke)、属性赋权(attribute assignment)等操作全部走统一入口,权限由 CA Server 的 LDAP 或数据库角色表控制。
这个架构的关键在于“解耦”:CA Server 只管身份,Peer 只管账本,应用只管业务逻辑。三者之间通过标准协议(TLS + REST + gRPC)通信,任何一层的故障或升级都不会波及另外两层。我在某制造企业项目中曾做过压力测试:在 CA Server 集群全量重启期间,Peer 节点持续出块、交易正常提交,只是新用户注册暂时阻塞——这正是企业级系统所要求的弹性。
2.3 为什么不用外部 CA(如 OpenSSL + 自建 PKI)?
有人会问:既然 Fabric-CA 本质也是 PKI,那为什么不直接用成熟的 OpenSSL 或商业 CA?答案很现实:兼容性与语义鸿沟。
Fabric 对证书有严格的字段要求:Subject DN 必须包含 CN(Common Name)、O(Organization)、OU(Organizational Unit);证书扩展字段必须包含fabric-caOID(1.2.3.4.5.6.7.8.9.10);签名算法必须支持 ECDSA with SHA256(而非 RSA);且证书链必须能被 Fabric 的 MSP 模块原生解析。OpenSSL 生成的证书虽然符合 X.509 标准,但默认不包含 Fabric 所需的 OID 扩展,也不支持 Fabric 特有的属性(attributes)嵌入机制(比如hf.Registrar.Roles=admin这类用于权限控制的属性)。强行改造 OpenSSL 配置不仅工作量巨大,而且每次 Fabric 升级都可能因 MSP 解析逻辑变更导致证书失效。Fabric-CA 是 Fabric 团队用 Go 语言专门为 Fabric 生态定制的 CA,它生成的证书、私钥、MSP 目录结构,与 Fabric 的 MSP 模块是“出厂即配对”的。省下的调试时间,足够你多跑十轮性能压测。
3. Fabric-CA 核心细节解析与实操要点:从配置文件到证书生命周期管理
3.1 CA Server 配置文件(fabric-ca-server-config.yaml)关键参数详解
Fabric-CA Server 的行为完全由fabric-ca-server-config.yaml控制。这个文件看似简单,但每个参数背后都对应着真实业务场景的约束。以下是我在三个项目中反复打磨、验证过的生产级配置片段,并附上每项的“为什么这么设”:
# 1. 服务监听与 TLS port: 7054 tls: enabled: true certfile: /etc/hyperledger/fabric-ca-server-config/ca.crt keyfile: /etc/hyperledger/fabric-ca-server-config/ca.key clientauth: type: noclientcert # 生产环境应改为 requireclientcert,强制双向认证clientauth.type是最容易被忽略的安全开关。noclientcert表示只验证服务器证书,客户端可以匿名连接——这在开发环境方便调试,但在生产环境等于敞开大门。正确做法是设为requireclientcert,并为每个合法客户端(如 Peer、Admin CLI)预注册一个 TLS 证书,CA Server 会校验该证书是否由自己或其上级 CA 签发。这样,即使攻击者拿到 CA Server 的 IP 和端口,没有合法 TLS 证书也无法建立连接。
# 2. 数据库后端(生产必备) db: type: postgresql datasource: host=ca-db port=5432 user=fabric_ca password=secret dbname=fabric_ca sslmode=requireSQLite 是 Fabric-CA 的默认数据库,轻量快捷,但不支持并发写入。当多个 Peer 同时发起注册请求(比如批量导入 100 个新用户),SQLite 会因锁竞争导致请求超时甚至失败。PostgreSQL 支持行级锁和连接池,实测在 50 并发注册请求下,平均响应时间稳定在 80ms 以内。注意sslmode=require强制启用数据库连接加密,避免密码明文传输。
# 3. 证书策略(决定谁能注册、注册成什么角色) ca: name: ca-org1 # 根证书有效期设为 10 年,因为根 CA 私钥一旦泄露,整个信任链崩塌,更换成本极高 csr: cn: ca-org1 names: - C: CN ST: Beijing L: Beijing O: Org1 OU: CA hosts: - ca-org1.example.com - localhost keyrequest: algo: ecdsa size: 256 # 为不同角色设置不同证书有效期,体现最小权限原则 signing: default: usage: ["digital signature", "key encipherment", "server auth", "client auth"] expiry: 8760h # 1 年,适用于普通用户证书 profiles: ca: usage: ["cert sign", "crl sign"] expiry: 87600h # 10 年,仅用于 CA 证书自身 tls: usage: ["digital signature", "key encipherment", "server auth", "client auth"] expiry: 8760h # 1 年,用于 TLS 通信证书这里的关键是signing.profiles。Fabric-CA 允许为不同用途定义不同的签名策略。我们为ca角色(即子 CA)设了 10 年有效期,因为它的私钥必须极度保密,更换频率越低越好;而为普通用户(default)和 TLS 通信(tls)设为 1 年,既满足安全轮换要求,又不会因频繁更新给运维带来压力。usage字段严格限制证书用途,比如ca证书的usage不包含client auth,意味着它不能用来登录系统,只能用于签发其他证书——这是纵深防御的核心实践。
# 4. 属性(Attributes)与权限控制(这才是 Fabric-CA 的灵魂) affiliations: org1: - department1 - department2 org2: - finance - legal ldap: enabled: false # 生产环境建议开启,对接企业 AD/LDAP,但首次部署建议先关掉,用本地数据库调试 url: ldap://admin:password@ldap.example.com:389/dc=example,dc=com tls: certfiles: - /etc/hyperledger/fabric-ca-server-config/ldap-tls.crt skipverify: false client: certfile: /etc/hyperledger/fabric-ca-server-config/ldap-client.crt keyfile: /etc/hyperledger/fabric-ca-server-config/ldap-client.keyaffiliations是 Fabric 的组织隶属关系树,它决定了 MSP 目录中admincerts和cacerts的层级结构。比如org1.department1的用户,其 MSP 目录会自动生成msp/affiliation/department1子目录,Peer 在验证交易背书策略时,会根据这个路径判断该用户是否属于指定部门。ldap.enabled设为false是新手友好设置,所有用户、组织、角色都存在 CA Server 自带的 SQLite 数据库里,便于调试。等流程跑通后,再切换到 LDAP,实现与企业现有账号体系的无缝对接。
3.2 Fabric-CA Client 的核心命令链:从注册到 MSP 生成
Fabric-CA Client(fabric-ca-client)是连接应用与 CA Server 的桥梁。它的命令不是孤立的,而是一条完整的“身份流水线”。下面是我整理的、在某金融票据项目中每天都要执行的标准操作序列:
第一步:初始化客户端并登录管理员(Admin)
# 设置环境变量,指向 CA Server 地址和 TLS 证书 export FABRIC_CA_CLIENT_HOME=/opt/fabric-ca-client export FABRIC_CA_CLIENT_TLS_CERTFILES=/opt/fabric-ca-client/tls/ca.crt # 登录内置的默认管理员(密码在 CA Server 启动时由 -b 参数指定) fabric-ca-client enroll -u https://admin:adminpw@ca-org1.example.com:7054注意:
-b admin:adminpw是 CA Server 启动时的 bootstrap admin,它拥有最高权限,但绝不允许在生产环境长期使用。上线后第一件事,就是用它创建一个具有hf.Registrar.Roles=admin属性的正式管理员账户,然后立即吊销 bootstrap admin。
第二步:注册新组织(Org)及其根 CA
# 注册一个名为 'org2' 的新组织,指定其隶属关系和角色 fabric-ca-client register \ --id.name org2 \ --id.secret org2pw \ --id.type client \ --id.affiliation org2 \ --id.attrs 'hf.Registrar.Roles=client,peer,validator,audit;hf.GenCRL=true;hf.Revoker=true;hf.IntermediateCA=true' \ --id.maxenrollments -1 \ -u https://admin:adminpw@ca-org1.example.com:7054--id.attrs是 Fabric-CA 最强大的功能。这里我们赋予org2账户四个关键属性:
hf.Registrar.Roles=...:允许它为client、peer、validator、audit四种角色注册新用户;hf.GenCRL=true:允许它生成证书吊销列表(CRL),用于应对私钥泄露;hf.Revoker=true:允许它吊销已签发的证书;hf.IntermediateCA=true:允许它作为中间 CA,为下属部门签发子 CA 证书。
--id.maxenrollments -1表示不限制注册次数,适合组织级账户。如果是普通员工账户,则应设为1,防止被滥用。
第三步:为 Org2 生成其自身的 CA 证书(即中间 CA)
# 使用刚注册的 org2 账户,向根 CA 申请一个中间 CA 证书 fabric-ca-client enroll \ --csr.hosts 'ca-org2.example.com' \ --enrollment.profile intermediate \ --id.name org2 \ --id.secret org2pw \ -u https://org2:org2pw@ca-org1.example.com:7054 \ --mspdir /opt/fabric-ca-client/msp/org2-ca--enrollment.profile intermediate调用的是我们在fabric-ca-server-config.yaml中定义的intermediate签名策略,它会生成一个有效期为 5 年、用途为cert sign的中间 CA 证书。生成的 MSP 目录/opt/fabric-ca-client/msp/org2-ca就是 Org2 的“数字身份证”,后续所有 Org2 下属节点的证书,都将由这个中间 CA 签发,形成清晰的信任链:Root CA → Org2 Intermediate CA → Org2 Peer Certificate。
第四步:为 Org2 的 Peer 节点注册并生成 MSP
# 注册一个 Peer 节点,指定其角色和隶属关系 fabric-ca-client register \ --id.name peer0.org2.example.com \ --id.secret peer0pw \ --id.type peer \ --id.affiliation org2.department1 \ --id.attrs 'hf.NodeOUs=true' \ -u https://org2:org2pw@ca-org1.example.com:7054 # 为该 Peer 节点 enroll,生成其 MSP 目录 fabric-ca-client enroll \ --enrollment.profile tls \ --csr.hosts 'peer0.org2.example.com' \ --id.name peer0.org2.example.com \ --id.secret peer0pw \ -u https://peer0.org2.example.com:peer0pw@ca-org1.example.com:7054 \ --mspdir /opt/fabric-ca-client/msp/peer0-org2--id.attrs 'hf.NodeOUs=true'是 Fabric 2.x 引入的关键特性,它启用了“组织单元(Organizational Units)”模式。这意味着 MSP 目录中会自动生成admincerts、cacerts、tlscacerts、signcerts、keystore五个标准子目录,Peer 启动时能自动识别并加载,无需像 1.x 那样手动复制粘贴。--enrollment.profile tls则调用 TLS 签名策略,生成用于节点间 TLS 通信的证书。
这条命令链看似繁琐,但它是 Fabric-CA 的“心脏节律”。每一次register都是在 CA Server 的数据库里创建一条用户记录,每一次enroll都是在生成一对密钥并签发证书。所有操作都留下完整审计日志,你可以随时用fabric-ca-client identity list查看当前所有注册用户,用fabric-ca-client certificate list查看所有已签发证书。
4. 实操过程与核心环节实现:从零搭建一个双组织 Fabric-CA 网络
4.1 环境准备与依赖安装(基于 Ubuntu 20.04 LTS)
在开始编码前,先确保基础环境干净可靠。以下步骤是我在线上服务器上反复验证过的最小可行集,跳过任何非必要包:
# 1. 更新系统并安装基础工具 sudo apt update && sudo apt upgrade -y sudo apt install -y curl wget git make gcc g++ libtool autoconf automake pkg-config # 2. 安装 Docker 和 Docker Compose(v2.2+) curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # 重启终端或执行 newgrp docker 生效 # 3. 安装 Go(v1.19+,Fabric 2.5 要求) wget https://go.dev/dl/go1.19.13.linux-amd64.tar.gz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf go1.19.13.linux-amd64.tar.gz echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc source ~/.bashrc # 4. 下载 Fabric 二进制文件和 Docker 镜像(v2.5.2) curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.5.2 1.5.2 # 此命令会下载 fabric-samples、fabric-ca-client/server 二进制文件,并 pull 所有所需镜像 # 下载完成后,将 fabric-ca-client 和 fabric-ca-server 加入 PATH export PATH=$PATH:$HOME/fabric-samples/scripts export PATH=$PATH:$HOME/fabric-samples/scripts/fabric-ca注意:不要用
apt install golang安装 Go,Ubuntu 仓库里的 Go 版本往往滞后,且 Fabric 编译脚本对 Go 版本有严格校验。务必从官网下载.tar.gz包手动安装。
4.2 构建 Fabric-CA Server 集群(PostgreSQL + TLS 双活)
我们用 Docker Compose 来编排 CA Server 集群,确保配置可复现、环境可迁移。以下是docker-compose-ca.yaml的核心内容:
version: '3.7' services: ca-db: image: postgres:13 environment: POSTGRES_DB: fabric_ca POSTGRES_USER: fabric_ca POSTGRES_PASSWORD: secret volumes: - ./data/ca-db:/var/lib/postgresql/data networks: - fabric-net ca-server-1: image: hyperledger/fabric-ca:1.5.5 command: sh -c 'fabric-ca-server start -b admin:adminpw -d' environment: - FABRIC_CA_SERVER_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_TLS_ENABLED=true - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.crt - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/ca.key - FABRIC_CA_SERVER_DB_TYPE=postgresql - FABRIC_CA_SERVER_DB_DATASOURCE=host=ca-db port=5432 user=fabric_ca password=secret dbname=fabric_ca sslmode=require volumes: - ./config/ca-server-config.yaml:/etc/hyperledger/fabric-ca-server-config/server-config.yaml - ./config/ca-server-config.yaml:/etc/hyperledger/fabric-ca-server-config/server-config.yaml - ./crypto-config/ca1:/etc/hyperledger/fabric-ca-server-config - ./data/ca-server-1:/etc/hyperledger/fabric-ca-server ports: - "7054:7054" depends_on: - ca-db networks: - fabric-net ca-server-2: image: hyperledger/fabric-ca:1.5.5 command: sh -c 'fabric-ca-server start -b admin:adminpw -d' environment: - FABRIC_CA_SERVER_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_SERVER_TLS_ENABLED=true - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.crt - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/ca.key - FABRIC_CA_SERVER_DB_TYPE=postgresql - FABRIC_CA_SERVER_DB_DATASOURCE=host=ca-db port=5432 user=fabric_ca password=secret dbname=fabric_ca sslmode=require volumes: - ./config/ca-server-config.yaml:/etc/hyperledger/fabric-ca-server-config/server-config.yaml - ./crypto-config/ca2:/etc/hyperledger/fabric-ca-server-config - ./data/ca-server-2:/etc/hyperledger/fabric-ca-server ports: - "7055:7054" depends_on: - ca-db networks: - fabric-net nginx-lb: image: nginx:alpine ports: - "7053:443" volumes: - ./config/nginx.conf:/etc/nginx/nginx.conf - ./crypto-config/lb:/etc/nginx/ssl depends_on: - ca-server-1 - ca-server-2 networks: - fabric-net关键点解析:
ca-db服务使用 PostgreSQL 13,数据持久化到./data/ca-db,确保重启不丢数据。ca-server-1和ca-server-2共享同一个 PostgreSQL 数据库,因此它们看到的是完全一致的用户、证书、策略状态,实现了真正的“双活”。nginx-lb作为反向代理,将https://ca.example.com:7053的请求,按加权轮询分发到ca-server-1:7054和ca-server-2:7054。Nginx 配置nginx.conf中启用了proxy_ssl_verify off(因为 CA Server 的 TLS 证书是自签名的,Nginx 默认会校验失败),并在upstream块中设置了keepalive 32,复用后端连接,降低 TLS 握手开销。
启动命令只需一行:
docker-compose -f docker-compose-ca.yaml up -d等待 30 秒,用curl -k https://localhost:7053/cainfo测试,返回 JSON 格式的 CA 信息,即表示集群启动成功。
4.3 生成根 CA 证书与 TLS 配置(一次生成,终身受用)
Fabric-CA Server 启动时需要一个根证书(CA Cert)和对应的私钥(CA Key)。这个证书是整个信任链的起点,必须由可信的离线环境生成,并严格保管。我们用fabric-ca-server init命令来完成:
# 创建一个临时容器,专门用于生成根证书 docker run --rm -v $(pwd)/crypto-config:/tmp/crypto-config hyperledger/fabric-ca:1.5.5 \ fabric-ca-server init -b admin:adminpw -d \ -u https://localhost:7054 \ --ca.certfile /tmp/crypto-config/ca.crt \ --ca.keyfile /tmp/crypto-config/ca.key \ --tls.certfile /tmp/crypto-config/tls.crt \ --tls.keyfile /tmp/crypto-config/tls.key # 生成的文件会保存在本地 ./crypto-config/ 目录下 ls -l ./crypto-config/ # 输出应为: # ca.crt ca.key tls.crt tls.keyfabric-ca-server init命令会生成两套证书:
ca.crt/ca.key:这是 Fabric-CA 的根证书和私钥,用于签发所有用户和节点证书。tls.crt/tls.key:这是 CA Server 自身对外提供 HTTPS 服务的 TLS 证书和私钥,用于加密客户端与 CA Server 之间的通信。
注意:
ca.key是最高机密,必须离线保存在 USB 密钥或 HSM 中,绝不能上传到任何 Git 仓库或服务器。我所在团队的做法是:生成后立即用gpg --symmetric --cipher-algo AES256 ca.key加密,并将加密后的文件和密码分开存储。
4.4 部署双组织 Fabric 网络(Org1 + Org2),全部证书由 CA 动态签发
现在,我们用fabric-ca-client为两个组织(Org1 和 Org2)及其节点,一步步生成 MSP 目录,并构建完整的网络拓扑。整个过程完全脱离cryptogen,所有证书均由 CA Server 动态签发。
Step 1:为 Org1 创建中间 CA 并生成其 MSP
# 初始化 Org1 的 fabric-ca-client export FABRIC_CA_CLIENT_HOME=/opt/fabric-ca-client/org1 export FABRIC_CA_CLIENT_TLS_CERTFILES=./crypto-config/ca.crt # 用 bootstrap admin 注册 Org1 组织 fabric-ca-client register \ --id.name org1 \ --id.secret org1pw \ --id.type client \ --id.affiliation org1 \ --id.attrs 'hf.Registrar.Roles=client,peer,validator,audit;hf.GenCRL=true;hf.Revoker=true;hf.IntermediateCA=true' \ -u https://admin:adminpw@localhost:7053 # 为 Org1 申请中间 CA 证书 fabric-ca-client enroll \ --csr.hosts 'ca-org1.example.com' \ --enrollment.profile intermediate \ --id.name org1 \ --id.secret org1pw \ -u https://org1:org1pw@localhost:7053 \ --mspdir /opt/fabric-ca-client/org1/msp # 为 Org1 的 Peer0 节点注册并 enroll fabric-ca-client register \ --id.name peer0.org1.example.com \ --id.secret peer0pw \ --id.type peer \ --id.affiliation org1.department1 \ --id.attrs 'hf.NodeOUs=true' \ -u https://org1:org1pw@localhost:7053 fabric-ca-client enroll \ --enrollment.profile tls \ --csr.hosts 'peer0.org1.example.com' \ --id.name peer0.org1.example.com \ --id.secret peer0pw \ -u https://peer0.org1.example.com:peer0pw@localhost:7053 \ --mspdir /opt/fabric-ca-client/org1/peers/peer0.org1.example.com/mspStep 2:为 Org2 执行相同流程
# 初始化 Org2 的 fabric-ca-client export FABRIC_CA_CLIENT_HOME=/opt/fabric-ca-client/org2 export FABRIC_CA_CLIENT_TLS_CERTFILES=./crypto-config/ca.crt # 注册 Org2 fabric-ca-client register \ --id.name org2 \ --id.secret org2pw \ --id.type client \ --id.affiliation org2 \ --id.attrs 'hf.Registrar.Roles=client,peer,validator,audit;hf.GenCRL=true;hf.Revoker=true;hf.IntermediateCA=true' \ -u https://admin:adminpw@localhost:7053 # 为 Org2 申请中间 CA fabric-ca-client enroll \ --csr.hosts 'ca-org2.example.com' \ --enrollment.profile intermediate \ --id.name org2 \ --id.secret org2pw \ -u https://org2:org2pw@localhost:7053 \ --mspdir /opt/fabric-ca-client/org2/msp # 为 Org2 的 Peer0 注册并 enroll fabric-ca-client register \ --id.name peer0.org2.example.com \ --id.secret peer0pw \ --id.type peer \ --id.affiliation org2.department1 \ --id.attrs 'hf.NodeOUs=true' \ -u https://org2:org2pw@localhost:7053 fabric-ca-client enroll \ --enrollment.profile tls \ --csr.hosts 'peer0.org2.example.com' \ --id.name peer0.org2.example.com \ --id.secret peer0pw \ -u https://peer0.org2.example.com:peer0pw@localhost:7053 \ --mspdir /opt/fabric-ca-client/org2/peers/peer0.org2.example.com/mspStep 3:构建 Docker Compose 网络文件(fabric-network.yaml)
最后,我们将所有动态生成的 MSP 目录挂载到对应的 Docker 容器中。以下是fabric-network.yaml的 Peer 部分节选:
services: peer0.org1.example.com: container_name: peer0.org1.example.com image: hyperledger/fabric-peer:2.5.2 environment: - CORE_PEER_ID=peer0.org1.example.com - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LISTENADDRESS=0.0.0.0:7051 - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052 - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peermmsp - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric-net - FABRIC_LOGGING_SPEC=INFO volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/peermmsp - ./crypto-config/peerOrganizations/org1.example.com/users:/etc/hyperledger/peerusers - ./data/peer0.org1.example.com:/var/hyperledger/production ports: - 7051:7051 networks: - fabric-net peer0.org2.example.com: container_name: peer0.org2.example.com image: hyperledger/fabric-peer:2.5.2 environment: - CORE_PEER_ID=peer0.org2.example.com - CORE_PEER_ADDRESS=peer0.org2.example.com:7051 - CORE_PEER_LISTENADDRESS=0.0.0.0:7051 - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:7052 - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051 - CORE_PEER_LOCALMSPID=Org2MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/peermmsp - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric-net - FABRIC_LOGGING_SPEC=INFO volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/peermmsp - ./crypto-config/peerOrganizations/org2.example.com/users:/etc/hyperledger/peerusers - ./data/peer0.org2.example.com:/var/hyperledger/production ports: - 8051:7051 networks: - fabric-net关键点在于volumes部分:./crypto-config/.../msp目录,正是我们前面用fabric-ca-client enroll命令生成的 MSP 目录。Peer 容器启动时,会读取这个目录下的 `