🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。
  
📌 特别说明:
文中问题案例来源于真实生产环境与公开技术社区,并结合多位一线资深工程师与架构师的长期实践经验,经过人工筛选与AI系统化智能整理后输出。文中的解决方案并非唯一“标准答案”,而是兼顾可行性、可复现性与思路启发性的实践参考,供你在实际项目中灵活运用与演进。
  
欢迎订阅本专栏,一次订阅后,专栏内所有文章可永久免费阅读,后续更新内容皆不用再次订阅,持续更新中。

📢 问题描述

详细问题描述如下: 在docker容器中的控制台目录下执行start.sh这个文件时这样子报错:create BcosSDK failed, error info: init channel network error: Failed to connect to all the nodes!

具体如下:

create BcosSDK failed, error info: init channel network error: Failed to connect to all the nodes! errorMessage:
ssl handshake failed:/10.1.0.10:20200! Please check the certificate and ensure that the SDK and the node are in the same agency!
ssl handshake failed:/10.1.0.11:20200! Please check the certificate and ensure that the SDK and the node are in the same agency!
ssl handshake failed:/10.1.0.12:20200! Please check the certificate and ensure that the SDK and the node are in the same agency!
ssl handshake failed:/10.1.0.20:20200! Please check the certificate and ensure that the SDK and the node are in the same agency!
ssl handshake failed:/10.1.0.21:20200! Please check the certificate and ensure that the SDK and the node are in the same agency!
ssl handshake failed:/10.1.0.22:20200! Please check the certificate and ensure that the SDK and the node are in the same agency!

📣 请知悉:如下方案不保证一定适配你的问题!

  如下是针对上述问题进行专业角度剖析答疑,不喜勿喷,仅供参考:

✅️ 问题理解

这是 Docker 容器内的 WeBASE 控制台 尝试连接 FISCO BCOS 节点时,发生 SSL/TLS 握手失败的问题 🔍

错误核心信息解读:

ssl handshake failed:/10.1.0.10:20200!
Please check the certificate and ensure that the SDK and the node are in the same agency!

这句话已经把根因说得很清楚了:SDK(控制台)使用的证书,与区块链节点不属于同一个机构(Agency),导致双向 TLS 认证失败。

深层原因分析:

FISCO BCOS 采用双向 TLS(Mutual TLS)认证机制,节点只信任同一机构 CA 签发的证书。控制台的 conf/ 目录下必须存放与节点同机构的 SDK 证书,才能握手成功。在 Docker 环境中这个问题更常见,因为容器内的证书挂载路径很容易配错。

✅️ 问题解决方案

🟢 方案 A:从对应节点目录重新拷贝正确的 SDK 证书(最直接根本)

错误的根本是证书不对,必须从生成节点时产生的 sdk/ 目录拿证书。

第一步:先确认节点证书目录在宿主机上的位置

# 在宿主机(不是容器里)执行
# 找到节点生成目录
find / -name "sdk" -type d 2>/dev/null | grep fisco

# 通常路径类似:
ls ~/fisco/nodes/10.1.0.10/sdk/
# 应包含:ca.crt  sdk.crt  sdk.key

第二步:确认是多机构部署还是单机构部署

从报错 IP 可以看出,10.1.0.10 ~ 10.1.0.22 跨越多个 IP,说明这是多机器部署的联盟链

# 查看每台机器节点的 agency 信息
cat ~/fisco/nodes/10.1.0.10/node0/conf/ca.crt | openssl x509 -noout -subject
# 重点看 O= 字段,这就是机构名

cat ~/fisco/nodes/10.1.0.10/sdk/ca.crt | openssl x509 -noout -subject
# 对比两个 ca.crt 的 O= 字段是否一致

第三步:将正确的 SDK 证书复制到 Docker 容器挂载的 conf 目录

# 找到控制台容器挂载的 conf 目录
docker inspect 容器名或ID | grep -A 20 "Mounts"
# 找到类似:
# "Source": "/host/path/to/console/conf"
# "Destination": "/fisco/console/conf"

# 把正确证书拷贝到宿主机挂载目录
cp ~/fisco/nodes/10.1.0.10/sdk/ca.crt  /host/path/to/console/conf/
cp ~/fisco/nodes/10.1.0.10/sdk/sdk.crt /host/path/to/console/conf/
cp ~/fisco/nodes/10.1.0.10/sdk/sdk.key /host/path/to/console/conf/

# 验证文件存在
ls -la /host/path/to/console/conf/

第四步:进入容器验证证书路径

# 进入容器
docker exec -it 容器名 bash

# 检查容器内证书
ls -la /fisco/console/conf/
cat /fisco/console/conf/config.toml | grep -A 10 "\[cert\]"
# 确认 caCert / sslCert / sslKey 路径与实际文件一致

# 验证证书内容
openssl x509 -in /fisco/console/conf/ca.crt -noout -subject -dates

第五步:重启容器后再执行 start.sh

# 退出容器后重启
docker restart 容器名
docker exec -it 容器名 bash
cd /fisco/console && bash start.sh
🟢 方案 B:检查并修正 config.toml 中的节点地址和证书路径(配置排查)

即使证书文件存在,config.toml 配置错误也会导致握手失败。

# 进入容器
docker exec -it 容器名 bash

# 查看 config.toml 完整内容
cat /fisco/console/conf/config.toml

重点检查以下字段:

[network]
# ⚠️ 节点 IP 端口必须与实际节点一致,且容器网络能访问
peers=["10.1.0.10:20200","10.1.0.11:20200","10.1.0.12:20200"]

[cert]
# ⚠️ 路径是容器内路径,必须是绝对路径或相对于运行目录的正确相对路径
caCert = "conf/ca.crt"       # 确认文件真实存在
sslCert = "conf/sdk.crt"     # 确认文件真实存在
sslKey = "conf/sdk.key"      # 确认文件真实存在

如果使用国密(GM/SM)版本,配置不同:

[cert]
caCert = "conf/gm/gmca.crt"
sslCert = "conf/gm/gmsdk.crt"
sslKey = "conf/gm/gmsdk.key"
enSslCert = "conf/gm/gmensdk.crt"
enSslKey = "conf/gm/gmensdk.key"

修改完 config.toml 后,不需要重启容器,直接重新执行:

bash start.sh
🟢 方案 C:修复 Docker 网络导致容器访问不到节点 IP(网络连通性问题)

容器内可能因为网络隔离,根本无法访问宿主机或其他机器的 10.1.0.x IP。

第一步:在容器内测试网络连通性

docker exec -it 容器名 bash

# 测试能否 ping 通节点
ping 10.1.0.10 -c 3

# 测试端口是否可达(更精准)
curl -v telnet://10.1.0.10:20200 2>&1 | head -5
# 或
nc -zv 10.1.0.10 20200

第二步:如果网络不通,修改 Docker 网络模式

# 方式1:以 host 网络模式重新启动容器(容器与宿主机共享网络)
docker run --network host -it \
  -v /宿主机/console/conf:/fisco/console/conf \
  镜像名 bash

# 方式2:docker-compose 中指定 host 网络
# 在 docker-compose.yml 中添加:
# network_mode: "host"

# 方式3:确保容器在能访问节点 IP 的自定义网络中
docker network create fisco-net --subnet=10.1.0.0/24
docker run --network fisco-net --ip 10.1.0.100 -it 镜像名 bash
🟡 方案 D:多机构联盟链场景——确认控制台属于哪个机构

从报错 IP 分布(10.1.0.10/11/12 和 10.1.0.20/21/22)来看,这很可能是两个机构的联盟链部署(每个机构 3 个节点)。

# 在宿主机上检查各机构的证书机构信息
# 机构1的 CA
openssl x509 -in ~/fisco/nodes/10.1.0.10/sdk/ca.crt -noout -subject
# 输出示例:subject=CN=agency1, O=fisco-bcos, C=CN

# 机构2的 CA(如果有)
openssl x509 -in ~/fisco/nodes/10.1.0.20/sdk/ca.crt -noout -subject
# 输出示例:subject=CN=agency2, O=fisco-bcos, C=CN

控制台的证书必须来自它要连接的节点所在机构!

# 验证控制台当前使用的证书是哪个机构
docker exec 容器名 openssl x509 -in /fisco/console/conf/ca.crt -noout -subject

# 对比节点的 ca.crt
docker exec 容器名 openssl x509 -in /fisco/console/conf/ca.crt -noout -issuer

# 如果机构不匹配,必须替换成对应机构的证书
🟡 方案 E:证书权限问题修复

Docker 容器内有时证书文件权限设置不当,导致 SDK 无法读取:

docker exec -it 容器名 bash

# 检查证书文件权限
ls -la /fisco/console/conf/

# 修复权限
chmod 644 /fisco/console/conf/ca.crt
chmod 644 /fisco/console/conf/sdk.crt
chmod 600 /fisco/console/conf/sdk.key   # 私钥只允许拥有者读取

# 或者直接放开权限(仅学习环境)
chmod 755 /fisco/console/conf/
chmod 644 /fisco/console/conf/*
🔴 方案 F:从零重建控制台容器(终极方案)

当证书路径彻底混乱时,重新生成一个干净的控制台容器:

# 第一步:在宿主机准备好正确的证书目录
mkdir -p ~/console-conf
cp ~/fisco/nodes/10.1.0.10/sdk/ca.crt  ~/console-conf/
cp ~/fisco/nodes/10.1.0.10/sdk/sdk.crt ~/console-conf/
cp ~/fisco/nodes/10.1.0.10/sdk/sdk.key ~/console-conf/

# 第二步:准备正确的 config.toml
cat > ~/console-conf/config.toml <<'EOF'
[network]
peers=["10.1.0.10:20200","10.1.0.11:20200","10.1.0.12:20200"]

[cert]
caCert = "conf/ca.crt"
sslCert = "conf/sdk.crt"
sslKey = "conf/sdk.key"
EOF

# 第三步:重新运行控制台容器并挂载证书
docker run -it \
  --network host \
  -v ~/console-conf:/fisco/console/conf \
  --name fisco-console-new \
  fiscoorg/fiscobcos-console:latest \
  bash

# 进入容器后执行
cd /fisco/console && bash start.sh

✅️ 问题延伸

FISCO BCOS 证书体系全图

核心规则: SDK 证书必须与它要连接的节点证书属于同一机构 CA 签发。

Docker 中证书挂载最佳实践
# docker-compose.yml 示例
version: '3'
services:
  console:
    image: fiscoorg/fiscobcos-console:latest
    network_mode: host   # 使用 host 网络避免网络隔离
    volumes:
      - ./nodes/10.1.0.10/sdk:/fisco/console/conf   # 直接挂载 sdk 目录
    command: bash start.sh
快速验证 SSL 握手是否成功的命令
# 在容器内手动测试 TLS 握手
openssl s_client \
  -connect 10.1.0.10:20200 \
  -cert /fisco/console/conf/sdk.crt \
  -key /fisco/console/conf/sdk.key \
  -CAfile /fisco/console/conf/ca.crt \
  -tls1_2 2>&1 | head -30

# 成功时应看到:Verify return code: 0 (ok)
# 失败时会看到:Verify return code: 20 (unable to get local issuer certificate)

✅️ 问题预测

🔮 解决握手问题后可能遇到的后续报错:

预测 1:证书问题解决了,但提示 GroupID 不存在

# 查看节点已有的 Group
curl http://10.1.0.10:8545 \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"getGroupList","id":1}'

# 在 config.toml 中确认 groupID 与实际一致

预测 2:容器重启后证书又丢失

# 说明 volume 挂载配置有问题,改用 Docker named volume
docker volume create fisco-certs
docker run -v fisco-certs:/fisco/console/conf ...
# 第一次运行时把证书复制进去
docker cp ~/console-conf/. 容器名:/fisco/console/conf/

预测 3:国密版本证书配置错误

# 检查节点是否为国密版本
file ~/fisco/nodes/10.1.0.10/node0/fisco-bcos
# 若输出含 "gm" 字样则为国密版本,需用 gm/ 目录下的证书

预测 4:控制台连接成功但无法发送交易(账户未初始化)

# 在控制台内创建账户
[group0]: /> newAccount
# 然后用该账户发送交易

预测 5:多机构联盟链中,控制台只能连接本机构节点

这是正常的设计,不是 bug。每个机构的控制台只能用本机构的 SDK 证书连接本机构的节点。

✅️ 小结

维度 内容
🎯 根本原因 控制台 conf/ 目录下的证书与节点不属于同一机构,TLS 双向认证失败
最先执行 方案 A:从 节点目录/sdk/ 重新拷贝 ca.crtsdk.crtsdk.key 到控制台 conf/
🔑 最关键排查 openssl x509 -noout -subject 对比控制台证书和节点证书的机构名是否一致
🐳 Docker 特有坑 证书要挂载到容器内,且容器网络要能访问节点 IP(建议 --network host
⚠️ 多机构注意 联盟链多机构场景下,控制台证书必须来自要连接的那个机构的 sdk 目录
📋 操作优先顺序 检查证书来源 → 确认挂载路径 → 验证网络连通 → 核对 config.toml → openssl 手动测试握手

💪 把节点机器上 ~/fisco/nodes/10.1.0.10/sdk/ 目录下的三个证书文件正确挂载进容器,基本上就能解决!

🌹 结语 & 互动说明

希望以上分析与解决思路,能为你当前的问题提供一些有效线索或直接可用的操作路径

若你按文中步骤执行后仍未解决:

  • 不必焦虑或抱怨,这很常见——复杂问题往往由多重因素叠加引起;
  • 欢迎你将最新报错信息、关键代码片段、环境说明等补充到评论区;
  • 我会在力所能及的范围内,结合大家的反馈一起帮你继续定位 👀

💡 如果你有更优或更通用的解法:

  • 非常欢迎在评论区分享你的实践经验或改进方案;
  • 你的这份补充,可能正好帮到更多正在被类似问题困扰的同学;
  • 正所谓「赠人玫瑰,手有余香」,也算是为技术社区持续注入正向循环

🧧 文末福利:技术成长加速包 🧧

  文中部分问题来自本人项目实践,部分来自读者反馈与公开社区案例,也有少量经由全网社区与智能问答平台整理而来。

  若你尝试后仍没完全解决问题,还请多一点理解、少一点苛责——技术问题本就复杂多变,没有任何人能给出对所有场景都 100% 套用的方案。

  如果你已经找到更适合自己项目现场的做法,非常建议你沉淀成文档或教程,这不仅是对他人的帮助,更是对自己认知的再升级。

  如果你还在持续查 Bug、找方案,可以顺便逛逛我专门整理的 Bug 专栏👉《全栈 Bug 调优(实战版)》👈️

这里收录的都是在真实场景中踩过的坑,希望能帮你少走弯路,节省更多宝贵时间。

✍️ 如果这篇文章对你有一点点帮助:

  • 欢迎给 bug菌 来个一键三连:关注 + 点赞 + 收藏
  • 你的支持,是我持续输出高质量实战内容的最大动力。

同时也欢迎关注我的硬核公众号 「猿圈奇妙屋」

获取第一时间更新的技术干货、BAT 等互联网公司最新面试真题、4000G+ 技术 PDF 电子书、简历 / PPT 模板、技术文章 Markdown 模板等资料,通通免费领取
你能想到的绝大部分学习资料,我都尽量帮你准备齐全,剩下的只需要你愿意迈出那一步来拿。

🫵 Who am I?

我是 bug菌:

  • 热活跃于 CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等技术社区;
  • CSDN 博客之星 Top30、华为云多年度十佳博主/卓越贡献者、掘金多年度人气作者 Top40;
  • 掘金、InfoQ、51CTO 等平台签约及优质作者;
  • 全网粉丝累计 30w+

更多高质量技术内容及成长资料,可查看这个合集入口 👉 点击查看 👈️

硬核技术公众号 「猿圈奇妙屋」 期待你的加入,一起进阶、一起打怪升级。

- End -

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐