【问题标题】:Hyperledger Fabric 2.3 connection issueHyperledger Fabric 2.3 连接问题
【发布时间】:2021-02-26 17:57:34
【问题描述】:

在查询分类帐时遇到问题。这是我们的网络的布局方式。 corp 网络内的 kubernetes 集群上有 2 个组织,网络内的 azure vm 上的 docker swarm 上也有一个。 azure vm 节点和 k8s 集群节点通过 nginx 服务器相互通信。现在,这种精心设置背后的原因是因为我们的供应链用例需要来自不同公司的合作伙伴加入我们的网络。因此,为了模拟公司网络之外的外部合作伙伴,我们使用 azure vm。由于我们计划将实现生产化,因此我们无法使用 Fabric 加密配置生成的证书并获得使用我们公司的中间证书和根证书颁发的新证书。现在这个网络设置上安装了链码,启用了背书策略,可以在所有 3 个节点上完美运行。我们使用的是 Fabric 2.3.0

现在我遇到的第一个问题是要在 connection.json 文件中使用的 TLS 证书。这是通过链接SO post here 中描述的证书来解决的。当前的问题是 nodejs 代码能够连接到组织,但无法执行任何读取或写入操作。在下面的 JS 代码中,如果我取消注释 channel.getPeer() 响应的控制台日志,它会正确打印整个对等对象。

这是我的 connection.json。 10.100.xx.xx ips都是k8s集群的pods,public.ip.address是nginx服务器的ips

{
    "name": "byfn",
    "version": "1.0.0",
    "client": {
        "organization": "ORG2MSP",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "10000"
                },
                "orderer": "10000"
            }
        }
    },
    "channels": {
        "supplychain": {
            "orderers": [
                "ord1.orderers.org1.com",
                "ord2.orderers.org1.com",
                "ord3.orderers.org1.com"
            ],
            "peers": {
                "peer1.peers.org1.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "ledgerQuery": true,
                    "eventSource": true
                },
                "peer1.peers.org3.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "ledgerQuery": true,
                    "eventSource": true
                },
                "peer1.peers.org2.com": {
                    "endorsingPeer": true,
                    "chaincodeQuery": true,
                    "ledgerQuery": true,
                    "eventSource": true
                }
            }
        }
    },
    "organizations": {
        "ORG2MSP": {
            "mspid": "ORG2MSP",
            "peers": [
                "peer1.peers.org2.com",
                "peer2.peers.org2.com"
            ]
        }
    },
    "orderers": {
        "ord1.orderers.org1.com": {
            "url": "grpcs://10.100.xxx.xxx:7050",
            "grpcOptions": {
                "ssl-target-name-override": "ord1.orderers.org1.com",
                "request-timeout": 12000
            },
            "tlsCACerts": {
                "path": "temp.pem"
            }
        },
        "ord2.orderers.org1.com": {
            "url": "grpcs://10.100.xxx.xxx:7050",
            "grpcOptions": {
                "ssl-target-name-override": "ord2.orderers.org1.com",
                "request-timeout": 12000
            },
            "tlsCACerts": {
                "path": "temp.pem"
            }
        },
        "ord3.orderers.org1.com": {
            "url": "grpcs://10.100.xxx.xxx:7050",
            "grpcOptions": {
                "ssl-target-name-override": "ord3.orderers.org1.com",
                "request-timeout": 12000
            },
            "tlsCACerts": {
                "path": "temp.pem"
            }
        }
    },
    "peers": {
        "peer1.peers.org1.com": {
            "url": "grpcs://10.100.xxx.xxx:7051",
            "grpcOptions": {
                "ssl-target-name-override": "peer1.peers.org1.com",
                "request-timeout": 12000,
                "grpc.keepalive_time_ms": 600000
            },
            "tlsCACerts": {
                "path": "temp.pem"
            }
        },
        "peer1.peers.org3.com": {
            "url": "grpcs://public.ip.address:7051",
            "grpcOptions": {
                "ssl-target-name-override": "peer1.peers.org3.com",
                "request-timeout": 12000,
                "grpc.keepalive_time_ms": 600000
            },
            "tlsCACerts": {
                "path": "temp.pem"
            }
        },
        "peer1.peers.org2.com": {
            "url": "grpcs://10.100.xxx.xxx:7051",
            "grpcOptions": {
                "ssl-target-name-override": "peer1.peers.org2.com",
                "request-timeout": 12000,
                "grpc.keepalive_time_ms": 600000
            },
            "tlsCACerts": {
                "path": "temp.pem"
            }
        }
    }
}

这是我的代码

'use strict';

const { Wallets, Gateway } = require('fabric-network');
const fs = require('fs');
const path = require('path');

const ccpPath = path.resolve(__dirname,'connection.json');
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);


async function main(){
    try {
        // const walletPath = path.join(process.cwd(), 'wallet');
        const wallet = await Wallets.newFileSystemWallet('wallet');
        // console.log(`Wallet path: ${walletPath}`);

        // Check to see if we've already enrolled the user.
        const userExists = await wallet.get('usernew');
        const tlsExists = await wallet.get('tlsid');
        if (!userExists) {
            console.log('An identity for the user "usernew" does not exist in the wallet');
            return;
        }
        if (!tlsExists) {
            console.log('An identity for the user "tls" does not exist in the wallet');
            return;
        }
        console.log("Here");
        // Create a new gateway for connecting to our peer node.
        const gateway = new Gateway();
        await gateway.connect(ccp, { wallet, identity: 'usernew', discovery: { enabled: false, asLocalhost: false }, clientTlsIdentity: 'tlsid' });

        console.log("Here1");
        // Get the network (channel) our contract is deployed to.
        const network = await gateway.getNetwork('supplychain');

        console.log("Here2");
        //Get the channel object to fetch out peers
        const channel = network.getChannel();

        console.log("Here3");
        //Get peers for endorsement
        //channel.getEndorsers();
        const org1Peer = channel.getPeer('peer1.peers.org1.com');
        //console.log(org1Peer);
        const org2Peer = channel.getPeer('peer1.peers.org2.com');
        //console.log(org2Peer);
        const org3Peer = channel.getPeer('peer1.peers.org3.com');
        //console.log(org3Peer);
        // All the above logs print correct information


        // Get the contract from the network.
        const contract = network.getContract('mycontract');

        const result = await contract.evaluateTransaction('queryAllObjects');
        
        console.log(`Transaction has been evaluated, result is: ${result.toString()}`);

    } catch (error) {
        console.error(`Failed to evaluate transaction: ${error}`);
    }
}

main()

这是加密文件夹树

C:.
├───peers.org1.com
│   └───users
│       ├───Admin@peers.org1.com
│       │   ├───msp
│       │   │   ├───admincerts
│       │   │   ├───cacerts
│       │   │   ├───intermediatecerts
│       │   │   ├───keystore
│       │   │   ├───signcerts
│       │   │   ├───tlscacerts
│       │   │   └───tlsintermediatecerts
│       │   └───tls
│       └───User1@peers.org1.com
│           ├───msp
│           │   ├───admincerts
│           │   ├───cacerts
│           │   ├───intermediatecerts
│           │   ├───keystore
│           │   ├───signcerts
│           │   ├───tlscacerts
│           │   └───tlsintermediatecerts
│           └───tls
├───peers.org2.com
│   └───users
│       ├───Admin@peers.org2.com
│       │   ├───msp
│       │   │   ├───admincerts
│       │   │   ├───cacerts
│       │   │   ├───intermediatecerts
│       │   │   ├───keystore
│       │   │   ├───signcerts
│       │   │   ├───tlscacerts
│       │   │   └───tlsintermediatecerts
│       │   └───tls
│       └───User1@peers.org2.com
│           ├───msp
│           │   ├───admincerts
│           │   ├───cacerts
│           │   ├───intermediatecerts
│           │   ├───keystore
│           │   ├───signcerts
│           │   ├───tlscacerts
│           │   └───tlsintermediatecerts
│           └───tls
└───peers.org3.com
    └───users
        ├───Admin@peers.org3.com
        │   ├───msp
        │   │   ├───admincerts
        │   │   ├───cacerts
        │   │   ├───intermediatecerts
        │   │   ├───keystore
        │   │   ├───signcerts
        │   │   ├───tlscacerts
        │   │   └───tlsintermediatecerts
        │   └───tls
        └───User1@peers.org3.com
            ├───msp
            │   ├───admincerts
            │   ├───cacerts
            │   ├───intermediatecerts
            │   ├───keystore
            │   ├───signcerts
            │   ├───tlscacerts
            │   └───tlsintermediatecerts
            └───tls

上面的连接文件中使用的 temp.pem 是通过附加如下所示的 ica.pem 和 ca.pem 来准备的。这是证书如何查找 Org2。其他 2 个组织看起来相似。 msp/tlscacerts/ca.pem

Issuer: C=XX, ST=XXXX, L=XXXX, O=MyCompany, OU=Cybersecurity, CN=MyCompany Root Certificate Authority 2018
Validity
    Not Before: Jul 23 17:07:45 2018 GMT
    Not After : Jul 23 17:17:44 2043 GMT
Subject: C=XX, ST=XXXX, L=XXXX, O=MyCompany, OU=Cybersecurity, CN=MyCompany Root Certificate Authority

msp/tlsintermediatecerts/ica.pem

Issuer: C=XX, ST=XXXX, L=XXXX, O=MyCompany, OU=Cybersecurity, CN=MyCompany Root Certificate Authority 2018
Validity
    Not Before: Nov 14 21:26:35 2018 GMT
    Not After : Nov 14 21:36:35 2025 GMT
Subject: C=XX, ST=XXXX, L=XXXX, O=MyCompany, CN=MyCompany Issuing CA 101

tls/server.crt

Issuer: C=XX, ST=XXXX, L=XXXX, O=MyCompany, CN=MyCompany Issuing CA 101
Validity
    Not Before: Jan 18 20:30:30 2021 GMT
    Not After : Jan 18 20:30:30 2023 GMT
Subject: C=XX, ST=XXXX, L=XXXX, O=MyCompany Inc., OU=org2client, CN=*.peers.org2.com
.
.
.
X509v3 Subject Alternative Name:
    DNS:*.peers.org2.com

Org2 NodeJs 日志

2021-02-25T10:21:33.736Z - error: [Endorser]: sendProposal[peer1.peers.org2.com] - Received error response from: grpcs://10.100.xxx.xxx:7051 error: Error: 2 UNKNOWN: error validating proposal: access denied: channel [supplychain] creator org [ORG2MSP]
2021-02-25T10:21:33.738Z - error: [Endorser]: sendProposal[peer1.peers.org2.com] - rejecting with: Error: 2 UNKNOWN: error validating proposal: access denied: channel [supplychain] creator org [ORG2MSP]
2021-02-25T10:21:33.738Z - error: [SingleQueryHandler]: evaluate: message=Query failed. Errors: ["Error: 2 UNKNOWN: error validating proposal: access denied: channel [supplychain] creator org [ORG2MSP]"], stack=FabricError: Query failed. Errors: ["Error: 2 UNKNOWN: error validating proposal: access denied: channel [supplychain] creator org [ORG2MSP]"]
    at SingleQueryHandler.evaluate (/fabric23/node_modules/fabric-network/lib/impl/query/singlequeryhandler.js:47:23)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async Transaction.evaluate (/fabric23/node_modules/fabric-network/lib/transaction.js:276:25)
    at async main (/fabric23/test.js:67:25), name=FabricError
Failed to evaluate transaction: FabricError: Query failed. Errors: ["Error: 2 UNKNOWN: error validating proposal: access denied: channel [supplychain] creator org [ORG2MSP]"]

Org2 对等日志

2021-02-25 10:21:33.732 UTC [endorser] Validate -> WARN 08f access denied: creator's signature over the proposal is not valid: The signature is invalid channel=supplychain txID=01bde838 mspID=ORG2MSP
2021-02-25 10:21:33.732 UTC [comm.grpc.server] 1 -> INFO 090 unary call completed grpc.service=protos.Endorser grpc.method=ProcessProposal grpc.peer_address=172.23.238.200:40928 grpc.peer_subject="CN=*.peers.org3.com,OU=org3client,O=MyCompany Inc.,L=XXXX,ST=XXXX,C=XX" error="error validating proposal: access denied: channel [supplychain] creator org [ORG2MSP]" grpc.code=Unknown grpc.call_duration=12.335491ms

Org3 对等日志

2021-02-26 13:42:26.081 UTC [gossip.channel] publishStateInfo -> DEBU 6155d8 Empty membership, no one to publish state info to
2021-02-26 13:42:26.493 UTC [core.comm] ServerHandshake -> DEBU 6155d9 Server TLS handshake completed in 49.605106ms server=PeerServer remoteaddress=public.ip.address:291542021-02-26 13:42:26.597 UTC [grpc] InfoDepth -> DEBU 6155da [transport]transport: loopyWriter.run returning. connection error: desc = "transport is closing"
2021-02-26 13:42:26.927 UTC [gossip.channel] publishStateInfo -> DEBU 6155db Empty membership, no one to publish state info to

我还尝试在 azure vm 上的 docker swarm 上部署相同的代码。但是当我使用SO post here中给出的错误证书时,它给出了同样的错误。

【问题讨论】:

    标签: node.js hyperledger-fabric hyperledger ibm-blockchain


    【解决方案1】:

    您可以检查的一些要点:

    • org3 的对等服务器 TLS 证书应该有一个替代名称,如“*.ip.adress”?
    • 频道包含所有 3 个组织,对吗?从 org2 的日志中,我看到“创建者对提案的签名无效”
    • 检查用户身份“usernew”PKI(不是 TLS)以确保颁发证书的 CA 是通道上的 CA MSP 之一。如果您使用中间 CA,那么这些 CA 证书也应该在通道上。

    最好的问候, 茨维坦

    【讨论】:

    • 嗨茨维坦。我检查了你上面提到的几点
    • 1.在上面的帖子正文中,您可以看到我已经为 org2 提供了 TLS 证书。该证书看起来类似于 org3 的证书。在证书的 SAN 部分,我们提供了该对等组织的 DNS。当您说“*.ip.adress”时,您是指天蓝色虚拟机的IP地址,还是虚拟机中的对等容器或nginx代理服务器的IP? 2. 通道包含所有 3 个组织,它们在 CLI 执行的事务中正常工作 3. 中间 CA 证书是通道的一部分。
    • 我使用这些证书从 org2 cli 执行命令 --tls $CORE_PEER_TLS_ENABLED --cafile /var/hyperledger/msp/tlsintermediatecerts/ica.pem --certfile /var/hyperledger/tls/server.crt --clientauth --keyfile /var/hyperledger/tls/server.key -C supplychain -n mycontract --peerAddresses $CORE_PEER_ADDRESS --peerAddresses peer1.peers.org1.com:7051 --peerAddresses peer1.peers.org3.com:7051 --tlsRootCertFiles /var/hyperledger/tls/ca.crt --tlsRootCertFiles /var/hyperledger/tls/ca.crt --tlsRootCertFiles /var/hyperledger/tls/ca.crt 与 org3 cli 相同,只有 --peerAddresses 列表更改
    • 那么当您代表 3 个组织中的每一个运行 CLI 命令时,它工作正常吗?其他几件事 1) 您可能对每个组织都有单独的连接配置文件。只需配置客户组织的对等方即可。让服务发现处理其余的事情。当然,您必须正确设置您的 TLS 证书以避免 ssl 覆盖 2)我看到您为 3 个组织的对等方拥有相同的 tlsCACerts 文件。这是否意味着您使用相同的 CA 来颁发 TLS 证书(实际上生活中那些将是 3 个不同的 CA)。此文件是否包含所有 TLS CA 服务器证书?我在 CLI 中看到您使用的是不同的。
    • 是的,来自所有 3 个组织的 CLI 命令都可以在链码上使用或不使用背书策略时完美运行。 1. 我对所有组织都有单独的连接配置文件,但还没有部署其余的 API。我想至少让 org2 中的一个来工作,以便我可以将学到的知识和更改应用于其余部分。我尝试在 VM 节点中部署一个 api,但它无法连接到任何对等点。甚至不是该组织本身的对等方。关于服务发现,我不相信我们已经部署/启用了假设它是一个需要部署的单独组件。
    猜你喜欢
    • 1970-01-01
    • 2018-02-28
    • 2021-07-14
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多