hlf-time-oracle 是一个为区块链 Hyperledger Fabric 提供的链码,用于向其他链码提供精确时间。hlf-time-oracle 基于 ntp 包 和 nts 包。从而解决了区块链客户端可能通过 交易时间操纵(CVE-2024-45244)带来的安全问题。该链码提供了 GetTimeNtp() 和 GetTimeNts() 函数。调用这些函数会触发对 NTP(网络时间协议)和 NTS(网络时间安全)服务器的请求。从这些服务器获取的时间可用于验证客户端定义的事务时间的正确性。区块链链码开发者可以使用 hlf-time-oracle,而无需自行编写与 NTP 和 NTS 服务器交互的代码。hlf-time-oracle 在运行过程中不会向区块链保存任何数据。
hlf-time-oracle 适用于 Hyperledger Fabric 2.4.x 版本,位于 hlf_2.4 文件夹;适用于 Hyperledger Fabric 2.5.x 版本,位于 hlf_2.5 文件夹。
如果你不希望依赖单个时间服务器,可以使用多个时间预言机。
预言机
NTS 是 NTP 的增强版(参见 RFC 8915)。它包含两种连接:用于 TLS 的 TCP 和用于 NTP 的 UDP。NTP 连接的端口由 NTS 服务器决定,可能与标准的 123/UDP 不同。配置防火墙时需要注意这一点。
为了正确建立 TLS 连接,需要客户端(即运行 hlf-time-oracle 的系统)的系统时间相对准确(在 NTS 服务器证书有效期内)。否则 连接将无法建立。
建议使用 GetTimeNts() 而不是 GetTimeNtp()。与 NTP 不同,使用 NTS 能够抵抗中间人攻击。如果开放数据部分被未授权篡改,会记录以下错误:authentication failed on client。如果 NTS 服务器证书被尝试伪造,会记录以下错误:key exchange failure: tls: failed to verify certificate: x509: certificate signed by unknown authority。
模型
hlf-time-oracle 运行在 Docker 中(Docker 网络 172.18.0.0/24)。在 Docker 宿主机(Host_1)上运行着 netsed(端口 4000/UDP)和 mitmproxy(端口 8080/TCP)。来自 hlf-time-oracle 的流量通过 iptables 定向到这两个工具。第二台主机(Host_2)通过调用 Oracle 的 GetTimeNtp() 和 GetTimeNts() 函数(通过 peer chaincode query 调用)来访问 Oracle。调用这些函数会使得 Oracle 分别向 NTP 服务器和 NTS 服务器发起请求。
将流量重定向到 netsed 的 iptables 规则:
iptables -t nat -A PREROUTING -s 172.18.0.0/24 -d 213.234.203.30/32 -p udp -m udp --dport 123 -m udp -j REDIRECT --to-ports 4000
使用规则运行 netsed。
在 netsed 中创建规则,将 %ea%33 替换为 %eF%33
攻击成功的结果。
将流量重定向到 netsed 的 iptables 规则(NTS 服务器 ntp1.glypnod.com 的 IP 地址为 104.131.155.175):
iptables -t nat -A PREROUTING -s 172.18.0.0/24 -d 104.131.155.175/32 -p udp -m udp --dport 8123 -m udp -j REDIRECT --to-ports 4000
使用规则运行 netsed。
在 netsed 中创建规则,将 %ea%33 替换为 %eF%33
攻击失败的结果。
查看 Docker 日志:
docker 日志
将流量重定向到 mitmproxy 的 iptables 规则(NTS 服务器 ntp1.glypnod.com 的 IP 地址为 104.131.155.175):
iptables -t nat -A PREROUTING -p tcp -s 172.18.0.0/24 --dport 4460 -m tcp -d 104.131.155.175 -j REDIRECT --to 8080
查看 mitmproxy 日志:
mitmproxy 日志
查看 Docker 日志:
docker 日志
MIT