Hyperledger Fabric: TLS Enabled External Chaincode

Arun S M
5 min readApr 18, 2021

The document describes how to run the chaincode as a service and enable TLS connections for the messages exchanged. Enabling TLS will ensure that as long as chaincode server is accessible, any connection to it is secured. However, it is not sufficient to protect unwanted parties from reaching out the chaincode service. Towards the end of the document, I will walk you through how a chaincode service can authenticate if the right peer is sending the request. Thus completing a secure communication between an externally running chaincode instance and the peer node.

Externally run chaincode could enable deployment environments (such as orchestration engines e.g. Kubernetes) manage the node for you.

Steps involved in running an external chaincode server:

  1. Configure the peer service to handle external chaincode builders. i.e. Tell the peer node to not package and run the chaincode by itself.
  2. Inform the peer node about external chaincode’s availability. i.e. Tell the peer node where can it find the external chaincode service. This is given through the connection.json file. The file itself is packaged into external builder package as expected.
  3. Install the chaincode package that carries connection.json file. Installation step is to be done once per peer node where it is needed.
  4. Instantiate or approve/commit the chaincode for a particular channel. Note that the peer node which belongs to the channel should have chaincode installed in it.
  5. Run the chaincode server externally. Note that if you’re following “peer lifecycle” process for chaincode management then you would see a warning at the time of commit if chaincode server is not already started.

Couple of points to note:

1. Chaincode server can be started/stopped any number of times. If the peer node does not find a connection to the running instance of chaincode server it will establish one when either commit, invoke or query.

2. Multiple peers can connect to a single instance of a chaincoder server. This is because the peer node passes the context required in every request.

Note: At the time of writing this article, the PR is still in process. You may refer to the PR https://github.com/hyperledger/fabric-samples/pull/438 for end to end hands-on with asset-transfer-basic example.

How is trust achieved in real world?

Let’s understand the fundamental concepts, it will help you in understanding what parameters to pass and visualize the connection between a peer node and a chaincode service.

Person Verifying Documents

Above diagram depicts a flow of achieving trust in real world. A verifying person would request for a document that is signed by a signatory authority (such as Govt. entity, educational institute etc.). The trust is established by the fact that the verifying person knows who signatory authority is and forging the signature is highly difficult.

How is trust achieved in digital world?

For the sake of this article, I would skip explaining digital signature, digital certificate, ciphersuite, client-server TLS handshake protocol. You may read on them from the available resources on the internet or feel free request in the comment section. I am happy to explain those concepts in later articles.

Client Verifying a Server

Above diagram shows that client has a list of signatories. While establishing the connection with the server, a client machine would request server to send the server’s certificate. This is first step of TLS handshake protocol. Server will respond back to the client’s request with a certificate that it owns. If the certificate served by the server is issued by any of the signatory that the client already trusts then the client will proceed. As follow up steps, the connection establishment happens using the ciphersuite that is agreed upon by both server and the client.

How does peer trust the chaincode server?

You would first configure your chaincode to run and serve a certificate. chaincode shim/library would make use of this certificate respond back to peer node’s connection establishment request.

The Peer node should have been configured to trust the certificate issued by the chaincode server. This is made possible by adding root_cert parameter in the connection.json file. In this example, I will explain with a self signed certificate so the certificate and the root certificate will both remain same.

Peer Establishing Trust With Chaincode Server

You may run the below command to generate a self signed certificate and a key pair. Note that the chaincode’s hostname parameter shall be specified in the certificate. It is part of TLS certificate verification, the verification will fail otherwise.

openssl req -nodes -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -subj "/C=IN/ST=KA/L=Bangalore/O=example Inc/OU=Developer/CN=chaincode.domain/emailAddress=dev@chaincode.domain"

Use these values in your chaincode’s TLS properties. Also, copy the root certificate (in this case cert.pem itself) and put it in the root_cert parameter of the connection.json file for the chaincode. Make sure you have enabled tls_required to true.

Enabling TLS ends here. If you are successful till this step, then all the communication between peer nodes and the chaincode server will be encrypted. Continue if you would like chaincode service to authenticate that the expected peer node is sending the request.

What does client_auth_required mean and how does chaincode verify if it is expected peer node?

So far, the chaincode server is only serving request at a given port. It is equivalent you writing your web service and serving the certificate for TLS connection. However, in this case you would like to protect your chaincode from unwanted requests. You would like to block requests from the peer nodes which are not expected to be sending requests.

TLS Enabled andChaincode Authenticating The Peer Node

From the diagram you might have seen that this time the client_auth_required parameter is set to true. This is an indicator for your peer node to expect other two files client_key and client_cert. In every connection request to the chaincode service, the peer node will use the certificate you have specified in the connection.json file.

Chaincode shall also be configured to trust the peer node’s certificate. This is achieved through the ClientCACerts parameter. Supply the certificate using which the peer’s certificate can be trusted. You could have self-signed certificate per connection.json or per chaincode. But in order to make it easier to manage and take full benefit of certificate authority structure you could use the certificate issued by a certifying authority.

Note: Consider using a certificate generated by Fabric CA of the organization to host chaincode as a service and also for the peer node to authenticate itself against the chaincode server.

Hope this article was helpful, Happy Coding!

--

--

Arun S M

Engineer. Leader. Curious Soul. There’s so much space to grow this list!