Enabling TLS on Hyperledger Fabric peer and orderer nodes encrypts client, peer, and ordering-service connections and lets clients verify the node identity before sending channel traffic. It is a production baseline whenever Fabric services are reachable outside a local lab or pass through shared network segments.
Fabric reads peer TLS settings from core.yaml under peer.tls and orderer TLS settings from orderer.yaml under General.TLS. The node certificate needs Subject Alternative Name entries for the DNS names or IP addresses that clients use, and the CLI needs the issuing TLS CA file when it connects.
A working rollout starts with node TLS certificates issued by the organization's TLS CA and copied into protected directories. Keep the same hostnames in certificate enrollment, node addresses, and CLI commands; a wrong name or wrong CA should fail before any channel command succeeds.
$ echo "$FABRIC_CFG_PATH" /etc/hyperledger/fabric
peer reads core.yaml and orderer reads orderer.yaml from FABRIC_CFG_PATH unless the service wrapper, container, or pod sets another configuration path.
/etc/hyperledger/fabric/org1/peer0/tls/ca.crt /etc/hyperledger/fabric/org1/peer0/tls/server.crt /etc/hyperledger/fabric/org1/peer0/tls/server.key /etc/hyperledger/fabric/orderer/tls/ca.crt /etc/hyperledger/fabric/orderer/tls/server.crt /etc/hyperledger/fabric/orderer/tls/server.key
Keep server.key readable only by the account, container, or pod that starts the Fabric component. A leaked node TLS private key lets another endpoint impersonate that peer or orderer until the certificate is replaced.
Enroll node TLS certificates with --enrollment.profile tls and --csr.hosts values that match the service names clients use.
Related: How to register and enroll a Hyperledger Fabric identity
$ openssl x509 -in /etc/hyperledger/fabric/org1/peer0/tls/server.crt -noout -subject -issuer -ext subjectAltName subject=CN=peer0.org1.example.com, O=Org1 issuer=CN=Org1 TLS CA, O=Org1 X509v3 Subject Alternative Name: DNS:peer0.org1.example.com, DNS:peer0, IP Address:127.0.0.1
Repeat the same inspection for the orderer certificate. Modern TLS clients use Subject Alternative Name entries for hostname checks; a familiar common name is not enough when the name clients dial is missing.
$ openssl verify -CAfile /etc/hyperledger/fabric/org1/peer0/tls/ca.crt /etc/hyperledger/fabric/org1/peer0/tls/server.crt /etc/hyperledger/fabric/org1/peer0/tls/server.crt: OK
Run the same check against the orderer certificate and its TLS CA file before restarting the ordering service.
$ sudoedit /etc/hyperledger/fabric/core.yaml
peer: tls: enabled: true clientAuthRequired: false cert: file: /etc/hyperledger/fabric/org1/peer0/tls/server.crt key: file: /etc/hyperledger/fabric/org1/peer0/tls/server.key rootcert: file: /etc/hyperledger/fabric/org1/peer0/tls/ca.crt clientRootCAs: files: - /etc/hyperledger/fabric/org1/peer0/tls/ca.crt
Set clientAuthRequired to true only when peer clients are ready to present client TLS certificates and keys. Containers can override the same settings with CORE_PEER_TLS_* environment variables, but keep one source of truth for the deployment.
$ sudoedit /etc/hyperledger/fabric/orderer.yaml
General: TLS: Enabled: true PrivateKey: /etc/hyperledger/fabric/orderer/tls/server.key Certificate: /etc/hyperledger/fabric/orderer/tls/server.crt RootCAs: - /etc/hyperledger/fabric/orderer/tls/ca.crt ClientAuthRequired: false ClientRootCAs: - /etc/hyperledger/fabric/orderer/tls/ca.crt
RootCAs trusts remote orderer certificates for outbound ordering-service communication. ClientRootCAs is used when ClientAuthRequired is true and clients must present a trusted client TLS certificate.
$ sudo systemctl restart fabric-peer
Replace fabric-peer with the actual service unit, container, Compose service, or Kubernetes workload that starts the peer.
$ sudo systemctl restart fabric-orderer
Do not put a TLS-terminating proxy in front of a Fabric node. If a proxy is required, use TCP TLS passthrough so the Fabric client still verifies the peer or orderer certificate.
$ export FABRIC_CFG_PATH=/etc/hyperledger/fabric $ export CORE_PEER_TLS_ENABLED=true $ export CORE_PEER_LOCALMSPID=Org1MSP $ export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/org1/admin/msp $ export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/org1/peer0/tls/ca.crt $ export CORE_PEER_ADDRESS=peer0.org1.example.com:7051 $ export ORDERER_CA=/etc/hyperledger/fabric/orderer/tls/ca.crt
When mutual TLS is enabled on the peer, also set CORE_PEER_TLS_CLIENTAUTHREQUIRED, CORE_PEER_TLS_CLIENTCERT_FILE, and CORE_PEER_TLS_CLIENTKEY_FILE before running peer CLI commands.
$ peer channel list INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized Channels peers has joined: mychannel
An empty channel list can still prove the CLI reached the peer when the node has not joined any channels yet. The connection failure to fix is usually a hostname mismatch, wrong CORE_PEER_TLS_ROOTCERT_FILE, or missing client certificate when mutual TLS is required.
$ peer channel fetch newest ./mychannel-newest.block \ -o orderer.example.com:7050 \ -c mychannel \ --tls \ --cafile "$ORDERER_CA" INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized INFO [channelCmd] readBlock -> Received block: 8
Add --ordererTLSHostnameOverride only for a lab or port-forwarded connection where the dialed address is not the hostname in the orderer certificate. Production clients should normally dial the certificate hostname directly.
$ openssl s_client -connect peer0.org1.example.com:7051 -servername peer0.org1.example.com -verify_hostname peer0.org1.example.com -CAfile /etc/hyperledger/fabric/org1/peer0/tls/ca.crt Connecting to 203.0.113.21 depth=1 CN=Org1 TLS CA, O=Org1 verify return:1 depth=0 CN=peer0.org1.example.com, O=Org1 verify return:1 CONNECTED(00000003) --- Certificate chain ##### snipped ##### Verification: OK Verified peername: peer0.org1.example.com ##### snipped ##### Verify return code: 0 (ok)
The same probe works for the orderer when the host, port, and CA file are replaced with the orderer values.
$ openssl s_client -connect peer0.org1.example.com:7051 -servername wrong.example.com -verify_hostname wrong.example.com -CAfile /etc/hyperledger/fabric/org1/peer0/tls/ca.crt Connecting to 203.0.113.21 depth=0 CN=peer0.org1.example.com, O=Org1 verify error:num=62:hostname mismatch ##### snipped ##### Verification error: hostname mismatch ##### snipped ##### Verify return code: 62 (hostname mismatch)
This controlled failure confirms the client is checking the certificate name instead of accepting any certificate signed by the CA.