Eisaku
Eisaku

Reputation: 1

Hyperledger Fabric network configuration issues

I'd like to clarify two things regarding the SAN and SNI in Hyperledger Fabric:

a) Is Common Name (CN) or Subject Alternative Name (SAN) from the client certificate verified by the server when Mutual TLS (TLS with client authentication) is enabled? (f.i. by resolving DNS name and comparing the consecutive IP address with the IP address of the client (the TCP/IP connection source))?

We have already tested this scenario and discovered that a peer as a server verifies TLS certificates hash regardless whether client authentication is enabled or not. Here is an example of peer logs supporting our conclusion:

2021-02-16 08:54:17.491 UTC [common.deliver] Handle -> DEBU 660f7 Attempting to read seek info message from 10.250.26.32:46320
2021-02-16 08:54:17.491 UTC [common.deliver] deliverBlocks -> WARN 660f8 error parsing envelope from 10.250.26.32:46320: **claimed TLS cert hash is** [235 124 10 219 135 57 10 64 94 166 44 162 123 25 91 195 202 31 164 34 51 5 12 238 77 39 197 171 135 246 12 244] **but actual TLS cert hash is** [185 32 246 230 116 37 63 240 4 9 236 246 210 42 59 45 198 22 209 194 183 117 64 137 153 68 27 56 143 39 211 118]
2021-02-16 08:54:17.492 UTC [orderer.common.server] func1 -> DEBU 660f9 Closing Deliver stream
2021-02-16 08:54:17.492 UTC [comm.grpc.server] 1 -> INFO 660fa streaming call completed grpc.service=orderer.AtomicBroadcast grpc.method=Deliver grpc.peer_address=10.250.26.32:46320 grpc.peer_subject="CN=proxy,OU=peer,O=Hyperledger,ST=North Carolina,C=US" grpc.code=OK grpc.call_duration=239.612µs

We also found a source code on github supposedly responsible for such behaviour (https://github.com/hyperledger/fabric/blob/master/internal/pkg/comm/util.go):

// mutualTLSBinding enforces the client to send its TLS cert hash in the message,
// and then compares it to the computed hash that is derived
// from the gRPC context.
// In case they don't match, or the cert hash is missing from the request or
// there is no TLS certificate to be excavated from the gRPC context,
// an error is returned.
func mutualTLSBinding(ctx context.Context, claimedTLScertHash []byte) error {
if len(claimedTLScertHash) == 0 {
return errors.Errorf("client didn't include its TLS cert hash")
}
actualTLScertHash := ExtractCertificateHashFromContext(ctx)
if len(actualTLScertHash) == 0 {
return errors.Errorf("client didn't send a TLS certificate")
}
if !bytes.Equal(actualTLScertHash, claimedTLScertHash) {
return errors.Errorf("claimed TLS cert hash is %v but actual TLS cert hash is %v", claimedTLScertHash, actualTLScertHash)
}
return nil
}

Is it possible to switch off this verification? Do you have any recommendation how can we configure HLF network with gRPCs reverse proxy between organisations (for incoming connections). In our test we assumed that proxy as a client uses its own certificate issued by CA of HLF organisation (peer’s organisation)?

b) Does fabric peers on version 1.4.1 supports SNI (Server Name Indicator)? The issue is if it's possible with proxy to host multiple https servers on a single IP?

We have already tested this using nginx proxy and this part of communication seems to work. But the question is if peer as a client will send SNI to the server (in our case nginx proxy) to inform it what DNS it is aiming? Thanks to it we can run many virtual servers on the proxy using only on IP address.

Upvotes: 0

Views: 428

Answers (1)

yacovm
yacovm

Reputation: 5140

a) Of course not, the server doesn't verify the client certificate SAN or CN when the client is reaching it.

The error you are getting is invoked from within the application layer (Fabric) so it means that you actually pass the TLS handshake.

This error is returned probably because:

  1. Mutual TLS (Client side authentication) is turned on in the peer local configuration. When mutual TLS is turned on, the Fabric client sends its TLS certificate hash in the request it sends to the peer, and the peer checks that the TLS hash matches the hash of the TLS certificate it detects from the stream. This is done to prevent a replay attack that will make a malicious peer re-use the same request to request blocks from peers while the malicious peer is not eligible of receiving these blocks.
  2. Your peer is behind a TLS terminating proxy. In such a case, the peer receives a TLS handshake from the proxy and not from the client, and the proxy has a different TLS certificate, so it rejects it.

Do you have any recommendation how can we configure HLF network with gRPCs reverse proxy between organisations (for incoming connections).

You need your proxy to work in a "passthrough mode" (googling TLS passthrough with your favorite proxy will yield you results).

b)

Does fabric peers on version 1.4.1 supports SNI (Server Name Indicator)? The issue is if it's possible with proxy to host multiple https servers on a single IP?

You can do it if your reverse proxy supports it, and it has nothing to do with Fabric. All you need is your proxy to be able to read the SNI in the client hello of the TLS handshake, and route to the correct port/host without terminating the TLS session.

Upvotes: 0

Related Questions