Skip to content

Commit 06784e2

Browse files
authored
[committer] Secure Committer Communication with TLS and mTLS (#85)
<!-- Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 --> #### Type of change - New feature - Improvement (improvement to code, performance, etc) #### Description To support secure communication between components, we added a TLS layer to ensure encrypted message transmission. This PR includes the following changes: 1. Implemented TLS and mTLS between the committer components. 2. Added TLS and mTLS support to the runtime, along with various TLS modes tests that utilize the loadgen to submit transactions after establishing a secure connection. 3. Added unit tests for each of the components. 4. Added TLS support to the loadgen adapters. #### Additional details * Each service can be configured to use TLS, mTLS, or an insecure connection via the tlsConfig. Clients must be configured accordingly. * All clients of a given service use the same set of credentials. #### Related issues Partly solves epic: #19, solves #108 Next related PRs: 1. TLS support for the database connection is already finished and just waiting for this PR to be merged. 2. Integration tests based on release images. 3. Unit tests for each load generator adapter. 4. TLS support for Mock-Orderer to Sidecar communication. 5. Prometheus servers configured with TLS. --------- Signed-off-by: Dean Amar <Dean.Amar@ibm.com>
1 parent e3ec30f commit 06784e2

62 files changed

Lines changed: 1188 additions & 570 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cmd/config/app_config_test.go

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,15 @@ func TestReadConfigSidecar(t *testing.T) {
4141
name: "default",
4242
configFilePath: emptyConfig(t),
4343
expectedConfig: &sidecar.Config{
44-
Server: makeServer("localhost", 4001),
45-
Monitoring: makeMonitoring("localhost", 2114),
44+
Server: newServerConfig("localhost", 4001),
45+
Monitoring: newMonitoringConfig("localhost", 2114),
4646
Orderer: ordererconn.Config{
4747
Connection: ordererconn.ConnectionConfig{
48-
Endpoints: ordererconn.NewEndpoints(0, "", makeServer("localhost", 7050)),
48+
Endpoints: ordererconn.NewEndpoints(0, "", newServerConfig("localhost", 7050)),
4949
},
5050
ChannelID: "mychannel",
5151
},
52-
Committer: sidecar.CoordinatorConfig{
53-
Endpoint: *makeEndpoint("localhost", 9001),
54-
},
52+
Committer: newClientConfig("localhost", 9001),
5553
Ledger: sidecar.LedgerConfig{
5654
Path: "./ledger/",
5755
},
@@ -67,7 +65,7 @@ func TestReadConfigSidecar(t *testing.T) {
6765
configFilePath: "samples/sidecar.yaml",
6866
expectedConfig: &sidecar.Config{
6967
Server: &connection.ServerConfig{
70-
Endpoint: *makeEndpoint("", 4001),
68+
Endpoint: *newEndpoint("", 4001),
7169
KeepAlive: &connection.ServerKeepAliveConfig{
7270
Params: &connection.ServerKeepAliveParamsConfig{
7371
Time: 300 * time.Second,
@@ -79,18 +77,16 @@ func TestReadConfigSidecar(t *testing.T) {
7977
},
8078
},
8179
},
82-
Monitoring: makeMonitoring("", 2114),
80+
Monitoring: newMonitoringConfig("", 2114),
8381
Orderer: ordererconn.Config{
8482
Connection: ordererconn.ConnectionConfig{
8583
Endpoints: ordererconn.NewEndpoints(
86-
0, "", makeServer("ordering-service", 7050),
84+
0, "", newServerConfig("ordering-service", 7050),
8785
),
8886
},
8987
ChannelID: "mychannel",
9088
},
91-
Committer: sidecar.CoordinatorConfig{
92-
Endpoint: *makeEndpoint("coordinator", 9001),
93-
},
89+
Committer: newClientConfig("coordinator", 9001),
9490
Ledger: sidecar.LedgerConfig{
9591
Path: "/root/sc/ledger",
9692
},
@@ -124,9 +120,9 @@ func TestReadConfigCoordinator(t *testing.T) {
124120
name: "default",
125121
configFilePath: emptyConfig(t),
126122
expectedConfig: &coordinator.Config{
127-
Server: makeServer("localhost", 9001),
128-
Monitoring: makeMonitoring("localhost", 2119),
129-
DependencyGraphConfig: &coordinator.DependencyGraphConfig{
123+
Server: newServerConfig("localhost", 9001),
124+
Monitoring: newMonitoringConfig("localhost", 2119),
125+
DependencyGraph: &coordinator.DependencyGraphConfig{
130126
NumOfLocalDepConstructors: 1,
131127
WaitingTxsLimit: 100_000,
132128
},
@@ -136,15 +132,11 @@ func TestReadConfigCoordinator(t *testing.T) {
136132
name: "sample",
137133
configFilePath: "samples/coordinator.yaml",
138134
expectedConfig: &coordinator.Config{
139-
Server: makeServer("", 9001),
140-
Monitoring: makeMonitoring("", 2119),
141-
VerifierConfig: connection.ClientConfig{
142-
Endpoints: []*connection.Endpoint{makeEndpoint("signature-verifier", 5001)},
143-
},
144-
ValidatorCommitterConfig: connection.ClientConfig{
145-
Endpoints: []*connection.Endpoint{makeEndpoint("validator-persister", 6001)},
146-
},
147-
DependencyGraphConfig: &coordinator.DependencyGraphConfig{
135+
Server: newServerConfig("", 9001),
136+
Monitoring: newMonitoringConfig("", 2119),
137+
Verifier: newMultiClientConfig("signature-verifier", 5001),
138+
ValidatorCommitter: newMultiClientConfig("validator-persister", 6001),
139+
DependencyGraph: &coordinator.DependencyGraphConfig{
148140
NumOfLocalDepConstructors: 1,
149141
WaitingTxsLimit: 100_000,
150142
},
@@ -174,8 +166,8 @@ func TestReadConfigVC(t *testing.T) {
174166
name: "default",
175167
configFilePath: emptyConfig(t),
176168
expectedConfig: &vc.Config{
177-
Server: makeServer("localhost", 6001),
178-
Monitoring: makeMonitoring("localhost", 2116),
169+
Server: newServerConfig("localhost", 6001),
170+
Monitoring: newMonitoringConfig("localhost", 2116),
179171
Database: defaultDBConfig(),
180172
ResourceLimits: &vc.ResourceLimitsConfig{
181173
MaxWorkersForPreparer: 1,
@@ -189,8 +181,8 @@ func TestReadConfigVC(t *testing.T) {
189181
name: "sample",
190182
configFilePath: "samples/vcservice.yaml",
191183
expectedConfig: &vc.Config{
192-
Server: makeServer("", 6001),
193-
Monitoring: makeMonitoring("", 2116),
184+
Server: newServerConfig("", 6001),
185+
Monitoring: newMonitoringConfig("", 2116),
194186
Database: defaultSampleDBConfig(),
195187
ResourceLimits: &vc.ResourceLimitsConfig{
196188
MaxWorkersForPreparer: 1,
@@ -224,8 +216,8 @@ func TestReadConfigVerifier(t *testing.T) {
224216
name: "default",
225217
configFilePath: emptyConfig(t),
226218
expectedConfig: &verifier.Config{
227-
Server: makeServer("localhost", 5001),
228-
Monitoring: makeMonitoring("localhost", 2115),
219+
Server: newServerConfig("localhost", 5001),
220+
Monitoring: newMonitoringConfig("localhost", 2115),
229221
ParallelExecutor: verifier.ExecutorConfig{
230222
Parallelism: 4,
231223
BatchSizeCutoff: 50,
@@ -237,8 +229,8 @@ func TestReadConfigVerifier(t *testing.T) {
237229
name: "sample",
238230
configFilePath: "samples/sigservice.yaml",
239231
expectedConfig: &verifier.Config{
240-
Server: makeServer("", 5001),
241-
Monitoring: makeMonitoring("", 2115),
232+
Server: newServerConfig("", 5001),
233+
Monitoring: newMonitoringConfig("", 2115),
242234
ParallelExecutor: verifier.ExecutorConfig{
243235
BatchSizeCutoff: 50,
244236
BatchTimeCutoff: 10 * time.Millisecond,
@@ -270,8 +262,8 @@ func TestReadConfigQuery(t *testing.T) {
270262
name: "default",
271263
configFilePath: emptyConfig(t),
272264
expectedConfig: &query.Config{
273-
Server: makeServer("localhost", 7001),
274-
Monitoring: makeMonitoring("localhost", 2117),
265+
Server: newServerConfig("localhost", 7001),
266+
Monitoring: newMonitoringConfig("localhost", 2117),
275267
Database: defaultDBConfig(),
276268
MinBatchKeys: 1024,
277269
MaxBatchWait: 100 * time.Millisecond,
@@ -283,8 +275,8 @@ func TestReadConfigQuery(t *testing.T) {
283275
name: "sample",
284276
configFilePath: "samples/queryservice.yaml",
285277
expectedConfig: &query.Config{
286-
Server: makeServer("", 7001),
287-
Monitoring: makeMonitoring("", 2117),
278+
Server: newServerConfig("", 7001),
279+
Monitoring: newMonitoringConfig("", 2117),
288280
Database: defaultSampleDBConfig(),
289281
MinBatchKeys: 1024,
290282
MaxBatchWait: 100 * time.Millisecond,
@@ -316,18 +308,18 @@ func TestReadConfigLoadGen(t *testing.T) {
316308
name: "default",
317309
configFilePath: emptyConfig(t),
318310
expectedConfig: &loadgen.ClientConfig{
319-
Server: makeServer("localhost", 8001),
311+
Server: newServerConfig("localhost", 8001),
320312
Monitoring: metrics.Config{
321-
Config: makeMonitoring("localhost", 2118),
313+
Config: newMonitoringConfig("localhost", 2118),
322314
},
323315
},
324316
}, {
325317
name: "sample",
326318
configFilePath: "samples/loadgen.yaml",
327319
expectedConfig: &loadgen.ClientConfig{
328-
Server: makeServer("", 8001),
320+
Server: newServerConfig("", 8001),
329321
Monitoring: metrics.Config{
330-
Config: makeMonitoring("", 2118),
322+
Config: newMonitoringConfig("", 2118),
331323
Latency: metrics.LatencyConfig{
332324
SamplerConfig: metrics.SamplerConfig{
333325
Portion: 0.01,
@@ -341,11 +333,11 @@ func TestReadConfigLoadGen(t *testing.T) {
341333
},
342334
Adapter: adapters.AdapterConfig{
343335
OrdererClient: &adapters.OrdererClientConfig{
344-
SidecarEndpoint: makeEndpoint("sidecar", 4001),
336+
SidecarClient: newClientConfig("sidecar", 4001),
345337
Orderer: ordererconn.Config{
346338
Connection: ordererconn.ConnectionConfig{
347339
Endpoints: ordererconn.NewEndpoints(
348-
0, "", makeServer("ordering-service", 7050),
340+
0, "", newServerConfig("ordering-service", 7050),
349341
),
350342
},
351343
ChannelID: "mychannel",
@@ -373,7 +365,7 @@ func TestReadConfigLoadGen(t *testing.T) {
373365
ID: 0,
374366
MspID: "org",
375367
API: []string{"broadcast", "deliver"},
376-
Endpoint: *makeEndpoint("ordering-service", 7050),
368+
Endpoint: *newEndpoint("ordering-service", 7050),
377369
}},
378370
},
379371
},
@@ -385,7 +377,7 @@ func TestReadConfigLoadGen(t *testing.T) {
385377
},
386378
Stream: &workload.StreamOptions{
387379
RateLimit: &workload.LimiterConfig{
388-
Endpoint: *makeEndpoint("", 6997),
380+
Endpoint: *newEndpoint("", 6997),
389381
InitialLimit: 10_000,
390382
},
391383
BuffersSize: 10,
@@ -415,7 +407,7 @@ func TestReadConfigLoadGen(t *testing.T) {
415407

416408
func defaultDBConfig() *vc.DatabaseConfig {
417409
return &vc.DatabaseConfig{
418-
Endpoints: []*connection.Endpoint{makeEndpoint("localhost", 5433)},
410+
Endpoints: []*connection.Endpoint{newEndpoint("localhost", 5433)},
419411
Username: "yugabyte",
420412
Password: "yugabyte",
421413
Database: "yugabyte",
@@ -429,7 +421,7 @@ func defaultDBConfig() *vc.DatabaseConfig {
429421

430422
func defaultSampleDBConfig() *vc.DatabaseConfig {
431423
return &vc.DatabaseConfig{
432-
Endpoints: []*connection.Endpoint{makeEndpoint("db", 5433)},
424+
Endpoints: []*connection.Endpoint{newEndpoint("db", 5433)},
433425
Username: "yugabyte",
434426
Password: "yugabyte",
435427
Database: "yugabyte",
@@ -446,21 +438,37 @@ func defaultSampleDBConfig() *vc.DatabaseConfig {
446438
}
447439
}
448440

449-
func makeEndpoint(host string, port int) *connection.Endpoint {
450-
return &connection.Endpoint{
451-
Host: host,
452-
Port: port,
441+
func newClientConfig(host string, port int) *connection.ClientConfig {
442+
return &connection.ClientConfig{
443+
Endpoint: newEndpoint(host, port),
444+
}
445+
}
446+
447+
func newMultiClientConfig(host string, port int) connection.MultiClientConfig {
448+
return connection.MultiClientConfig{
449+
Endpoints: []*connection.Endpoint{
450+
newEndpoint(host, port),
451+
},
452+
}
453+
}
454+
455+
func newMonitoringConfig(host string, port int) monitoring.Config {
456+
return monitoring.Config{
457+
Server: newServerConfig(host, port),
453458
}
454459
}
455460

456-
func makeServer(host string, port int) *connection.ServerConfig {
461+
func newServerConfig(host string, port int) *connection.ServerConfig {
457462
return &connection.ServerConfig{
458-
Endpoint: *makeEndpoint(host, port),
463+
Endpoint: *newEndpoint(host, port),
459464
}
460465
}
461466

462-
func makeMonitoring(host string, port int) monitoring.Config {
463-
return monitoring.Config{Server: makeServer(host, port)}
467+
func newEndpoint(host string, port int) *connection.Endpoint {
468+
return &connection.Endpoint{
469+
Host: host,
470+
Port: port,
471+
}
464472
}
465473

466474
func emptyConfig(t *testing.T) string {

cmd/config/cobra_test_exports.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/hyperledger/fabric-x-committer/service/vc/dbtest"
2727
"github.com/hyperledger/fabric-x-committer/utils/connection"
2828
"github.com/hyperledger/fabric-x-committer/utils/logging"
29+
"github.com/hyperledger/fabric-x-committer/utils/test"
2930
)
3031

3132
// CommandTest is a struct that represents a CMD unit test.
@@ -47,7 +48,7 @@ func StartDefaultSystem(t *testing.T) SystemConfig {
4748
_, orderer := mock.StartMockOrderingServices(t, &mock.OrdererConfig{NumService: 1})
4849
_, coordinator := mock.StartMockCoordinatorService(t)
4950
conn := dbtest.PrepareTestEnv(t)
50-
server := connection.NewLocalHostServer()
51+
server := connection.NewLocalHostServerWithTLS(test.InsecureTLSConfig)
5152
listen, err := server.Listener()
5253
require.NoError(t, err)
5354
connection.CloseConnectionsLog(listen)

cmd/config/create_config_file.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ type (
3131
// Instance endpoints.
3232
ServiceEndpoints ServiceEndpoints
3333

34+
// ServiceTLS holds the TLS configuration for a service.
35+
ServiceTLS connection.TLSConfig
36+
// ClientTLS holds the TLS configuration used by a service when acting as a client to other services.
37+
ClientTLS connection.TLSConfig
38+
3439
// System's resources.
3540
Endpoints SystemEndpoints
3641
DB DatabaseConfig

cmd/config/samples/loadgen.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ monitoring:
1616
bucket-count: 1000
1717

1818
orderer-client:
19-
sidecar-endpoint: sidecar:4001
19+
sidecar-client:
20+
endpoint: sidecar:4001
2021
orderer:
2122
connection:
2223
endpoints:

cmd/config/templates/coordinator.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
#
55
server:
66
endpoint: {{ .ServiceEndpoints.Server | default "localhost:0" }}
7+
tls:
8+
mode: {{ .ServiceTLS.Mode }}
9+
key-path: {{ .ServiceTLS.KeyPath }}
10+
cert-path: {{ .ServiceTLS.CertPath }}
11+
ca-cert-paths:
12+
{{- range .ServiceTLS.CACertPaths }}
13+
- {{ . }}
14+
{{- end }}
715
monitoring:
816
server:
917
endpoint: {{ .ServiceEndpoints.Metrics | default "localhost:0" }}
@@ -13,11 +21,20 @@ verifier:
1321
{{- range .Endpoints.Verifier }}
1422
- {{ .Server }}
1523
{{- end }}
24+
tls: &ClientCreds
25+
mode: {{ .ClientTLS.Mode }}
26+
key-path: {{ .ClientTLS.KeyPath }}
27+
cert-path: {{ .ClientTLS.CertPath }}
28+
ca-cert-paths:
29+
{{- range .ClientTLS.CACertPaths }}
30+
- {{ . }}
31+
{{- end }}
1632
validator-committer:
1733
endpoints:
1834
{{- range .Endpoints.VCService }}
1935
- {{ .Server }}
2036
{{- end }}
37+
tls: *ClientCreds
2138

2239
dependency-graph:
2340
num-of-local-dep-constructors: 1

cmd/config/templates/loadgen_client_coordinator.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,11 @@
77

88
coordinator-client:
99
endpoint: {{ .Endpoints.Coordinator.Server }}
10+
tls:
11+
mode: {{ .ClientTLS.Mode }}
12+
key-path: {{ .ClientTLS.KeyPath }}
13+
cert-path: {{ .ClientTLS.CertPath }}
14+
ca-cert-paths:
15+
{{- range .ClientTLS.CACertPaths }}
16+
- {{ . }}
17+
{{- end }}

cmd/config/templates/loadgen_client_distributed_loadgen.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,11 @@
77

88
loadgen-client:
99
endpoint: {{ .Endpoints.LoadGen.Server }}
10+
tls:
11+
mode: {{ .ClientTLS.Mode }}
12+
key-path: {{ .ClientTLS.KeyPath }}
13+
cert-path: {{ .ClientTLS.CertPath }}
14+
ca-cert-paths:
15+
{{- range .ClientTLS.CACertPaths }}
16+
- {{ . }}
17+
{{- end }}

cmd/config/templates/loadgen_client_orderer.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@
66
# It should be complimented by the common load generator configuration.
77

88
orderer-client:
9-
sidecar-endpoint: {{ .Endpoints.Sidecar.Server }}
9+
sidecar-client:
10+
endpoint: {{ .Endpoints.Sidecar.Server }}
11+
tls:
12+
mode: {{ .ClientTLS.Mode }}
13+
key-path: {{ .ClientTLS.KeyPath }}
14+
cert-path: {{ .ClientTLS.CertPath }}
15+
ca-cert-paths:
16+
{{- range .ClientTLS.CACertPaths }}
17+
- {{ . }}
18+
{{- end }}
1019
orderer:
1120
connection:
1221
endpoints:

0 commit comments

Comments
 (0)