Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow the user to enable/disable tls and client-side auth selectivly #691

Merged
merged 6 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ clean:
rm -rf ./cmd/fsccli/cmd
rm -rf ./samples/fabric/iou/cmd

.PHONY: clean-fabric-peer-images
clean-fabric-peer-images:
docker images -a | grep "_peer_" | awk '{print $3}' | xargs docker rmi

.PHONY: fsccli
fsccli:
@go install ./cmd/fsccli
23 changes: 20 additions & 3 deletions docs/core-fabric.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ fabric:

# TBD: idemix-folder, bccsp-folder

# define the default values for the tls connections
tls:
# Species the fabric network requires TLS or not
enabled: true
Expand All @@ -291,18 +292,25 @@ fabric:
interval: 60s
# If not provided, the default is 20 seconds
timeout: 600s
# If not provided, the default is 10 seconds
connectionTimeout: 10s
tlsEnabled: true

ordering:
# number of retries to attempt to send a transaction to an orderer
# If not specified or set to 0, it will default to 3 retries
numRetries: 3
# retryInternal specifies the amount of time to wait before retrying a connection to the ordering service, it has no default and must be specified
retryInterval: 3s
# here is possible to disable tls just for the ordering service.
# if this key is not specified, then the `tls` section is used.
tlsEnabled: true
# here is possible to enable tls client-side authentication just for the ordering service
# if this key is not specified, then the `tls` section is used.
tlsClientAuthRequired: false

# List of orderers on top of those discovered in the channel
# This is optional and as such it should be left to those orderers discovered on the channel
# tls configuration is governed by the `tls` section, if not otherwise specified in the `ordering` section
orderers:
# address of orderer
- address: 'orderer0:7050'
Expand All @@ -312,9 +320,14 @@ fabric:
tlsRootCertFile: /path/to/ordererorg/ca.crt
# server name override if tls cert SANS doesn't match address
serverNameOverride:
# it is possible to customize per orderer the TLS behaviour, by using the following attributes
tlsClientSideAuth: true
tlsDisabled: true
tlsEnabled: false

# List of trusted peers this node can connect to.
# usually this will be the fabric peers in the same organisation as the FSC node
# usually this will be the fabric peers in the same organisation as the FSC node.
# tls configuration is governed by the `tls` section.
peers:
# address of orderer
- address: 'peer2:7051'
Expand All @@ -323,8 +336,12 @@ fabric:
# path to peer org's ca cert if tls is enabled
tlsRootCertFile: /path/to/peerorg/ca.crt
serverNameOverride:
# it is possible to customize per peer the TLS behaviour, by using the following attributes
tlsClientSideAuth: true
tlsDisabled: true
tlsEnabled: false

# List of channels and deployed chaincode
# List of channels and deployed chaincode
channels:
- name: mychannel
# whether this is the default channel or not
Expand Down
6 changes: 3 additions & 3 deletions docs/fabric/fabricdev/core/fabricdev/channelprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/delivery"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/finality"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/membership"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/peer"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/rwset"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/services"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/core/generic/transaction"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/driver"
driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver"
Expand Down Expand Up @@ -90,7 +90,7 @@ func (p *provider) NewChannel(nw driver.FabricNetworkService, channelName string
envelopeService := transaction.NewEnvelopeService(p.kvss, nw.Name(), channelName)
transactionService := transaction.NewEndorseTransactionService(p.kvss, nw.Name(), channelName)
metadataService := transaction.NewMetadataService(p.kvss, nw.Name(), channelName)
peerService := peer.NewService(nw.ConfigService(), nw.LocalMembership().DefaultSigningIdentity())
peerService := services.NewClientFactory(nw.ConfigService(), nw.LocalMembership().DefaultSigningIdentity())

// Fabric finality
fabricFinality, err := finality.NewFabricFinality(
Expand Down Expand Up @@ -193,7 +193,7 @@ func (p *provider) NewChannel(nw driver.FabricNetworkService, channelName string
ChannelMembershipService: channelMembershipService,
ChaincodeManagerService: chaincodeManagerService,
CommitterService: committerService,
PeerManager: peerService,
PeerService: peerService,
}
if err := c.Init(); err != nil {
return nil, errors.WithMessagef(err, "failed initializing Channel [%s]", channelName)
Expand Down
44 changes: 30 additions & 14 deletions integration/fabric/iou/iou_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,41 @@ import (

var _ = Describe("EndToEnd", func() {
Describe("IOU Life Cycle With LibP2P", func() {
s := NewTestSuite(fsc.LibP2P, integration.NoReplication)
s := NewTestSuite(fsc.LibP2P, integration.NoReplication, true)
BeforeEach(s.Setup)
AfterEach(s.TearDown)
It("succeeded", s.TestSucceeded)
})

Describe("IOU Life Cycle With Websockets", func() {
s := NewTestSuite(fsc.WebSocket, integration.NoReplication)
s := NewTestSuite(fsc.WebSocket, integration.NoReplication, true)
BeforeEach(s.Setup)
AfterEach(s.TearDown)
It("succeeded", s.TestSucceeded)
})

Describe("IOU Life Cycle With Websockets and no TLS", func() {
s := NewTestSuite(fsc.WebSocket, integration.NoReplication, false)
BeforeEach(s.Setup)
AfterEach(s.TearDown)
It("succeeded", s.TestSucceeded)
})

Describe("IOU Life Cycle With Websockets and replicas", func() {
s := NewTestSuite(fsc.WebSocket, &integration.ReplicationOptions{
ReplicationFactors: map[string]int{
"borrower": 3,
"lender": 2,
},
SQLConfigs: map[string]*postgres.ContainerConfig{
"borrower": postgres.DefaultConfig("borrower-db"),
"lender": postgres.DefaultConfig("lender-db"),
s := NewTestSuite(
fsc.WebSocket,
&integration.ReplicationOptions{
ReplicationFactors: map[string]int{
"borrower": 3,
"lender": 2,
},
SQLConfigs: map[string]*postgres.ContainerConfig{
"borrower": postgres.DefaultConfig("borrower-db"),
"lender": postgres.DefaultConfig("lender-db"),
},
},
})
true,
)
BeforeEach(s.Setup)
AfterEach(s.TearDown)
It("succeeded", s.TestSucceededWithReplicas)
Expand All @@ -50,9 +61,14 @@ type TestSuite struct {
*integration.TestSuite
}

func NewTestSuite(commType fsc.P2PCommunicationType, nodeOpts *integration.ReplicationOptions) *TestSuite {
return &TestSuite{integration.NewTestSuiteWithSQL(nodeOpts.SQLConfigs, func() (*integration.Infrastructure, error) {
return integration.Generate(StartPort(), true, integration.ReplaceTemplate(iou.Topology(&iou.SDK{}, commType, nodeOpts))...)
func NewTestSuite(commType fsc.P2PCommunicationType, nodeOpts *integration.ReplicationOptions, tlsEnabled bool) *TestSuite {
return &TestSuite{TestSuite: integration.NewTestSuiteWithSQL(nodeOpts.SQLConfigs, func() (*integration.Infrastructure, error) {
return integration.Generate(StartPort(), true, integration.ReplaceTemplate(iou.Topology(&iou.Opts{
SDK: &iou.SDK{},
CommType: commType,
ReplicationOpts: nodeOpts,
TLSEnabled: tlsEnabled,
}))...)
})}
}

Expand Down
24 changes: 16 additions & 8 deletions integration/fabric/iou/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,38 @@ import (
"github.com/hyperledger-labs/fabric-smart-client/platform/view/sdk/tracing"
)

func Topology(sdk api2.SDK, commType fsc.P2PCommunicationType, replicationOpts *integration.ReplicationOptions) []api.Topology {
type Opts struct {
SDK api2.SDK
CommType fsc.P2PCommunicationType
ReplicationOpts *integration.ReplicationOptions
TLSEnabled bool
}

func Topology(opts *Opts) []api.Topology {
// Define a Fabric topology with:
// 1. Three organization: Org1, Org2, and Org3
// 2. A namespace whose changes can be endorsed by Org1.
fabricTopology := fabric.NewDefaultTopology()
fabricTopology.AddOrganizationsByName("Org1", "Org2", "Org3")
fabricTopology.SetNamespaceApproverOrgs("Org1")
fabricTopology.AddNamespaceWithUnanimity("iou", "Org1")
fabricTopology.TLSEnabled = opts.TLSEnabled

// Define an FSC topology with 3 FCS nodes.
// One for the approver, one for the borrower, and one for the lender.
fscTopology := fsc.NewTopology()
fscTopology.P2PCommunicationType = commType
fscTopology.P2PCommunicationType = opts.CommType
fscTopology.EnablePrometheusMetrics()

//fscTopology.SetLogging("debug", "")
// fscTopology.SetLogging("debug", "")
fscTopology.EnableTracing(tracing.Otpl)

// Add the approver FSC node.
fscTopology.AddNodeByName("approver1").
// This option equips the approver's FSC node with an identity belonging to Org1.
// Therefore, the approver is an endorser of the Fabric namespace we defined above.
AddOptions(fabric.WithOrganization("Org1")).
AddOptions(replicationOpts.For("approver1")...).
AddOptions(opts.ReplicationOpts.For("approver1")...).
RegisterResponder(&views.ApproverView{}, &views.CreateIOUView{}).
RegisterResponder(&views.ApproverView{}, &views.UpdateIOUView{}).
RegisterViewFactory("init", &views.ApproverInitViewFactory{})
Expand All @@ -50,23 +58,23 @@ func Topology(sdk api2.SDK, commType fsc.P2PCommunicationType, replicationOpts *
// This option equips the approver's FSC node with an identity belonging to Org1.
// Therefore, the approver is an endorser of the Fabric namespace we defined above.
AddOptions(fabric.WithOrganization("Org1")).
AddOptions(replicationOpts.For("approver2")...).
AddOptions(opts.ReplicationOpts.For("approver2")...).
RegisterResponder(&views.ApproverView{}, &views.CreateIOUView{}).
RegisterResponder(&views.ApproverView{}, &views.UpdateIOUView{}).
RegisterViewFactory("init", &views.ApproverInitViewFactory{})

// Add the borrower's FSC node
fscTopology.AddNodeByName("borrower").
AddOptions(fabric.WithOrganization("Org2")).
AddOptions(replicationOpts.For("borrower")...).
AddOptions(opts.ReplicationOpts.For("borrower")...).
RegisterViewFactory("create", &views.CreateIOUViewFactory{}).
RegisterViewFactory("update", &views.UpdateIOUViewFactory{}).
RegisterViewFactory("query", &views.QueryViewFactory{})

// Add the lender's FSC node
fscTopology.AddNodeByName("lender").
AddOptions(fabric.WithOrganization("Org3")).
AddOptions(replicationOpts.For("lender")...).
AddOptions(opts.ReplicationOpts.For("lender")...).
RegisterResponder(&views.CreateIOUResponderView{}, &views.CreateIOUView{}).
RegisterResponder(&views.UpdateIOUResponderView{}, &views.UpdateIOUView{}).
RegisterViewFactory("query", &views.QueryViewFactory{})
Expand All @@ -77,7 +85,7 @@ func Topology(sdk api2.SDK, commType fsc.P2PCommunicationType, replicationOpts *
monitoringTopology.EnableOPTL()

// Add Fabric SDK to FSC Nodes
fscTopology.AddSDK(sdk)
fscTopology.AddSDK(opts.SDK)

return []api.Topology{
fabricTopology,
Expand Down
43 changes: 23 additions & 20 deletions integration/nwo/fabric/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Network struct {
EventuallyTimeout time.Duration
MetricsProvider string
StatsdEndpoint string
TLSEnabled bool
ClientAuthRequired bool

Logging *topology.Logging
Expand Down Expand Up @@ -97,25 +98,27 @@ func New(reg api.Context, topology *topology.Topology, builderClient BuilderClie
EventuallyTimeout: 20 * time.Minute,
MetricsProvider: "prometheus",

Organizations: topology.Organizations,
Consensus: topology.Consensus,
Orderers: topology.Orderers,
Peers: topology.Peers,
SystemChannel: topology.SystemChannel,
Channels: topology.Channels,
Profiles: topology.Profiles,
Consortiums: topology.Consortiums,
Templates: topology.Templates,
Logging: topology.Logging,
MSPvtTxSupport: topology.MSPvtTxSupport,
MSPvtCCSupport: topology.MSPvtCCSupport,
FabTokenSupport: topology.FabTokenSupport,
FabTokenCCSupport: topology.FabTokenCCSupport,
GRPCLogging: topology.GRPCLogging,
PvtTxSupport: topology.PvtTxSupport,
PvtTxCCSupport: topology.PvtTxCCSupport,
ccps: ccps,
Extensions: []Extension{},
Organizations: topology.Organizations,
Consensus: topology.Consensus,
Orderers: topology.Orderers,
Peers: topology.Peers,
SystemChannel: topology.SystemChannel,
Channels: topology.Channels,
Profiles: topology.Profiles,
Consortiums: topology.Consortiums,
Templates: topology.Templates,
Logging: topology.Logging,
MSPvtTxSupport: topology.MSPvtTxSupport,
MSPvtCCSupport: topology.MSPvtCCSupport,
FabTokenSupport: topology.FabTokenSupport,
FabTokenCCSupport: topology.FabTokenCCSupport,
GRPCLogging: topology.GRPCLogging,
PvtTxSupport: topology.PvtTxSupport,
PvtTxCCSupport: topology.PvtTxCCSupport,
ClientAuthRequired: topology.ClientAuthRequired,
TLSEnabled: topology.TLSEnabled,
ccps: ccps,
Extensions: []Extension{},
PackagerFactory: func() Packager {
return packager.New()
},
Expand Down Expand Up @@ -282,7 +285,7 @@ func (n *Network) DeployChaincode(chaincode *topology.ChannelChaincode) {
if chaincode.Chaincode.InitRequired {
InitChaincode(n, chaincode.Channel, orderer, &chaincode.Chaincode, peers...)
}
//add new chaincode to the topology
// add new chaincode to the topology
n.topology.AddChaincode(chaincode)
}

Expand Down
29 changes: 16 additions & 13 deletions integration/nwo/fabric/network/network_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@ func (n *Network) PeerRunner(p *topology.Peer, env ...string) *runner2.Runner {
}, "", fmt.Sprintf("FABRIC_CFG_PATH=%s", n.PeerDir(p)), fmt.Sprintf("CORE_PEER_ID=%s", fmt.Sprintf("%s.%s", p.Name, n.Organization(p.Organization).Domain)))

cmd.Env = append(cmd.Env, env...)
//cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
// cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}

config := runner2.Config{
AnsiColorCode: n.nextColor(),
Expand Down Expand Up @@ -1035,17 +1035,19 @@ func (n *Network) peerCommand(command common.Command, tlsDir string, env ...stri
cmd.Env = append(cmd.Env, "GRPC_GO_LOG_SEVERITY_LEVEL=debug")
}

if common.ConnectsToOrderer(command) {
cmd.Args = append(cmd.Args, "--tls")
cmd.Args = append(cmd.Args, "--cafile", n.CACertsBundlePath())
}
if n.topology.TLSEnabled {
if common.ConnectsToOrderer(command) {
cmd.Args = append(cmd.Args, "--tls")
cmd.Args = append(cmd.Args, "--cafile", n.CACertsBundlePath())
}

if common.ClientAuthEnabled(command) {
certfilePath := filepath.Join(tlsDir, "client.crt")
keyfilePath := filepath.Join(tlsDir, "client.key")
if common.ClientAuthEnabled(command) {
certfilePath := filepath.Join(tlsDir, "client.crt")
keyfilePath := filepath.Join(tlsDir, "client.key")

cmd.Args = append(cmd.Args, "--certfile", certfilePath)
cmd.Args = append(cmd.Args, "--keyfile", keyfilePath)
cmd.Args = append(cmd.Args, "--certfile", certfilePath)
cmd.Args = append(cmd.Args, "--keyfile", keyfilePath)
}
}

cmd.Env = append(cmd.Env, fmt.Sprintf("FABRIC_LOGGING_SPEC=%s", n.Logging.Spec))
Expand Down Expand Up @@ -1534,16 +1536,17 @@ func (n *Network) GenerateOrdererConfig(o *topology.Orderer) {
orderer, err := os.Create(n.OrdererConfigPath(o))
Expect(err).NotTo(HaveOccurred())
defer orderer.Close()

tlsEnabled := n.topology.TLSEnabled
t, err := template.New("orderer").Funcs(template.FuncMap{
"Orderer": func() *topology.Orderer { return o },
"ToLower": func(s string) string { return strings.ToLower(s) },
"ReplaceAll": func(s, old, new string) string { return strings.Replace(s, old, new, -1) },
"TLSEnabled": func() bool { return tlsEnabled },
}).Parse(n.Templates.OrdererTemplate())
Expect(err).NotTo(HaveOccurred())

// pw := gexec.NewPrefixedWriter(fmt.Sprintf("[%s#orderer.yaml] ", o.ID()), ginkgo.GinkgoWriter)
err = t.Execute(io.MultiWriter(orderer), n)
pw := gexec.NewPrefixedWriter(fmt.Sprintf("[%s#orderer.yaml] ", o.ID()), ginkgo.GinkgoWriter)
err = t.Execute(io.MultiWriter(orderer, pw), n)
Expect(err).NotTo(HaveOccurred())
}

Expand Down
4 changes: 3 additions & 1 deletion integration/nwo/fabric/topology/core_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ peer:
keepalive:
minInterval: 60s
tls:
enabled: true
enabled: {{ .TLSEnabled }}
clientAuthRequired: {{ .ClientAuthRequired }}
cert:
file: {{ .PeerLocalTLSDir Peer }}/server.crt
Expand Down Expand Up @@ -287,9 +287,11 @@ fabric:
keepalive:
interval: 60s
timeout: 600s
connectionTimeout: 10s
ordering:
numRetries: 3
retryInterval: 3s
tlsEnabled: {{ TLSEnabled }}
peers: {{ range Peers }}
- address: {{ PeerAddress . "Listen" }}
connectionTimeout: 10s
Expand Down
Loading