From 42ecc2f2b9c7750a864b6388c1d29c9802ca4fb1 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Mon, 10 Jun 2024 11:48:14 +0300 Subject: [PATCH] [#1170] morph: Support mTLS Signed-off-by: Evgenii Stratonikov --- go.mod | 2 ++ go.sum | 4 ++-- pkg/morph/client/constructor.go | 13 +++++++++---- pkg/morph/client/mtls.go | 22 ++++++++++++++++++++++ pkg/morph/client/multi.go | 13 +++++++------ 5 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 pkg/morph/client/mtls.go diff --git a/go.mod b/go.mod index 42896ed8c..4ce8a0d27 100644 --- a/go.mod +++ b/go.mod @@ -127,3 +127,5 @@ require ( lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) + +replace github.com/nspcc-dev/neo-go => git.frostfs.info/TrueCloudLab/neoneo-go v0.106.1-0.20240611123832-594f716b3d18 diff --git a/go.sum b/go.sum index 07632a032..cb97af3d4 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240531132048-ebd8fcd1685f git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240531132048-ebd8fcd1685f/go.mod h1:4AObM67VUqkXQJlODTFThFnuMGEuK8h9DrAXHDZqvCU= git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc= git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM= +git.frostfs.info/TrueCloudLab/neoneo-go v0.106.1-0.20240611123832-594f716b3d18 h1:JRjwcHaQajTbSCBCK3yZnqvyHvgWBaoThDGuT4kvIIc= +git.frostfs.info/TrueCloudLab/neoneo-go v0.106.1-0.20240611123832-594f716b3d18/go.mod h1:bZyJexBlrja4ngxiBgo8by5pVHuAbhg9l09/8yVGDyg= git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240513163744-1f6f4163d40d h1:hHk8FWbWgEnwm2I045CaBIrZBjy/o81CehIVOySA/pQ= git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240513163744-1f6f4163d40d/go.mod h1:SgioiGhQNWqiV5qpFAXRDJF81SEFRBhtwGEiU0FViyA= git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA= @@ -186,8 +188,6 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2 h1:mD9hU3v+zJcnHAVmHnZKt3I++tvn30gBj2rP2PocZMk= github.com/nspcc-dev/go-ordered-json v0.0.0-20240301084351-0246b013f8b2/go.mod h1:U5VfmPNM88P4RORFb6KSUVBdJBDhlqggJZYGXGPxOcc= -github.com/nspcc-dev/neo-go v0.106.0 h1:YiOdW/GcLmbVSvxMRfD5aytO6n3TDHrEA97VHMawy6g= -github.com/nspcc-dev/neo-go v0.106.0/go.mod h1:9k7vBqqQeePuj4c2CqMN9uPFsfxvwSk9vnQFrkE5eg8= github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240521091047-78685785716d h1:Vcb7YkZuUSSIC+WF/xV3UDfHbAxZgyT2zGleJP3Ig5k= github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240521091047-78685785716d/go.mod h1:/vrbWSHc7YS1KSYhVOyyeucXW/e+1DkVBOgnBEXUCeY= github.com/nspcc-dev/rfc6979 v0.2.1 h1:8wWxkamHWFmO790GsewSoKUSJjVnL1fmdRpokU/RgRM= diff --git a/pkg/morph/client/constructor.go b/pkg/morph/client/constructor.go index 50a9572d4..c499aa892 100644 --- a/pkg/morph/client/constructor.go +++ b/pkg/morph/client/constructor.go @@ -141,7 +141,7 @@ func New(ctx context.Context, key *keys.PrivateKey, opts ...Option) (*Client, er } else { var endpoint Endpoint for cli.endpoints.curr, endpoint = range cli.endpoints.list { - cli.client, act, err = cli.newCli(ctx, endpoint.Address) + cli.client, act, err = cli.newCli(ctx, endpoint) if err != nil { cli.logger.Warn(logs.FrostFSIRCouldntCreateRPCClientForEndpoint, zap.Error(err), zap.String("endpoint", endpoint.Address)) @@ -162,10 +162,15 @@ func New(ctx context.Context, key *keys.PrivateKey, opts ...Option) (*Client, er return cli, nil } -func (c *Client) newCli(ctx context.Context, endpoint string) (*rpcclient.WSClient, *actor.Actor, error) { - cli, err := rpcclient.NewWS(ctx, endpoint, rpcclient.WSOptions{ +func (c *Client) newCli(ctx context.Context, endpoint Endpoint) (*rpcclient.WSClient, *actor.Actor, error) { + cfg, err := endpoint.MTLSConfig.parse() + if err != nil { + return nil, nil, fmt.Errorf("read mtls certificates: %w", err) + } + cli, err := rpcclient.NewWS(ctx, endpoint.Address, rpcclient.WSOptions{ Options: rpcclient.Options{ - DialTimeout: c.cfg.dialTimeout, + DialTimeout: c.cfg.dialTimeout, + TLSClientConfig: cfg, }, }) if err != nil { diff --git a/pkg/morph/client/mtls.go b/pkg/morph/client/mtls.go new file mode 100644 index 000000000..3de51afe7 --- /dev/null +++ b/pkg/morph/client/mtls.go @@ -0,0 +1,22 @@ +package client + +import ( + "crypto/tls" + + "github.com/nspcc-dev/neo-go/pkg/rpcclient" +) + +// MTLSConfig represents endpoint mTLS configuration. +type MTLSConfig struct { + TrustedCAList []string + KeyFile string + CertFile string +} + +func (m *MTLSConfig) parse() (*tls.Config, error) { + if m == nil { + return nil, nil + } + + return rpcclient.TLSClientConfig(m.TrustedCAList, m.CertFile, m.KeyFile) +} diff --git a/pkg/morph/client/multi.go b/pkg/morph/client/multi.go index 25ec626d1..10ed21582 100644 --- a/pkg/morph/client/multi.go +++ b/pkg/morph/client/multi.go @@ -11,8 +11,9 @@ import ( // Endpoint represents morph endpoint together with its priority. type Endpoint struct { - Address string - Priority int + Address string + Priority int + MTLSConfig *MTLSConfig } type endpoints struct { @@ -38,11 +39,11 @@ func (c *Client) SwitchRPC(ctx context.Context) bool { // Iterate endpoints in the order of decreasing priority. for c.endpoints.curr = range c.endpoints.list { - newEndpoint := c.endpoints.list[c.endpoints.curr].Address + newEndpoint := c.endpoints.list[c.endpoints.curr] cli, act, err := c.newCli(ctx, newEndpoint) if err != nil { c.logger.Warn(logs.ClientCouldNotEstablishConnectionToTheSwitchedRPCNode, - zap.String("endpoint", newEndpoint), + zap.String("endpoint", newEndpoint.Address), zap.Error(err), ) @@ -52,7 +53,7 @@ func (c *Client) SwitchRPC(ctx context.Context) bool { c.cache.invalidate() c.logger.Info(logs.ClientConnectionToTheNewRPCNodeHasBeenEstablished, - zap.String("endpoint", newEndpoint)) + zap.String("endpoint", newEndpoint.Address)) c.client = cli c.setActor(act) @@ -119,7 +120,7 @@ mainLoop: tryE := e.Address - cli, act, err := c.newCli(ctx, tryE) + cli, act, err := c.newCli(ctx, e) if err != nil { c.logger.Warn(logs.ClientCouldNotCreateClientToTheHigherPriorityNode, zap.String("endpoint", tryE),