Search code examples
hyperledger-fabrichyperledger-fabric-ca

Configuring dual-headed CA


I'm trying to configure a dual-headed CA (different crypto material for signing and TLS on the same node) with mutual-TLS by using --cafiles according to:

So the first question is: Do they have to have a different port?

I'm starting the CA like this:

export FABRIC_CA_SERVER_HOME=/config/tls-ca
fabric-ca-server start -b admin:adminpw --cafiles /config/ca/fabric-ca-server-config.yaml

This way, in the /config/tls-ca folder a ca-cert.pem and a tls-cert.pem are created on startup, as well as /config/ca/ca-cert.pem (but no tls-cert.pem). So it seems to be important which CA is created by FABRIC_CA_SERVER_HOME and which one by --cafiles, isn't it? (Second question)

Third question: How should each fabric-ca-server-config.yaml look like to reference the correct files?

Currently, the one for TLS-CA is this (important parts):

port: 7054
tls:
  enabled: true
  certfile: # leave empty?
  keyfile:  # leave empty?
  clientauth:
    type: RequireAndVerifyClientCert
    certfiles:
      - /config/tls-ca/tls-cert.pem # or /config/tls-ca/ca-cert.pem? Or empty?
ca:
  name: Org1TLSCA
csr:
   cn: org1-tls-ca

The one for Signing-CA is this (important parts):

port: 7054 # same port allowed?
tls:
  enabled: true
  certfile: # Do I first have to register and enroll at the TLS-CA and then restart all?
  keyfile:  # see above
  clientauth:
    type: RequireAndVerifyClientCert
    certfiles:
      - /config/tls-ca/tls-cert.pem # or /config/tls-ca/ca-cert.pem? Or empty?
ca:
  name: Org1CA
csr:
   cn: org1-ca

It feels like a chicken-egg problem and I'm not sure which files to use. Any help is appreciated.

Kind regards

[Edit] Bonus question: When the TLS-CA has mutual TLS enabled, how can one issue a certificate for the fabric-ca-client? It's not able to speak to the server because the cert is missing, but it needs to to issue a certificate...


Solution

  • Ok, I finally found a way.

    1. Create two fabric-ca-server-config.yaml files. One for the CA and one for the TLS-CA part:

      config/ca/fabric-ca-server-config.yaml:

      port: 7054
      tls:
        enabled: true
        certfile: /config/ca/tls-msp/signcerts/cert.pem
        keyfile:  /config/ca/tls-msp/keystore/key.pem
        clientauth:
          type: NoClientCert
          certfiles:
            - /config/tls-ca/ca-cert.pem
      ca:
        name: CA
      csr:
         cn: org1-ca
      

      config/tls-ca/fabric-ca-server-config.yaml:

      port: 7054
      tls:
        enabled: true
        certfile: # leave empty
        keyfile:  # leave empty
        clientauth:
          type: RequireAndVerifyClientCert
          certfiles:
            - /config/tls-ca/ca-cert.pem
      ca:
        name: TLSCA
      csr:
         cn: org1-tls-ca
      
    2. Start the server:

      export FABRIC_CA_SERVER_HOME=/config/tls-ca
      export FABRIC_CA_SERVER_TLS_CLIENTAUTH_TYPE=NoClientCert
      fabric-ca-server start -b tls-ca-admin:adminpw --cafiles /config/ca/fabric-ca-server-config.yaml
      
    3. Enroll TLS-CA admin

      export FABRIC_CA_CLIENT_TLS_CERTFILES=/config/tls-ca/ca-cert.pem
      export FABRIC_CA_CLIENT_HOME=msps/org1/tls-ca-admin
      export FABRIC_CA_CLIENT_MSPDIR=msp
      fabric-ca-client enroll -d -u https://tls-ca-admin:adminpw@localhost:7054 --caname TLSCA
      
    4. Create TLS certificate for the (signing-material-)CA and the fabric-ca-client:

      export FABRIC_CA_CLIENT_TLS_CERTFILES=/config/tls-ca/ca-cert.pem
      export FABRIC_CA_CLIENT_HOME=msps/org1/tls-ca-admin
      export FABRIC_CA_CLIENT_MSPDIR=msp
      fabric-ca-client register -d --id.name ca --id.secret caPW --id.type client -u https://localhost:7054 --caname TLSCA
      fabric-ca-client register -d --id.name ca-client --id.secret caclientPW --id.type client -u https://localhost:7054 --caname TLSCA
      
      export FABRIC_CA_CLIENT_HOME=msps/org1/ca
      export FABRIC_CA_CLIENT_MSPDIR=tls-msp
      fabric-ca-client enroll -d --enrollment.profile tls -u https://ca:caPW@localhost:7054 --caname TLSCA
      
      export FABRIC_CA_CLIENT_HOME=msps/org1/ca-client
      fabric-ca-client enroll -d --enrollment.profile tls -u https://ca-client:caclientPW@localhost:7054 --caname TLSCA
      
    5. Copy the generated TLS material into the CA's folder:
      cp -r msps/org1/ca/tls-msp /config/org1/ca/

    6. Shut the CA server down and start it again:

      export FABRIC_CA_SERVER_HOME=/config/tls-ca
      export FABRIC_CA_SERVER_TLS_CLIENTAUTH_TYPE=RequireAndVerifyClientCert
      fabric-ca-server start --cafiles /config/ca/fabric-ca-server-config.yaml
      
    7. You're done! Note: since the CA and TLS-CA part have the same port, you need to append --caname to each fabric-ca-client command. Otherwise the server doesn't know how to route your request.