TLS handshake failed with error remote error: tls: bad certificate server=Orderer - hyperledger-fabric

I am trying to set up a hyperledger fabric on a VM manually. I have generated all the artifacts and configured the orderer.yaml and core.yaml. I have orderer running on port 127.0.0.1:7050. When I try to create channel using the peer cli channel create command I am getting a context deadline exceeded message on peer terminal.
./bin/peer channel create -o 127.0.0.1:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /home/fabric-release/mynetwork/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
Error: failed to create deliver client: orderer client failed to connect to 127.0.0.1:7050: failed to create new connection: context deadline exceeded
On the orderer terminal I am getting the following error:
2019-04-23 09:22:03.707 EDT [core.comm] ServerHandshake -> ERRO 01b TLS handshake failed with error remote error: tls: bad certificate server=Orderer remoteaddress=127.0.0.1:38618
2019-04-23 09:22:04.699 EDT [core.comm] ServerHandshake -> ERRO 01c TLS handshake failed with error remote error: tls: bad certificate server=Orderer remoteaddress=127.0.0.1:38620
2019-04-23 09:22:06.187 EDT [core.comm] ServerHandshake -> ERRO 01d TLS handshake failed with error remote error: tls: bad certificate server=Orderer remoteaddress=127.0.0.1:38622
I have gone through the configurations a few time, I am not sure if I am missing something. Following is my orderer.yaml
General:
LedgerType: file
ListenAddress: 127.0.0.1
ListenPort: 7050
TLS:
Enabled: true
PrivateKey: /home/fabric-release/mynetwork/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
Certificate: /home/fabric-release/mynetwork/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
RootCAs:
- /home/fabric-release/mynetwork/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
ClientAuthRequired: true
Keepalive:
ServerMinInterval: 60s
ServerInterval: 7200s
ServerTimeout: 20s
GenesisMethod: file
GenesisProfile: OneOrgOrdererGenesis
GenesisFile: channel-artifacts/genesis.block
LocalMSPDIR: /home/fabric-release/mynetwork/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp
LocalMSPID: OrdererMSP
Authentication:
TimeWindow: 15m
FileLedger:
Location: /var/hyperledger/production/orderer
Prefix: hyperledger-fabric-ordererledger

The issue is that the TLS server certificate used by the orderer does not have a SAN matching "127.0.0.1". You can add "localhost" and/or "127.0.0.1" to you TLS certificates by using a custom crypto-config.yaml when generating your artifacts with cryptogen:
# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:
# ---------------------------------------------------------------------------
# Orderer
# ---------------------------------------------------------------------------
- Name: Orderer
Domain: example.com
EnableNodeOUs: false
# ---------------------------------------------------------------------------
# "Specs" - See PeerOrgs below for complete description
# ---------------------------------------------------------------------------
Specs:
- Hostname: orderer
SANS:
- "localhost"
- "127.0.0.1"
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: org1
Domain: org1.example.com
EnableNodeOUs: true
Template:
Count: 2
SANS:
- "localhost"
- "127.0.0.1"
Users:
Count: 1
- Name: org2
Domain: org2.example.com
EnableNodeOUs: false
Template:
Count: 2
SANS:
- "localhost"
- "127.0.0.1"
Users:
Count: 1

I also faced the same problem and in my case, the issue was that I made some changes to the local directory files and apparently those changes were not successfully reflected while mounting those files back into the docker containers. What fixed the problem for me was
docker volume rm $(docker volume ls)
I restarted the network again and didn't see any more certificate errors. Worth a try.

when the problem of TLS handshake failed occurs between the orderer and orderer, it is most likely that there is an error in the configuration parameters when generating the TLS file.
if you are registered with TLS via fabric-ca, then you need to check whether the CSR properties in the TLS files of the two orderer are the same. You can use the following command "openssl x509 -in certificate.crt -text -noout".
The following you need to check whether the --cer.names, -m and other parameters of the orderer enroll are duplicate or incorrect.
In cases where the contents of the TLS file are consistent and the HostName specified, it is rare for the handshake to fail

Related

Debugging TLS handshake failure

I'm trying to access my peer through the fabric-network nodejs sdk.
However, I encounter an error during the gateway.connect in the sdk and the logs I find in the peer container is not helpful.
All I have, even with the grpc=debug logging mode is :
peer0.catie-test | 2020-09-21 13:27:07.731 UTC [core.comm] ServerHandshake -> ERRO 087 TLS handshake failed with error remote error: tls: handshake failure server=PeerServer remoteaddress=172.17.0.1:49918
peer0.catie-test | 2020-09-21 13:27:07.731 UTC [grpc] handleRawConn -> DEBU 088 grpc: Server.Serve failed to complete security handshake from "172.17.0.1:49918": remote error: tls: handshake failure
Any way to have more helpful logs ? I would like to know, for example, which key are used for the TLS handshake check.
Edit with more infos: Configuration files and TLS verification
My peer is configured with TLS with the env variables :
CORE_PEER_TLS_ENABLED=true
CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/crypto/peer/tls-msp/keystore/key.pem
CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/crypto/peer/tls-msp/signcerts/cert.pem
CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/crypto/peer/tls-msp/tlscacerts/tlsca.catie-test-cert.pem
I have the correct tlscacert of my peer on the client side, because the output from the peer and from client side are the same:
cat /etc/hyperledger/crypto/peer/tls-msp/tlscacerts/tlsca.catie-test-cert.pem # From the peer, output ZTd/o8LLw== at the end
cat /tmp/fabric-start-catie-test/building/artifacts/peer0.catie-test-crypto/tls-msp/tlscacerts/tlsca.catie-test-cert.pem # From the client, output ZTd/o8LLw== at the end
Path to the peer tlscacert is filled in the client side connection-profile.json :
"peers": {
"peer0.catie-test": {
"tlsCACerts": {
"path": "/tmp/fabric-start-catie-test/building/artifacts/peer0.catie-test-crypto/tls-msp/tlscacerts/tlsca.catie-test-cert.pem"
},
"grpcOptions":{
"ssl-target-name-override": "172.17.0.7",
"grpc.keepalive_time_ms": 10000
},
"url": "grpcs://172.17.0.4:7051",
"eventUrl": "grpcs://172.17.0.4:7053"
}
}
And I also checked that the tlsCAcert is the one that generated my peer cert :
openssl verify -CAfile $CORE_PEER_TLS_ROOTCERT_FILE $CORE_PEER_TLS_CERT_FILE # Output : /etc/hyperledger/crypto/peer/tls-msp/signcerts/cert.pem: OK
Edit 2 : Grpc option, peer name instead of IP and client logs
Also tried adding the grpcOptions to the peer section of the connection-profile.json (see the updated paragraph above) but it didn't change anything.
Also tried to add peer name to my /etc/hosts to reach my peer via its name instead of its IP. It makes a warning disappear but don't solve my problem and I prefer to work with IPs in my scripts.
Here are the logs of the nodejs sdk client in case it helps to diagnose the problem, but it only says that the Endorser must be connected and I think it is, because it reaches my peer as I have this TLS error in my peer's logs.
(node:59350) [DEP0123] DeprecationWarning: Setting the TLS ServerName to an IP address is not permitted by RFC 6066. This will be ignored in a future version.
2020-09-23T06:42:20.704Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer0.catie-test, url:grpcs://172.17.0.7:7051, connected:false, connectAttempted:true
2020-09-23T06:42:20.705Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.catie-test url:grpcs://172.17.0.7:7051 timeout:3000
2020-09-23T06:42:20.708Z - error: [NetworkConfig]: buildPeer - Unable to connect to the endorser peer0.catie-test due to Error: Failed to connect before the deadline on Endorser- name: peer0.catie-test, url:grpcs://172.17.0.7:7051, connected:false, connectAttempted:true
at checkState (/home/rqueraud/CATIE/Myrmica/myrmica-start/node_modules/#grpc/grpc-js/build/src/client.js:69:26)
at Timeout._onTimeout (/home/rqueraud/CATIE/Myrmica/myrmica-start/node_modules/#grpc/grpc-js/build/src/channel.js:292:17)
at listOnTimeout (internal/timers.js:549:17)
at processTimers (internal/timers.js:492:7) {
connectFailed: true
}
(node:59350) UnhandledPromiseRejectionWarning: Error: Endorser must be connected
at Channel.addEndorser (/home/rqueraud/CATIE/Myrmica/myrmica-start/node_modules/fabric-common/lib/Channel.js:259:10)
at buildChannel (/home/rqueraud/CATIE/Myrmica/myrmica-start/node_modules/fabric-network/lib/impl/ccp/networkconfig.js:50:21)
at Object.loadFromConfig (/home/rqueraud/CATIE/Myrmica/myrmica-start/node_modules/fabric-network/lib/impl/ccp/networkconfig.js:34:19)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async Gateway.connect (/home/rqueraud/CATIE/Myrmica/myrmica-start/node_modules/fabric-network/lib/gateway.js:279:13)
at async queryChaincode (/home/rqueraud/CATIE/Myrmica/myrmica-start/test/chaincode-sdk/index.js:41:5)
at async /home/rqueraud/CATIE/Myrmica/myrmica-start/test/chaincode-sdk/index.js:57:5
Edit 3 : Docker IPs ? Trying with EC2 instances.
As #Urko mentionned, my nodes are in fact docker container running docker-in-docker (dind) images. Inside these containers are some other containers running the hyperledger peers, cli, ... images.
I access them from the host which is also where I run the fabric sdk nodejs client. I cannot access them via their container name, I think it is only possible in a docker-compose configuration, isn't it ? I already tried (see Edit 2 above) to add their name to my /etc/hosts to reach them via a name instead of an IP but it didn't change anything.
However, as my network startup is scripted, I deployed it using docker-machine in AWS instead of the dind docker containers this time, so these are real instances reachable on the internet. But I still encounter the same errors, here is the log from the peer where you can see this is coming from a public IP :
2020-09-24 08:32:57.653 UTC [core.comm] ServerHandshake -> ERRO 0d7 TLS handshake failed with error remote error: tls: handshake failure server=PeerServer remoteaddress=31.36.26.4:35462
It seems that the connection with your Peer have been defined to be secured by the TLS protocol. So, you may configure you Peer configuration to know wich certificates are you using at the TLS.
As when you connect to any server using this protocol, the communication among the parties is encripted using the certificate of the server (in this case, the Peer will be the server). So, you need to configure your client to trust on the server by the Root CA that haven been used to issue the Peers TLS certificates.
The client is where you use the SDK, so, you should configure it to trust on the Peer TLS certificate. When you configure the connection to the Blockchain nodes (peers and orderers), you would define their direction, as well as their TLS certificate. This one is an example that you can find at the following link. There, you have to define the value of the tlsCACerts param:
orderers:
orderer.example.com:
url: grpcs://localhost:7050
grpcOptions:
ssl-target-name-override: orderer.example.com
grpc-max-send-message-length: 4194304
tlsCACerts:
path: test/fixtures/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tlscacerts/example.com-cert.pem
peers:
peer0.org1.example.com:
url: grpcs://localhost:7051
grpcOptions:
ssl-target-name-override: peer0.org1.example.com
grpc.keepalive_time_ms: 600000
tlsCACerts:
path: test/fixtures/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tlscacerts/org1.example.com-cert.pem
----- Edited ----
Also, you have to check the value of the ssl-target-name-override param. It should be the same to you nodes name, as you can see in the example file
----- Edited ----
Why are you using those IPs?! I understand that those IPs are internal from the Docker network, so you should not use them. Could you try using your containers names instead of the docker networks IPs?
----- Edited ----
Could you verify your ca-server configuration file and check that the tls is set to true?
You try a gRPC call in peer Server where peer server is secured with it's TLS system. So if you fail to provide the valid TLS certificate, server tls handshake will be failed and you will not get success to establish the connection.
Please check that your network config file is properly develop, also check that you are using the same TLS certificate that is used to run the peer server and your TLS certificate path is correct.

How to add a new Orderer Organization to existing Hyperledger Fabric network

I am trying to add a new Orderer Organization to RAFT based existing ordering service. I am using the first-network from fabric-samples as the base network. While generating crypto-material, I have modified to generate crypto-material for 1 more orderer organization. The crypto-config.yaml looks like:
OrdererOrgs:
# ---------------------------------------------------------------------------
# Orderer
# ---------------------------------------------------------------------------
- Name: Orderer
Domain: example.com
EnableNodeOUs: true
# ---------------------------------------------------------------------------
# "Specs" - See PeerOrgs below for complete description
# ---------------------------------------------------------------------------
Specs:
- Hostname: orderer
- Hostname: orderer2
- Hostname: orderer3
- Hostname: orderer4
- Hostname: orderer5
- Name: Orderer1
Domain: example1.com
EnableNodeOUs: true
Specs:
- Hostname: orderer
- Hostname: orderer2
- Hostname: orderer3
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
Template:
Count: 2
# Start: 5
# Hostname: {{.Prefix}}{{.Index}} # default
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users:
Count: 1
# ---------------------------------------------------------------------------
# Org2: See "Org1" for full specification
# ---------------------------------------------------------------------------
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
Also, the configtx.yaml for creating new Orderer organization's MSP in JSON format is given as:
Organizations:
- &Orderer1Org
# DefaultOrg defines the organization which is used in the sampleconfig
# of the fabric.git development environment
Name: Orderer1Org
# ID to load the MSP definition as
ID: Orderer1MSP
MSPDir: ../crypto-config/ordererOrganizations/example1.com/msp
# Policies defines the set of policies at this level of the config tree
# For organization policies, their canonical path is usually
# /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
Policies:
Readers:
Type: Signature
Rule: "OR('Orderer1MSP.member')"
Writers:
Type: Signature
Rule: "OR('Orderer1MSP.member')"
Admins:
Type: Signature
Rule: "OR('Orderer1MSP.admin')"
Then I boot up the the network using byfn.sh. Now I use the cli container to modify the system channel configuration in following steps:
First I add the organization's JSON to the Orderer group as follows and submit channel update:
jq -s '.[0] * {"channel_group":{"groups":{"Orderer":{"groups": {"Orderer1Org":.[1]}}}}}' config.json orderer1org.json > modified_config.json
Then I add organization's JSON to the Consortium group as follows and submit channel update:
jq -s '.[0] * {"channel_group":{"groups":{"Consortiums":{"groups":{"SampleConsortium":{"groups": {"Orderer1MSP":.[1]}}}}}}}' config1.json orderer1org.json > modified_config1.json
Then I add organization's orderer1 TLS certificates to Consenters section and submit channel update:
cert=`base64 ../crypto/ordererOrganizations/example1.com/orderers/orderer.example1.com/tls/server.crt | sed ':a;N;$!ba;s/\n//g'`
cat modified_config1.json | jq '.channel_group.groups.Orderer.values.ConsensusType.value.metadata.consenters += [{"client_tls_cert": "'$cert'", "host": "orderer.example1.com", "port": 7050, "server_tls_cert": "'$cert'"}] ' > modified_config2.json
Then I update the system channel configuration's Application group with new Orderer Org's JSON:
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Orderer1Org":.[1]}}}}}' config.json orderer1org.json > modified_config.json
Then I start one of the orderers in the new organization (orderer.example1.com) but the container is failing with following error:
2020-04-09 13:09:05.600 UTC [orderer.common.cluster.replication] fetchLastBlockSeq -> WARN 0e8 Received status:FORBIDDEN from orderer.example.com:7050: forbidden pulling the cha
nnel
2020-04-09 13:09:05.600 UTC [orderer.common.cluster.replication] func1 -> WARN 0e9 Received error of type 'forbidden pulling the channel' from {orderer.example.com:7050 [certs]}
The orderer.example.com logs throw this error:
2020-04-09 13:28:59.338 UTC [cauthdsl] deduplicate -> ERRO a3c Principal deserialization failure (the supplied identity is not valid: x509: certificate signed by unknown authorit
y) for identity 0
2020-04-09 13:28:59.338 UTC [cauthdsl] deduplicate -> ERRO a3d Principal deserialization failure (the supplied identity is not valid: x509: certificate signed by unknown authorit
y) for identity 0
2020-04-09 13:28:59.339 UTC [cauthdsl] deduplicate -> ERRO a3e Principal deserialization failure (the supplied identity is not valid: x509: certificate signed by unknown authorit
y) for identity 0
2020-04-09 13:28:59.340 UTC [cauthdsl] deduplicate -> ERRO a3f Principal deserialization failure (the supplied identity is not valid: x509: certificate signed by unknown authorit
y) for identity 0
2020-04-09 13:28:59.340 UTC [common.deliver] deliverBlocks -> WARN a40 [channel: byfn-sys-channel] Client authorization revoked for deliver request from 172.25.0.15:36196: implic
it policy evaluation failed - 0 sub-policies were satisfied, but this policy requires 1 of the 'Readers' sub-policies to be satisfied: permission denied
2020-04-09 13:28:59.341 UTC [comm.grpc.server] 1 -> INFO a41 streaming call completed grpc.service=orderer.AtomicBroadcast grpc.method=Deliver grpc.peer_address=172.25.0.15:36196
grpc.peer_subject="CN=orderer.example1.com,L=San Francisco,ST=California,C=US" grpc.code=OK grpc.call_duration=4.992078ms
I was able to extend the first-network by adding a new Orderer Organization as follows:
Start the first-network through the byfn.sh script in the fabric-samples repo in the etcdraft mode.
I generated crypto-material like described in the crypto-config.yaml in the question above.
Use the configtxgen tool to print the new orderer organization's MSP into JSON format.
Mount or docker cp this JSON file to the running cli container.
Set the environment inside the cli container corresponding to existing ordering node. Import the latest system-channel configuration. Decode it to JSON format.
Edit the system channel configuration block's Orderer section to add the new orderer organization's MSP as follows:
jq -s '.[0] * {"channel_group":{"groups":{"Orderer":{"groups": {"Orderer1Org":.[1]}}}}}' config.json orderer1org.json > config1.json
Edit the system channel configuration block's Consortiums section to add the new orderer organization's MSP as follows:
jq -s '.[0] * {"channel_group":{"groups":{"Consortiums":{"groups":{"SampleConsortium":{"groups": {"Orderer1MSP":.[1]}}}}}}}' config1.json orderer1org.json > config2.json
Edit the system channel configuration block's Consenters section to add the TLS credentials for the new orderer organization's orderer.example1.com node as follows:
cert=`base64 ../crypto/ordererOrganizations/example1.com/orderers/orderer.example1.com/tls/server.crt | sed ':a;N;$!ba;s/\n//g'`
cat config2.json | jq '.channel_group.groups.Orderer.values.ConsensusType.value.metadata.consenters += [{"client_tls_cert": "'$cert'", "host": "orderer.example1.com", "port": 7050, "server_tls_cert": "'$cert'"}] ' > modified_config.json
Encode the block, find delta, create channel update transaction, encode it as protobuf envelope and submit the channel update transaction.
Fetch the latest system channel configuration block.
Start one of the orderers (the one who was added to consenters list previously) using this latest fetched system channel configuration block as it's genesis.block file.
Perform docker exec into the cli container. Using the environment of an existing orderer node, fetch the latest system channel configuration.
Edit the system channel configuration block to add the new orderer's endpoint in the OrdererAddresses section as follows:
cat config.json | jq '.channel_group.values.OrdererAddresses.value.addresses += ["orderer.example1.com:7050"] ' > modified_config.json
Encode the block, find delta, create channel update transaction, encode it as protobuf envelope and get the block signed by Orderer1Org admin to satify the mod_policy for /Channel/OrdererAddresses resource which is set to Admins policy. This implicit meta policy expects the signature of MAJORITY Admins at that level of update. So, as the number of orderer organizations are 2 now, we need both the organization's admins to sign this system channel update transaction. Set the environment corresponding to Orderer1Org admin and run the following command:
peer channel signconfigtx -f ordorg_update_in_envelope.pb
Set the environment back to OrdererOrg admin and submit the channel update transaction. The peer channel update will automatically sign the transaction on behalf of OrdererOrg admin.
peer channel update -f ordorg_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
For updating any application channel, just replace the step 7 by updating the application channel configuration block's Application section to add the new orderer organization's MSP there.
Hope this helps!
I followed above sequence of steps to add new Orderer Organization into existing network, but channel (i.e updating config change to orderer channel) update throw error like below,
2020-09-29 00:53:49.794 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Error: got unexpected status: BAD_REQUEST -- error applying config update to existing channel 'e2e-orderer-syschan': error authorizing update: error validating DeltaSet: policy for [Value] /Channel/OrdererAddresses not satisfied: implicit policy evaluation failed - 0 sub-policies were satisfied, but this policy requires 1 of the 'Admins' sub-policies to be satisfied
I modified-json blocks by using below setup calls (tried mix/match combination of this below json change steps)
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"'${KL_NEW_ORDERER_NAME}'":.[1]}}}}}' config.json ${KL_NEW_ORDERER_NAME}.json > modified-config.json
jq -s '.[0] * {"channel_group":{"groups":{"Orderer":{"groups": {"'${KL_NEW_ORDERER_NAME}'":.[1]}}}}}' modified-config.json ${KL_NEW_ORDERER_NAME}.json > modified-config1.json
jq -s '.[0] * {"channel_group":{"groups":{"Consortiums":{"groups":{"'${KL_CONSORTIUM_NAME}'":{"groups": {"Orderermk01MSP":.[1]}}}}}}}' modified-config1.json ${KL_NEW_ORDERER_NAME}.json > modified-config2.json
LENGTH=$(jq '.channel_group.values.OrdererAddresses.value.addresses | length' modified-config2.json)
jq '.channel_group.values.OrdererAddresses.value.addresses['${LENGTH}'] |= "'${KL_NEW_ORDERER_URL}'"' modified-config2.json > modified-config3.json
cert=`base64 /hl-material/mk01-orderer/crypto-config/ordererOrganizations/${KL_DOMAIN}/orderers/orderer.mk01.${KL_DOMAIN}/tls/server.crt | sed ':a;N;$!ba;s/\n//g'`
cat modified-config3.json | jq '.channel_group.groups.Orderer.values.ConsensusType.value.metadata.consenters += [{"client_tls_cert": "'$cert'", "host": "raft0.mk01.'${KL_DOMAIN}'", "port": 32050, "server_tls_cert": "'$cert'"}] ' > modified-config4.json
My network setup based on HLF 2.2 LTS with 5 raft nodes under K8s cluster.
I have successful setup with multi channel, multiple peer organization on 2.2 LTS (know how to get this in dynamic way without bringdown any network). But now looking for scaling orderer organization into multiple cluster/orgs dynamically. Is any tip or update needed on above steps ? Thanks again
Mariya

Hyperledger fabric:TLS handshake failed with error remote error: tls: bad certificate server=Orderer remoteaddress

This seems like a common issue in HLF channel creation command
Here is my command to create the channel
peer channel create -o orderer1.workspace:7050 -c base-main-channel -f ./config/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/base.order/orderers/orderer1.base.order/msp/tlscacerts/tlsca.base.order-cert.pem
The error I am getting from the order node is
ERRO 02d TLS handshake failed with error remote error: tls: bad certificate server=Orderer remoteaddress=172.23.0.7:36982
I've tried the solution from this question TLS handshake failed with error remote error: tls: bad certificate server=Orderer
But it doesn't work for me
The only difference I am using raft ordering service instead of kafka
Here is my raft config
Raft:
<<: *ChannelDefaults
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
OrdererType: etcdraft
EtcdRaft:
Consenters:
- Host: orderer.base
Port: 7050
ClientTLSCert: crypto-config/ordererOrganizations/base.order/orderers/orderer1.base.order/tls/server.crt
ServerTLSCert: crypto-config/ordererOrganizations/base.order/orderers/orderer1.base.order/tls/server.crt
Addresses:
- orderer.base:7050
You are using the uncorrect folder path for --cafile in your peer channel create command.
Instead of
--cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/base.order/orderers/orderer1.base.order/msp/tlscacerts/tlsca.base.order-cert.pem
Use
--cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/base.order/tlsca/tlsca.base.order-cert.pem
Another solution is to remove the container's volumes
docker volume rm $(docker volume ls)
and restart the network

What is the use of TLS concept in the first network of fabric samples of hyperledger?

How can we implement TLS in first-network?i have tried by adding the below section in peers.What is the need to configure peers by Tls?
CORE_PEER_TLS_ENABLED=true
CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
I am working on multi organisation network setup using first network of fabric samples.one of the organisation say org1 has created a channel by passing tls certs of orderer ,the other organisation org2 has to fetch the channel created by org1 and join the peers into the channel.when i do fetch action using peer channel fetch by passing tls certs of orderer ,i got the error like
peer channel fetch config-o orderer.example.com:7050 -c channelone1 -f --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
connection error: desc = "transport: Error while dialing dial tcp 98.124.199.121:7050: connect: connection refused". Reconnecting...
and in orderer logs ,i got error as :
TLS handshake failed with error tls: client didn't provide a certificate {"server": "Orderer", "remote address": "172.24.0.4:49608"}
Created the channel using:
peer channel create -o orderer.example.com:7050 -c channelone1 -f ./channel-artifacts/channel-one.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
Output is: Received block is 0
By default the first-network will start with TLS enabled.
The four environment variables you refer to are included in the file base/peer-base.yaml the the peer-base file is "included" by use of the extends: and file: base/docker-compose-base.yaml

Create channel on peer fails

The official hyperledger fabric v1.0.0 gives a simple demo by using docker. Here is the link.
What i am doing is to avoid docker and directly run them on the machine. Thanks to the answer from my previous question, I have successfully launch 1 solo orderer and two peers, each from one org.
This is part of orderer's config orderer.yaml and i am sure the tls-related path is set correctly.
General:
# Ledger Type: The ledger type to provide to the orderer.
# Two non-production ledger types are provided for test purposes only:
# - ram: An in-memory ledger whose contents are lost on restart.
# - json: A simple file ledger that writes blocks to disk in JSON format.
# Only one production ledger type is provided:
# - file: A production file-based ledger.
LedgerType: file
# Listen address: The IP on which to bind to listen.
ListenAddress: 127.0.0.1
# Listen port: The port on which to bind to listen.
ListenPort: 7040
# TLS: TLS settings for the GRPC server.
TLS:
Enabled: true
PrivateKey: ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
Certificate: ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
RootCAs:
- ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
ClientAuthEnabled: false
ClientRootCAs:
# Log Level: The level at which to log. This accepts logging specifications
# per: fabric/docs/Setup/logging-control.md
LogLevel: debug
However, when I want to create the channel using command as follows:
export FABRIC_CFG_PATH=$PWD
export CHANNEL_NAME=my_channel
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp
export CORE_PEER_ADDRESS=127.0.0.1:7001
peer channel create -o 127.0.0.1:7040 -c $CHANNEL_NAME -f channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA >&log.txt
The log reports the error saying as follows:
Error: Error connecting due to rpc error: code = Internal desc = connection error: desc = "transport: authentication handshake failed: x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs"
I think it is related to a tls configuration problem. I am not very familiar about it. Can any one help me to solve this simple problem and give me a simple explanation?
The error is caused due to hostname verification failing at the TLS layer.
The TLS certificates don't have IP Subject Alternative Names (SANs) - they only have DNS-based SANs.
The easiest thing to do is to just add host entries into your /etc/hosts file (assuming you are running on Linux or macOS). Assuming that you are running everything on the same machine, then adding the following line to your /etc/hosts should resolve your issue:
127.0.0.1 localhost orderer peer0.org1.example.com peer0.org2.example.com
And then make sure to use the hostnames rather than IP addresses:
export FABRIC_CFG_PATH=$PWD
export CHANNEL_NAME=my_channel
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=crypto-config/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7001
peer channel create -o orderer:7040 -c $CHANNEL_NAME -f channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA >&log.txt

Resources