Hyperledger Fabric v2.3 Example Network Setup — Identities(Part I)

Anıl HELVACI
stm-blockchain
Published in
17 min readMar 9, 2021

Introduction

This is the part one of a walk through which consists of building a sample Hyperledger Fabric network without a system channel then creating an application channel with osnadmin , deploying a chaincode and invoking its methods.

This part will be focused on distributing identities to the components in the network. We will achieve this using Fabric CA which is the Hyperledger’s own tool for creating x509 certificates and private keys. There is also a github repo that I have created which contains the complete code and instructions to get the network up and running.

Identities In a Fabric Network

Since Hyperledger Fabric is a permissioned network, participants in the network need a way to prove their identity to the rest of the network in order to operate on the network. This is achieved by Public Key Infrastructure’s verifiable identities through a chain of trust. There are network components whose job is to generate these public and private key-pairs. These components are called “Certificate Authorities” or “CA”. Every organization in the network needs to have at least one CA.

MSP (Membership Service Provider)

Since a private key, that is in a public and private key-pair, can never go out of band there is a mechanism needed to verify the identity of the network member. If the identity is verified this mechanism now needs to decide which privileges this member has. This is how an MSP turns an identity into a role. So the duties of an MSP;

  • Verify the identities of network members
  • Determine the privileges assigned to a certain member in the network

These duties are achieved by fabric binaries and you don’t have to worry about them as a network admin. What we need to do here is to create some certain type of folder structures and fill them with the crypto materials that are generated by a CA in order for fabric binaries to consume them and execute the above duties of an MSP. There are two types of folder types;

  • Local MSPs
  • Channel MSPs

Local MSPs

This type of MSP folder holds individual identity of the network member. Every member in the network must have this in its local file system. Here is how it looks;

Structure of a local MSP
  • cacerts: This folder holds the Root(issuer = subject) certificate of the CA which the network member belongs to.
  • signcerts: In this folder you will find the x509 certificate of the corresponding member which serves as the public key in identity verification operation.
  • keystore: This folder holds the corresponding private key of the public key found in signcerts/ folder. The content of this folder should never go out of band.
  • config.yaml: This file is used to enable the NodeOUs. The concept of NodeOU will be explained later in this article.

Channel MSPs

This MSP type is required in order to determine which members will act on behalf of which organizations in an application channel. To be more specific, we need to specify the root certificates of a certain organization’s CAs in channel configuration so that fabric can then decide if a network member has the right to transact on that application channel by checking whether if that member’s organization is specified in channel configuration or not. We do this by specifying every organization and it’s corresponding msp/ folder in the configtx.yaml file. The contents of this msp/ folder is as follows;

Organization MSP folder structure
  • cacerts: This folder is the same as the one explained in the Local MSPs section.
  • config.yaml: This file is used to enable the NodeOUs. The concept of NodeOU will be explained later in this article.
  • tlscacerts: This folder holds the root certificate of the TLS CA. The need of a separate TLS CA will be explained later in this article.

Since there is nothing but public keys(certificates) and a small configuration file ,that does not contain any confidential data, this MSP folder can go out of band and actually will need go out of band in a real life scenario where organizations run on different physical machines.

In Hyperledger Fabric terminology you may see terms like “cacerts” , “ca cert”, “tlscacerts”, etc. When you see this kind of usage, what you need to understand is the root certificate of a certain CA.

Organizational Units and NodeOUs

Dividing an organization into departments might come in handy when an organization has too many responsibilities. This is where Organizational Units come into play. Think of separating an organization into small units according to their responsibilities in that organization. In fabric you use term affiliations when specifying these units. If you are using Fabric CA to generate your crypto material you would set organizational units using --id.affiliation flag. When you need to specify some complex policies in channel configuration or in your chaincode these OUs will be useful.

A NodeOU is a special kind of OU (Organizational Unit) that is used to specify the role of a certain identity has in the network. Here are available NodeOUs;

  • peer
  • client
  • admin
  • orderer

In order to make use of these roles you need to have a config.yaml file in the root of your MSP folder. You can check out the MSP section in the article to have a visual example of the folder structure. The config.yaml file looks like this;

Since this is a yaml file you need to pay attention to syntax. One other key part of this file is that in line 2 Enable: true is set to true. This enables the “identity classification” feature which tells fabric to accept these roles and do not look for any admincerts/ folder in the MSP folder.

Again, if you are using Fabric CA as your crypto material generator you would use --id.type flag to specify your identity’s role in the network. Here is sample x509 public key of a peer;

As it can be observed from the blue circles this certificate belong to a peer that has no affiliations.

Fabric CA

In order to achieve verification of identities we first need crypto material. Although there is no restriction of using Fabric CA, it is a suitable choice considering it is managed Hyperledger and has some features that provides convenience with fabric MSP structure. Fabric CA provides two cli binaries which are fabric-ca-client and fabric-ca-server .

We can think of fabric-ca-server as the actual CA that is up and listens for request from the network. The server also holds the records of the identities it has registered. There must be a one-to-one relationship between the fabric-ca-server and the CA.

On the other hand one fabric-ca-server can be used to interact with multiple fabric-ca-server s. This is achieved by specifying destination server and the msp folder of the client who will be interacting with the server via flags.

The general flow of Fabric CA usage is as follows;

  1. Start the server with a bootstrapped identity(specify a username and a password) to be able to register other identities using this bootstrapped identity.
  2. Enroll at the server using username and password you bootstrapped via fabric-ca-client .
  3. Register new users to the server using the msp/ folder that is generated automatically when the enrollment of the bootstrapped identity is successful. In this register phase do not forget to specify username and password for the new identity as they will be necessary for the enrollment phase.
  4. The newly registered users then should enroll themselves using the username and password specified in the register phase.

As you can see the private key of the users never traveled over the internet, instead it is generated locally during the enrollment phase. The authentication to the server is achieved via username and password specified during the register phase.

Example Network

Sample Network Topology

We have gone over the basics of identity concept in Hyperledger Fabric so far and now we are ready to dive into action. Above is the topology of our network. By the time we are done you will have this network on your local machine. The breakdown of the network components:

  • Ordering Service: This component contains the node Orderer1 , an Organization CA Server and a TLS CA Server (as the official docs recommends).
  • Org1: Just like the Ordering Service, Org1 has it’s own necessary CA servers but since Org1 is a peer organization it also contains a peer node called Peer1 to join channels and endorse transactions.
  • Org2: This organization serves as a peer organization to our network just like Org1.
  • testchannel: A sample application channel which is created by the Orderer1 using osnadmin without the existence of a system-channel.

TLS CA & Organization CA

In order for a secure communication to be established TLS must be enabled in the whole network. TLS is a security protocol that makes use of symmetric and asymmetric cryptography so packets that are being transferred are encrypted and decrypted correctly. If you are not familiar with the basics of TLS porotocol here is a good explanation.

In a production scenario of course we will want our communications over the web to be encrypted. To ensure these security measures are met, every node in the network must enroll at a CA with --enrollment.profile tls (assuming Fabric CA is being used). Since we are planning for a production network we assume we will be dealing with a great number of clients, peers, admins etc. So to divide this load, it makes sense to have a separate CA server that only deals with the TLS related business and another CA server to deal with identity related business. In order to that the CA server responsible from giving out identities must be enrolled at the TLS server too. We will see how this is done in the following steps.

Walkthrough

As I stated at the beginning of the article I will be explaining the code in this repo. Since this is a multipart article and in this part we have talked about identities, I will leave the channel creation and chaincode related stuff to the other part. Here we will focus on setting the identities correctly.

This walkthrough assumes you have a basic understaning about docker, docker-compose, bash.

In this topology we have three organizations one of them is an Ordering Service and two of them are identical peer organizations. So we will only cover the ordering service and Org1 since Org2 and Org1 are identical.

We have three shell scripts to start the organizations. By start I mean get the CA servers up and running, register and enroll identities. These three shell scripts are;

  • startOrderingService.sh
  • startOrg1.sh
  • startOrg2.sh

We will focus on startOrderingService.sh and startOrg1.sh since Org1 and Org2 are identical.

For a full list of Prerequisites please refer here

Folder Structure

Since all containers run on the same physical machine, an efficient folder structure is required in terms of management of the network artifacts. I will share details of my folder structure but you can use any structure you want.

For every organization in the network there is folder named after that organization’s name (orderingservice/, Org1/, etc.). This folder is the root folder that contains everything about that organization(peers, MSP folders, orderers, ledger data, etc.). Inside the root folder there are 3 folders which are guaranteed to exist;

  • server/ : Contains data(registered identities, crypto material) of the CA servers this organization has.
  • msp/ : This is the MSP folder of this organization and will be necessary when configuring an application channel.
  • client/ : Contains the crypto materials which are generated during the enrollment process.

In addition to these folders there will be a folder for each created node. For example, if you create an orderer node named “orderer1” you will see a folder named orderer1/ as well. Here is the sample folder structure of the “orderingservice” in our sample network.

Sample Folder Structure

Ordering Service

As the name suggests we will be observing the startOrderingService.sh here.

Step 1

We first need to start our TLS CA Server since our Organization CA will register here as well. The first line of the script;

docker-compose -p fabric-2.3 up -d tlsca.orderingservice.com
  • docker-compose up : Create and start a container
  • -p : The name of the project
  • -d : The service name which is configured inside docker-compose.yaml file.

This is our tlsca.orderingservice.com configuration;

  • FABRIC_CA_SERVER_HOME: This is an environemt variable to set the folder location of the materials that will be generated once the server is up.
  • FABRIC_CA_SERVER_TLS_ENABLED: Enables TLS handshake
  • FABRIC_CA_SERVER_CA_NAME: Name of this CA
  • FABRIC_CA_SERVER_CSR_CN: Sets the “CN” field that represents this CA in the x509 certificates.
  • FABRIC_CA_SERVER_CSR_HOSTS: Sets valid hosts for the certificates which this CA will issue.
  • FABRIC_CA_SERVER_DEBUG: Enables debug mode.
  • FABRIC_CA_SERVER_OPERATIONS_LISTENADDRESS: Operations is a separate server which can be useful for the purposes of debeg, etc. This environment variable sets it’s listen address.

Step 2

Now that our TLS CA Server is up and running it is time to interract with it. In order to do that we must first do some configuration

First two lines create the basic msp/ and client/ folders which are explained in the Folder Structure section. Line three copies the ca-cert.pem file to the root of the client/ folder with name tls-ca-cert.pem .

ca-cert.pem is the root certificate of the TLS CA and will used in the TLS handshake porcess when we are trying to interract with the members of this organization. Since this server is the TLS CA of this organization its root certificate is the root TLS certificate of this organization. That is why we need to specify the location of this certificate during our enroll & register phase.

export FABRIC_CA_CLIENT_HOME=$PWD/orderingservice/client                       export FABRIC_CA_CLIENT_TLS_CERTFILES=$PWD/orderingservice/cliet/tls-ca-cert.pem
  • FABRIC_CA_CLIENT_HOME: This is the path which fabric-ca-client will use as its base folder location.
  • FABRIC_CA_CLIENT_TLS_CERTFILES: fabric-ca-client uses the certificate specified in this environment variable as the root TLS certificate in the TLS handshake process.

Step 3

We have made the required configurations for fabric-ca-client . Now it is time to register and enroll our identities.

  • fabric-ca-client enroll : Generates the identity crypto material after verifying this member using username and password that are registered to the server.
  • fabric-ca-client register: Registers a new member with specifications from the flags but first it needs to verify that this user has the authority to register new members. The verification is achieved using the MSP folder specified with the -M flag.

When using fabric-ca-client register -M flag points the identity of the user who is making register request but if you sue fabric-ca-client enroll -M flag points the location where new MSP folder will be created. Let’s take a closer look at the first enroll command;

The purpose of this command is to generate the crypto material that represents “tls-ca-admin” of ordering service. Important thing here is that “tls-ca-admin:tls-ca-adminpw” credentials are not registered but “bootstrapped” when the server started. This bootstrapped identitiy is a “Registrar” meaning has the prrivilledge of registering other users.

  • -u : Points the address of the CA server to send the request
  • -M : Since this is an “enroll” command this flag points the location of MSP folder to be generated.
  • --csr.hosts : This is a list of hosts that the generated certificates will be valid on.
  • --enrollment.profile tls : This flag lets the server know the public-private key generated as result of this enrollment will be used in TLS handshake process.

Once we have an identity who has the authorization of registering new identities, it is time to register new members using the credentials of this identity. To do that we use fabric-ca-client register command and here are flags and their purposes;

  • -d : Means debug mode so logs are printed in console.
  • --id.name and --id.secret : These are the username and password of the new member respectively. We will need this when we enroll this user.
  • --id.type : This flag sets the NodeOU type of the new user.
  • -u : Points the address of the CA server.
  • -M : As I have mentioned before, this flag points credentials of the user who has authorized to register new member.

One other important thing here to note that, the first command registers a user “org-ca-admin:org-ca-adminpw”. This user is the representation of our Organization CA which deals with the identities within our organization. We will use this user’s public-private key from the TLS CA when we are starting our Organization CA.

After the registration process is done, now we can enroll and claim the Local MSPs for our newly registered users.

The enrollments above are the same as the one I have explained above. With these enrollments we have completed starting phase of TLS CA Server. Now let’s move forward to the Organization CA Server.

Step 4

Here is the part of code that starts Organization CA

Do you remember me mentioning something about registering Organization CA to the TLS CA Server? Between the lines 1–4 we are setting that up. We first create folder named “tls/” under the Organization CA Server’s home folder. Then we rename the private key of our “org-ca-admin” to “key.pem”. Later we copy the public-private key pair of org-ca-admin to the “tls/” we created. We will need the contents of this “tls/” folder as we start the Organization CA Server.

At line 8 we run;

docker-compose -p fabric-2.3 up -d orgca.orderingservice.com

This command is the same as the one we use for starting tls ca server but this time we start the orgca.orderingservice.com

This docker-compose service is almost identical with the one we used for the TLS CA Server but has a few differences;

  • FABRIC_CA_SERVER_TLS_CERTFILE: This environment variable points to location of the public key we got for org-ca-admin which we registered and enrolled with our TLS CA Server.
  • FABRIC_CA_SERVER_TLS_KEYFILE: Similar to the above environment variable this points to the private key of org-ca-admin user.

The public-private key pair above will be used during TLS handshake process of the Organization CA Server.

The register & enroll process is pretty staright forward. We first enroll the identity that is bootstarpped during startup of the server, then using the credentials of that bootstrapped identity we register new users and enroll them.

Step 5

So far we have started our CA servers and created the identity elements for the members of Ordering Service. Now we can finally create our orderer node.

In order for our “orderer1” node start properly, we first need to make some preparations in terms of files and folder structure.

Between the lines 1–5, we are creating this folder structure for the ;

Between the lines 7–20, we are creating this folder structure;

Finally start the orderer node;

docker-compose -p fabric-2.3 up -d orderer1.orderingservice.com

orderer1.orderingservice.com;

  • ORDERER_GENERAL_LISTENADDRESS: Hostname that the ordering node listens on.
  • ORDERER_GENERAL_LOCALMSPID: MSP ID of the ordering organization as specified in the channel configuration.
  • ORDERER_GENERAL_LOCALMSPDIR: Path to the ordering node MSP folder.
  • ORDERER_GENERAL_TLS_ENABLED: Server-side TLS should be enabled in all production networks.
  • ORDERER_GENERAL_TLS_CERTIFICATE: Ordering node signed certificate (public key) from the TLS CA.
  • ORDERER_GENERAL_TLS_PRIVATEKEY: Ordering node private key from TLS CA.
  • ORDERER_GENERAL_BOOTSTRAPMETHOD: This allows the orderer to start without needing a system channel configuration block.
  • ORDERER_DEBUG_BROADCASTTRACEDIR: BroadcastTraceDir when set will cause each request to the Broadcast service for this orderer to be written to a file in this directory
  • ORDERER_FILELEDGER_LOCATION: Location on the file system to the ledgers of the channels this orderer will be servicing.
  • ORDERER_CHANNELPARTICIPATION_ENABLED: Set to true. This allows the orderer to be joined to an application channel without joining a system channel first.
  • ORDERER_ADMIN_LISTENADDRESS: The orderer admin server address (host and port) that can be used by the osnadmin command to configure channels on the ordering service. This value should be a uniquehost:port combination to avoid conflicts.
  • ORDERER_ADMIN_TLS_ENABLED: Technically this can be set to false, but this is not recommended. In general, you should always set this value to true.
  • ORDERER_ADMIN_TLS_PRIVATEKEY: The path to and file name of the orderer private key issued by the TLS CA.
  • ORDERER_ADMIN_TLS_CERTIFICATE: The path to and file name of the orderer signed certificate issued by the TLS CA.
  • ORDERER_ADMIN_TLS_CLIENTAUTHREQUIRED: This value must be set to true. Note that while mutual TLS is required for all operations on the orderer Admin endpoint, the entire network is not required to use Mutual TLS.
  • ORDERER_ADMIN_TLS_CLIENTROOTCAS: The path to and file name of the admin client TLS CA Root certificate. In the folder structure above, this is tls/tls-ca-cert.pem.
  • FABRIC_CFG_PATH: Points to the location of orderer.yaml configuration file.
  • FABRIC_LOGGING_SPEC: Sets the logging level specification.

In the orderer.yaml pointed by FABRIC_CFG_PATH, we have commented out General.TLS.RootCAs as recommended in the official docs.

Since there is no system channel the creation of application channels will be done by orderers using the osnadmin command. Fabric holds it mandatory to enable mutual TLS. This means the orderer admin server must be sure that the requesting client is really who it claims it is as well as client must be sure of the server is who claims it is. For the rest of the network only server-side TLS is enough.

Org1

In the “Ordering Service” section we went over startOrderingService.sh script, in this section we will go over the differences between startOrg1.sh and startOrderingService.sh since a great majority of these scripts are the same.

Above is the full startOrg1.sh script. As you can see most of the operations like enroll & register, creating the folder structure are identical but only used the name “Org1” instead of “orderingservice”. So the real difference lies with the creation of the peer node.

This is the service when we run docker-compose -p fabric-2.3 up -d peer1.Org1.com

  • CORE_PEER_ID: The name of the peer.
  • CORE_PEER_ADDRESS: The address that other peers in the organization use to connect to this peer.
  • CORE_PEER_LOCALMSPID: Name of the organization this peer belongs to. This name must match the name of the organization in a channel configuration file in order for this peer to join that channel succesfully.
  • CORE_PEER_LISTENADDRESS: The address this peer will listen on.
  • CORE_PEER_CHAINCODELISTENADDRESS: The address that this peer listens for chaincode requests
  • CORE_PEER_MSPCONFIGPATH: This is the path to the peer’s local MSP.
  • CORE_VM_ENDPOINT: Endpoint of the vm management system. This value should be set correctly to succesfully install and run chaincodes.
  • CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE: Starts chaincode containers on the same bridge network as this peer.
  • FABRIC_LOGGING_SPEC: Sets the logging specification level.
  • CORE_PEER_TLS_ENABLED: Server-side TLS should be enabled in all production networks.
  • CORE_PEER_TLS_CERT_FILE: Path to the certificate(public key) issued by TLS CA of Org1.
  • CORE_PEER_TLS_KEY_FILE: Path to the private key issued by TLS CA of Org1.
  • CORE_PEER_TLS_ROOTCERT_FILE: Path to the root certificate of TLS CA of Org1.
  • CORE_PEER_GOSSIP_USELEADERELECTION: When set false, peer.gossip.orgLeader should be set to true so that this peer receives new blocks from the orderer directly. If this is set to ture this means you prefer that peers use Gossip for block dissemination among peers in the organization.
  • CORE_PEER_GOSSIP_ORGLEADER: If true this peer receives blocks from the orderer directly. Set this value to false if you want to use Gossip for block dissemination among peers in the organization.
  • CORE_PEER_GOSSIP_EXTERNALENDPOINT: The address that other peers in this organization should use to connect to this peer.
  • CORE_PEER_GOSSIP_BOOTSTRAP: The list of other peer addresses in this organization to discover.
  • CORE_LEDGER_STATE_STATEDATABASE: Type of the state database.
  • CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS: Address of the CouchDB container.
  • CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME: Username for the admin of CouchDB server.
  • CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD: Password for the admin of CouchDB server.

peer1.Org1.com.couchdb and cli.peer1.Org1.com docker-compose services will be explained in the part 2 of this walkthrough. Since Org1 and Org2 are identical in terms of topology, we now have walkted through everything that needed our attention.

And with this we complete “start phase” of our network. Once you run all of the startOrderingService.sh , startOrg1.sh and startOrg2.sh scripts the -network will be up and ready for channel operations.

Summary

What we have done so far is;

  • Talked about what an identity is in a Hyperledger Fabric network.
  • Explained an MSP in terms of its usage, types and logic.
  • Described Organizational Units and NodeOUs.
  • Talked about basic flow of Fabric CA.
  • Explained the code and design choices of sample network.

In the next part we will be focusing on channel creation with osnadmin and chaincode operations like package, install, approve, commit, invoke, query . Thank you for reading.

--

--