From d187ddd206bde77664dd4df7309120257d8099fc Mon Sep 17 00:00:00 2001 From: Joshua Foster Date: Mon, 4 Nov 2024 23:25:34 -0500 Subject: [PATCH 1/9] initial POC for grpc tls --- nodebuilder/core/config.go | 7 ++++--- nodebuilder/core/flags.go | 17 ++++++++++++--- nodebuilder/state/core.go | 3 +-- state/core_access.go | 43 +++++++++++++++++++------------------- state/core_access_test.go | 2 +- state/integration_test.go | 2 +- 6 files changed, 43 insertions(+), 31 deletions(-) diff --git a/nodebuilder/core/config.go b/nodebuilder/core/config.go index b82be1d809..038239a68c 100644 --- a/nodebuilder/core/config.go +++ b/nodebuilder/core/config.go @@ -16,9 +16,10 @@ var MetricsEnabled bool // Config combines all configuration fields for managing the relationship with a Core node. type Config struct { - IP string - RPCPort string - GRPCPort string + IP string + RPCPort string + GRPCPort string + EnableTLS bool } // DefaultConfig returns default configuration for managing the diff --git a/nodebuilder/core/flags.go b/nodebuilder/core/flags.go index 127ee5ee60..ec693e1465 100644 --- a/nodebuilder/core/flags.go +++ b/nodebuilder/core/flags.go @@ -8,9 +8,10 @@ import ( ) var ( - coreFlag = "core.ip" - coreRPCFlag = "core.rpc.port" - coreGRPCFlag = "core.grpc.port" + coreFlag = "core.ip" + coreRPCFlag = "core.rpc.port" + coreGRPCFlag = "core.grpc.port" + coreEnableTLSFlag = "core.grpc.tls" ) // Flags gives a set of hardcoded Core flags. @@ -34,6 +35,11 @@ func Flags() *flag.FlagSet { DefaultGRPCPort, "Set a custom gRPC port for the core node connection. The --core.ip flag must also be provided.", ) + flags.Bool( + coreEnableTLSFlag, + false, + "Enables grpc TLS. The --core.ip flag must also be provided.", + ) return flags } @@ -60,6 +66,11 @@ func ParseFlags( cfg.GRPCPort = grpc } + if cmd.Flag(coreEnableTLSFlag).Changed { + enabled := cmd.Flag(coreEnableTLSFlag).Value.String() == "true" + cfg.EnableTLS = enabled + } + cfg.IP = coreIP return cfg.Validate() } diff --git a/nodebuilder/state/core.go b/nodebuilder/state/core.go index 39ab732368..d2febebdc5 100644 --- a/nodebuilder/state/core.go +++ b/nodebuilder/state/core.go @@ -30,8 +30,7 @@ func coreAccessor( *modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader], error, ) { - ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, - network.String(), opts...) + ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, corecfg.EnableTLS, network.String(), opts...) sBreaker := &modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader]{ Service: ca, diff --git a/state/core_access.go b/state/core_access.go index a363577b1c..af0798b0bc 100644 --- a/state/core_access.go +++ b/state/core_access.go @@ -2,11 +2,18 @@ package state import ( "context" + "crypto/tls" "errors" "fmt" "sync" "time" + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/encoding" + apperrors "github.com/celestiaorg/celestia-app/v3/app/errors" + "github.com/celestiaorg/celestia-app/v3/pkg/user" + libhead "github.com/celestiaorg/go-header" + libshare "github.com/celestiaorg/go-square/v2/share" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -20,15 +27,9 @@ import ( "github.com/tendermint/tendermint/proto/tendermint/crypto" "google.golang.org/grpc" "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" - "github.com/celestiaorg/celestia-app/v3/app" - "github.com/celestiaorg/celestia-app/v3/app/encoding" - apperrors "github.com/celestiaorg/celestia-app/v3/app/errors" - "github.com/celestiaorg/celestia-app/v3/pkg/user" - libhead "github.com/celestiaorg/go-header" - libshare "github.com/celestiaorg/go-square/v2/share" - "github.com/celestiaorg/celestia-node/header" ) @@ -67,10 +68,11 @@ type CoreAccessor struct { prt *merkle.ProofRuntime - coreConn *grpc.ClientConn - coreIP string - grpcPort string - network string + coreConn *grpc.ClientConn + coreIP string + grpcPort string + enableTLS bool + network string // these fields are mutatable and thus need to be protected by a mutex lock sync.Mutex @@ -86,15 +88,7 @@ type CoreAccessor struct { // NewCoreAccessor dials the given celestia-core endpoint and // constructs and returns a new CoreAccessor (state service) with the active // connection. -func NewCoreAccessor( - keyring keyring.Keyring, - keyname string, - getter libhead.Head[*header.ExtendedHeader], - coreIP, - grpcPort string, - network string, - options ...Option, -) (*CoreAccessor, error) { +func NewCoreAccessor(keyring keyring.Keyring, keyname string, getter libhead.Head[*header.ExtendedHeader], coreIP, grpcPort string, enableTLS bool, network string, options ...Option) (*CoreAccessor, error) { // create verifier prt := merkle.DefaultProofRuntime() prt.RegisterOpDecoder(storetypes.ProofOpIAVLCommitment, storetypes.CommitmentOpDecoder) @@ -106,6 +100,7 @@ func NewCoreAccessor( getter: getter, coreIP: coreIP, grpcPort: grpcPort, + enableTLS: enableTLS, prt: prt, network: network, } @@ -124,9 +119,15 @@ func (ca *CoreAccessor) Start(ctx context.Context) error { // dial given celestia-core endpoint endpoint := fmt.Sprintf("%s:%s", ca.coreIP, ca.grpcPort) + grpcOpts := make([]grpc.DialOption, 0) + if ca.enableTLS { + grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) + } else { + grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) + } client, err := grpc.NewClient( endpoint, - grpc.WithTransportCredentials(insecure.NewCredentials()), + grpcOpts..., ) if err != nil { return err diff --git a/state/core_access_test.go b/state/core_access_test.go index c487944749..1a456c402d 100644 --- a/state/core_access_test.go +++ b/state/core_access_test.go @@ -264,7 +264,7 @@ func buildAccessor(t *testing.T) (*CoreAccessor, []string) { WithAppCreator(appCreator) // needed until https://github.com/celestiaorg/celestia-app/pull/3680 merges cctx, _, grpcAddr := testnode.NewNetwork(t, config) - ca, err := NewCoreAccessor(cctx.Keyring, accounts[0].Name, nil, "127.0.0.1", extractPort(grpcAddr), chainID) + ca, err := NewCoreAccessor(cctx.Keyring, accounts[0].Name, nil, "127.0.0.1", extractPort(grpcAddr), false, chainID) require.NoError(t, err) return ca, getNames(accounts) } diff --git a/state/integration_test.go b/state/integration_test.go index 8680b4d181..620b7e8987 100644 --- a/state/integration_test.go +++ b/state/integration_test.go @@ -52,7 +52,7 @@ func (s *IntegrationTestSuite) SetupSuite() { s.Require().Greater(len(s.accounts), 0) accountName := s.accounts[0].Name - accessor, err := NewCoreAccessor(s.cctx.Keyring, accountName, localHeader{s.cctx.Client}, "", "", "") + accessor, err := NewCoreAccessor(s.cctx.Keyring, accountName, localHeader{s.cctx.Client}, "", "", false, "") require.NoError(s.T(), err) setClients(accessor, s.cctx.GRPCClient) s.accessor = accessor From e0f0fd34a8be6d9e4709278fa4d7add890641abb Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Wed, 6 Nov 2024 13:29:31 +0200 Subject: [PATCH 2/9] minor improvements to 3917 --- nodebuilder/core/tls.go | 39 +++++++++++++++++++++++++++++++++++++++ nodebuilder/state/core.go | 9 ++++++++- state/core_access.go | 32 ++++++++++++++++++++------------ state/core_access_test.go | 2 +- state/integration_test.go | 2 +- 5 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 nodebuilder/core/tls.go diff --git a/nodebuilder/core/tls.go b/nodebuilder/core/tls.go new file mode 100644 index 0000000000..3774a77ae1 --- /dev/null +++ b/nodebuilder/core/tls.go @@ -0,0 +1,39 @@ +package core + +import ( + "crypto/tls" + "github.com/celestiaorg/celestia-node/libs/utils" + "os" + "path/filepath" +) + +const ( + cert = "cert.pem" + key = "key.pem" +) + +var tlsPath = "CELESTIA_GRPC_TLS_PATH" + +// TLS tries to read `CELESTIA_GRPC_TLS_PATH` to get the tls path and configure the config +// with build certificate. In returns an empty config in case the path hasn't specified. +func TLS() (*tls.Config, error) { + cfg := &tls.Config{MinVersion: tls.VersionTLS12} + path := os.Getenv(tlsPath) + if path == "" { + return cfg, nil + } + + certPath := filepath.Join(path, cert) + keyPath := filepath.Join(path, key) + exist := utils.Exists(certPath) && utils.Exists(keyPath) + if !exist { + return cfg, nil + } + + cert, err := tls.LoadX509KeyPair(certPath, keyPath) + if err != nil { + return nil, err + } + cfg.Certificates = append(cfg.Certificates, cert) + return cfg, nil +} diff --git a/nodebuilder/state/core.go b/nodebuilder/state/core.go index d2febebdc5..4fc729e6ac 100644 --- a/nodebuilder/state/core.go +++ b/nodebuilder/state/core.go @@ -30,7 +30,14 @@ func coreAccessor( *modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader], error, ) { - ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, corecfg.EnableTLS, network.String(), opts...) + if corecfg.EnableTLS { + tls, err := core.TLS() + if err != nil { + return nil, nil, nil, err + } + opts = append(opts, state.WithTLSConfig(tls)) + } + ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, network.String(), opts...) sBreaker := &modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader]{ Service: ca, diff --git a/state/core_access.go b/state/core_access.go index af0798b0bc..86712fd21f 100644 --- a/state/core_access.go +++ b/state/core_access.go @@ -47,6 +47,12 @@ var ( // to configure parameters. type Option func(ca *CoreAccessor) +func WithTLSConfig(cfg *tls.Config) Option { + return func(ca *CoreAccessor) { + ca.tls = cfg + } +} + // CoreAccessor implements service over a gRPC connection // with a celestia-core node. type CoreAccessor struct { @@ -68,11 +74,12 @@ type CoreAccessor struct { prt *merkle.ProofRuntime - coreConn *grpc.ClientConn - coreIP string - grpcPort string - enableTLS bool - network string + coreConn *grpc.ClientConn + coreIP string + grpcPort string + network string + + tls *tls.Config // these fields are mutatable and thus need to be protected by a mutex lock sync.Mutex @@ -88,7 +95,7 @@ type CoreAccessor struct { // NewCoreAccessor dials the given celestia-core endpoint and // constructs and returns a new CoreAccessor (state service) with the active // connection. -func NewCoreAccessor(keyring keyring.Keyring, keyname string, getter libhead.Head[*header.ExtendedHeader], coreIP, grpcPort string, enableTLS bool, network string, options ...Option) (*CoreAccessor, error) { +func NewCoreAccessor(keyring keyring.Keyring, keyname string, getter libhead.Head[*header.ExtendedHeader], coreIP, grpcPort string, network string, options ...Option) (*CoreAccessor, error) { // create verifier prt := merkle.DefaultProofRuntime() prt.RegisterOpDecoder(storetypes.ProofOpIAVLCommitment, storetypes.CommitmentOpDecoder) @@ -100,7 +107,6 @@ func NewCoreAccessor(keyring keyring.Keyring, keyname string, getter libhead.Hea getter: getter, coreIP: coreIP, grpcPort: grpcPort, - enableTLS: enableTLS, prt: prt, network: network, } @@ -119,16 +125,18 @@ func (ca *CoreAccessor) Start(ctx context.Context) error { // dial given celestia-core endpoint endpoint := fmt.Sprintf("%s:%s", ca.coreIP, ca.grpcPort) - grpcOpts := make([]grpc.DialOption, 0) - if ca.enableTLS { - grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) + + var creds credentials.TransportCredentials + if ca.tls != nil { + creds = credentials.NewTLS(ca.tls) } else { - grpcOpts = append(grpcOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) + creds = insecure.NewCredentials() } client, err := grpc.NewClient( endpoint, - grpcOpts..., + grpc.WithTransportCredentials(creds), ) + if err != nil { return err } diff --git a/state/core_access_test.go b/state/core_access_test.go index 1a456c402d..c487944749 100644 --- a/state/core_access_test.go +++ b/state/core_access_test.go @@ -264,7 +264,7 @@ func buildAccessor(t *testing.T) (*CoreAccessor, []string) { WithAppCreator(appCreator) // needed until https://github.com/celestiaorg/celestia-app/pull/3680 merges cctx, _, grpcAddr := testnode.NewNetwork(t, config) - ca, err := NewCoreAccessor(cctx.Keyring, accounts[0].Name, nil, "127.0.0.1", extractPort(grpcAddr), false, chainID) + ca, err := NewCoreAccessor(cctx.Keyring, accounts[0].Name, nil, "127.0.0.1", extractPort(grpcAddr), chainID) require.NoError(t, err) return ca, getNames(accounts) } diff --git a/state/integration_test.go b/state/integration_test.go index 620b7e8987..8680b4d181 100644 --- a/state/integration_test.go +++ b/state/integration_test.go @@ -52,7 +52,7 @@ func (s *IntegrationTestSuite) SetupSuite() { s.Require().Greater(len(s.accounts), 0) accountName := s.accounts[0].Name - accessor, err := NewCoreAccessor(s.cctx.Keyring, accountName, localHeader{s.cctx.Client}, "", "", false, "") + accessor, err := NewCoreAccessor(s.cctx.Keyring, accountName, localHeader{s.cctx.Client}, "", "", "") require.NoError(s.T(), err) setClients(accessor, s.cctx.GRPCClient) s.accessor = accessor From 5cb7bbeffc2b20eb871eac8ac11a513caf59db3c Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Wed, 6 Nov 2024 15:28:58 +0200 Subject: [PATCH 3/9] extend config with tls path field --- nodebuilder/core/config.go | 2 +- nodebuilder/core/flags.go | 11 +++++++++++ nodebuilder/core/tls.go | 26 +++++++++++++------------- nodebuilder/state/core.go | 5 +++-- state/core_access.go | 23 +++++++++++++++-------- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/nodebuilder/core/config.go b/nodebuilder/core/config.go index 038239a68c..4146890e80 100644 --- a/nodebuilder/core/config.go +++ b/nodebuilder/core/config.go @@ -20,13 +20,13 @@ type Config struct { RPCPort string GRPCPort string EnableTLS bool + TLSPath string } // DefaultConfig returns default configuration for managing the // node's connection to a Celestia-Core endpoint. func DefaultConfig() Config { return Config{ - IP: "", RPCPort: DefaultRPCPort, GRPCPort: DefaultGRPCPort, } diff --git a/nodebuilder/core/flags.go b/nodebuilder/core/flags.go index ec693e1465..e76202380b 100644 --- a/nodebuilder/core/flags.go +++ b/nodebuilder/core/flags.go @@ -12,6 +12,7 @@ var ( coreRPCFlag = "core.rpc.port" coreGRPCFlag = "core.grpc.port" coreEnableTLSFlag = "core.grpc.tls" + coreTLSPAthFlag = "core.grpc.tls.path" ) // Flags gives a set of hardcoded Core flags. @@ -40,6 +41,11 @@ func Flags() *flag.FlagSet { false, "Enables grpc TLS. The --core.ip flag must also be provided.", ) + flags.String( + coreTLSPAthFlag, + "", + fmt.Sprintf("Set a path to the TLS certificates. The --%s must be set to true ", coreEnableTLSFlag), + ) return flags } @@ -71,6 +77,11 @@ func ParseFlags( cfg.EnableTLS = enabled } + if cmd.Flag(coreTLSPAthFlag).Changed { + path := cmd.Flag(coreTLSPAthFlag).Value.String() + cfg.TLSPath = path + } + cfg.IP = coreIP return cfg.Validate() } diff --git a/nodebuilder/core/tls.go b/nodebuilder/core/tls.go index 3774a77ae1..202cc143c0 100644 --- a/nodebuilder/core/tls.go +++ b/nodebuilder/core/tls.go @@ -2,9 +2,10 @@ package core import ( "crypto/tls" - "github.com/celestiaorg/celestia-node/libs/utils" - "os" + "fmt" "path/filepath" + + "github.com/celestiaorg/celestia-node/libs/utils" ) const ( @@ -12,22 +13,21 @@ const ( key = "key.pem" ) -var tlsPath = "CELESTIA_GRPC_TLS_PATH" - -// TLS tries to read `CELESTIA_GRPC_TLS_PATH` to get the tls path and configure the config -// with build certificate. In returns an empty config in case the path hasn't specified. -func TLS() (*tls.Config, error) { +// TLS parses the tls path and tries to configure the config with tls certificates. +// In returns an empty config in case the path was not specified. +func TLS(tlsPath string) (*tls.Config, error) { cfg := &tls.Config{MinVersion: tls.VersionTLS12} - path := os.Getenv(tlsPath) - if path == "" { + if tlsPath == "" { return cfg, nil } - - certPath := filepath.Join(path, cert) - keyPath := filepath.Join(path, key) + certPath := filepath.Join(tlsPath, cert) + keyPath := filepath.Join(tlsPath, key) exist := utils.Exists(certPath) && utils.Exists(keyPath) if !exist { - return cfg, nil + return nil, fmt.Errorf("can't find %s or %s under %s"+ + "Please specify another path or disable tls in the config", + cert, key, tlsPath, + ) } cert, err := tls.LoadX509KeyPair(certPath, keyPath) diff --git a/nodebuilder/state/core.go b/nodebuilder/state/core.go index 4fc729e6ac..d642b20102 100644 --- a/nodebuilder/state/core.go +++ b/nodebuilder/state/core.go @@ -31,13 +31,14 @@ func coreAccessor( error, ) { if corecfg.EnableTLS { - tls, err := core.TLS() + tls, err := core.TLS(corecfg.TLSPath) if err != nil { return nil, nil, nil, err } opts = append(opts, state.WithTLSConfig(tls)) } - ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, network.String(), opts...) + ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, + corecfg.IP, corecfg.GRPCPort, network.String(), opts...) sBreaker := &modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader]{ Service: ca, diff --git a/state/core_access.go b/state/core_access.go index 86712fd21f..ff9077defe 100644 --- a/state/core_access.go +++ b/state/core_access.go @@ -8,12 +8,6 @@ import ( "sync" "time" - "github.com/celestiaorg/celestia-app/v3/app" - "github.com/celestiaorg/celestia-app/v3/app/encoding" - apperrors "github.com/celestiaorg/celestia-app/v3/app/errors" - "github.com/celestiaorg/celestia-app/v3/pkg/user" - libhead "github.com/celestiaorg/go-header" - libshare "github.com/celestiaorg/go-square/v2/share" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/crypto/keyring" @@ -30,6 +24,13 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/encoding" + apperrors "github.com/celestiaorg/celestia-app/v3/app/errors" + "github.com/celestiaorg/celestia-app/v3/pkg/user" + libhead "github.com/celestiaorg/go-header" + libshare "github.com/celestiaorg/go-square/v2/share" + "github.com/celestiaorg/celestia-node/header" ) @@ -95,7 +96,13 @@ type CoreAccessor struct { // NewCoreAccessor dials the given celestia-core endpoint and // constructs and returns a new CoreAccessor (state service) with the active // connection. -func NewCoreAccessor(keyring keyring.Keyring, keyname string, getter libhead.Head[*header.ExtendedHeader], coreIP, grpcPort string, network string, options ...Option) (*CoreAccessor, error) { +func NewCoreAccessor( + keyring keyring.Keyring, + keyname string, + getter libhead.Head[*header.ExtendedHeader], + coreIP, grpcPort, network string, + options ...Option, +) (*CoreAccessor, error) { // create verifier prt := merkle.DefaultProofRuntime() prt.RegisterOpDecoder(storetypes.ProofOpIAVLCommitment, storetypes.CommitmentOpDecoder) @@ -132,11 +139,11 @@ func (ca *CoreAccessor) Start(ctx context.Context) error { } else { creds = insecure.NewCredentials() } + client, err := grpc.NewClient( endpoint, grpc.WithTransportCredentials(creds), ) - if err != nil { return err } From 1117237244b6d3b8cc390491cd695306b635a3f9 Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Mon, 11 Nov 2024 15:01:21 +0200 Subject: [PATCH 4/9] feat(grpc): enable grpc connection with x-token auth token --- nodebuilder/core/config.go | 16 ++++--- nodebuilder/core/flags.go | 40 ++++++++++-------- nodebuilder/core/tls.go | 46 ++++++++++++++++----- nodebuilder/state/core.go | 19 ++++++--- state/core_access.go | 85 +++++++++++++++++++++++++++----------- 5 files changed, 142 insertions(+), 64 deletions(-) diff --git a/nodebuilder/core/config.go b/nodebuilder/core/config.go index 4146890e80..843423f9a0 100644 --- a/nodebuilder/core/config.go +++ b/nodebuilder/core/config.go @@ -16,11 +16,17 @@ var MetricsEnabled bool // Config combines all configuration fields for managing the relationship with a Core node. type Config struct { - IP string - RPCPort string - GRPCPort string - EnableTLS bool - TLSPath string + IP string + RPCPort string + GRPCPort string + // TLSPath specifies the directory path where the TLS certificates are stored. + // It should not include file names('cert.pem' and 'key.pem'). + // If left empty, the client will be configured for an insecure (non-TLS) connection. + TLSPath string + // XTokenPath specifies the file path to the JSON file containing the X-Token for gRPC authentication. + // The JSON file should have a key-value pair where the key is "x-token" and the value is the authentication token. + // If left empty, the client will not include the X-Token in its requests. + XTokenPath string } // DefaultConfig returns default configuration for managing the diff --git a/nodebuilder/core/flags.go b/nodebuilder/core/flags.go index e76202380b..c34facf901 100644 --- a/nodebuilder/core/flags.go +++ b/nodebuilder/core/flags.go @@ -8,11 +8,11 @@ import ( ) var ( - coreFlag = "core.ip" - coreRPCFlag = "core.rpc.port" - coreGRPCFlag = "core.grpc.port" - coreEnableTLSFlag = "core.grpc.tls" - coreTLSPAthFlag = "core.grpc.tls.path" + coreFlag = "core.ip" + coreRPCFlag = "core.rpc.port" + coreGRPCFlag = "core.grpc.port" + coreTLSPathFlag = "core.grpc.tls.path" + coreXTokenPathFlag = "core.grpc.xtoken.path" ) // Flags gives a set of hardcoded Core flags. @@ -36,15 +36,20 @@ func Flags() *flag.FlagSet { DefaultGRPCPort, "Set a custom gRPC port for the core node connection. The --core.ip flag must also be provided.", ) - flags.Bool( - coreEnableTLSFlag, - false, - "Enables grpc TLS. The --core.ip flag must also be provided.", + flags.String( + coreTLSPathFlag, + "", + "specifies the directory path where the TLS certificates are stored. "+ + "It should not include file names ('cert.pem' and 'key.pem'). "+ + "If left empty, the client will be configured for an insecure (non-TLS) connection", ) + flags.String( - coreTLSPAthFlag, + coreXTokenPathFlag, "", - fmt.Sprintf("Set a path to the TLS certificates. The --%s must be set to true ", coreEnableTLSFlag), + "specifies the file path to the JSON file containing the X-Token for gRPC authentication. "+ + "The JSON file should have a key-value pair where the key is 'x-token' and the value is the authentication token. "+ + "If left empty, the client will not include the X-Token in its requests.", ) return flags } @@ -72,16 +77,15 @@ func ParseFlags( cfg.GRPCPort = grpc } - if cmd.Flag(coreEnableTLSFlag).Changed { - enabled := cmd.Flag(coreEnableTLSFlag).Value.String() == "true" - cfg.EnableTLS = enabled - } - - if cmd.Flag(coreTLSPAthFlag).Changed { - path := cmd.Flag(coreTLSPAthFlag).Value.String() + if cmd.Flag(coreTLSPathFlag).Changed { + path := cmd.Flag(coreTLSPathFlag).Value.String() cfg.TLSPath = path } + if cmd.Flag(coreXTokenPathFlag).Changed { + path := cmd.Flag(coreXTokenPathFlag).Value.String() + cfg.XTokenPath = path + } cfg.IP = coreIP return cfg.Validate() } diff --git a/nodebuilder/core/tls.go b/nodebuilder/core/tls.go index 202cc143c0..8cb0d2bce6 100644 --- a/nodebuilder/core/tls.go +++ b/nodebuilder/core/tls.go @@ -2,34 +2,31 @@ package core import ( "crypto/tls" - "fmt" + "encoding/json" + "errors" + "os" "path/filepath" "github.com/celestiaorg/celestia-node/libs/utils" ) const ( - cert = "cert.pem" - key = "key.pem" + cert = "cert.pem" + key = "key.pem" + xtoken = "xtoken.json" ) // TLS parses the tls path and tries to configure the config with tls certificates. // In returns an empty config in case the path was not specified. func TLS(tlsPath string) (*tls.Config, error) { - cfg := &tls.Config{MinVersion: tls.VersionTLS12} - if tlsPath == "" { - return cfg, nil - } certPath := filepath.Join(tlsPath, cert) keyPath := filepath.Join(tlsPath, key) exist := utils.Exists(certPath) && utils.Exists(keyPath) if !exist { - return nil, fmt.Errorf("can't find %s or %s under %s"+ - "Please specify another path or disable tls in the config", - cert, key, tlsPath, - ) + return nil, os.ErrNotExist } + cfg := &tls.Config{MinVersion: tls.VersionTLS12} cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { return nil, err @@ -37,3 +34,30 @@ func TLS(tlsPath string) (*tls.Config, error) { cfg.Certificates = append(cfg.Certificates, cert) return cfg, nil } + +type AuthToken struct { + Token string `json:"x-token"` +} + +func XToken(xtokenPath string) (string, error) { + xtokenPath = filepath.Join(xtokenPath, xtoken) + exist := utils.Exists(xtokenPath) + if !exist { + return "", os.ErrNotExist + } + + token, err := os.ReadFile(xtokenPath) + if err != nil { + return "", err + } + + var auth AuthToken + err = json.Unmarshal(token, &auth) + if err != nil { + return "", err + } + if auth.Token == "" { + return "", errors.New("x-token is empty. Please setup a token or cleanup xtokenPath") + } + return auth.Token, nil +} diff --git a/nodebuilder/state/core.go b/nodebuilder/state/core.go index d642b20102..8d48aa0bcf 100644 --- a/nodebuilder/state/core.go +++ b/nodebuilder/state/core.go @@ -1,6 +1,9 @@ package state import ( + "errors" + "os" + "github.com/cosmos/cosmos-sdk/crypto/keyring" libfraud "github.com/celestiaorg/go-fraud" @@ -30,13 +33,17 @@ func coreAccessor( *modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader], error, ) { - if corecfg.EnableTLS { - tls, err := core.TLS(corecfg.TLSPath) - if err != nil { - return nil, nil, nil, err - } - opts = append(opts, state.WithTLSConfig(tls)) + + tls, err := core.TLS(corecfg.TLSPath) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, nil, nil, err } + xtoken, err := core.XToken(corecfg.XTokenPath) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, nil, nil, err + } + + opts = append(opts, state.WithTLSConfig(tls), state.WithXToken(xtoken)) ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, network.String(), opts...) diff --git a/state/core_access.go b/state/core_access.go index ff9077defe..ede741e238 100644 --- a/state/core_access.go +++ b/state/core_access.go @@ -23,6 +23,7 @@ import ( "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/metadata" "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" @@ -54,6 +55,12 @@ func WithTLSConfig(cfg *tls.Config) Option { } } +func WithXToken(xtoken string) Option { + return func(ca *CoreAccessor) { + ca.xtoken = xtoken + } +} + // CoreAccessor implements service over a gRPC connection // with a celestia-core node. type CoreAccessor struct { @@ -80,7 +87,8 @@ type CoreAccessor struct { grpcPort string network string - tls *tls.Config + tls *tls.Config + xtoken string // these fields are mutatable and thus need to be protected by a mutex lock sync.Mutex @@ -130,32 +138,11 @@ func (ca *CoreAccessor) Start(ctx context.Context) error { } ca.ctx, ca.cancel = context.WithCancel(context.Background()) - // dial given celestia-core endpoint - endpoint := fmt.Sprintf("%s:%s", ca.coreIP, ca.grpcPort) - - var creds credentials.TransportCredentials - if ca.tls != nil { - creds = credentials.NewTLS(ca.tls) - } else { - creds = insecure.NewCredentials() - } - - client, err := grpc.NewClient( - endpoint, - grpc.WithTransportCredentials(creds), - ) + err := ca.startGRPCClient(ctx) if err != nil { - return err - } - // this ensures we can't start the node without core connection - client.Connect() - if !client.WaitForStateChange(ctx, connectivity.Ready) { - // hits the case when context is canceled - return fmt.Errorf("couldn't connect to core endpoint(%s): %w", endpoint, ctx.Err()) + return fmt.Errorf("failed to start grpc client: %w", err) } - ca.coreConn = client - // create the staking query client ca.stakingCli = stakingtypes.NewQueryClient(ca.coreConn) ca.feeGrantCli = feegrant.NewQueryClient(ca.coreConn) @@ -617,6 +604,56 @@ func (ca *CoreAccessor) setupTxClient(ctx context.Context, keyName string) (*use ) } +func (ca *CoreAccessor) startGRPCClient(ctx context.Context) error { + // dial given celestia-core endpoint + endpoint := fmt.Sprintf("%s:%s", ca.coreIP, ca.grpcPort) + // By default, the gRPC client is configured to handle an insecure connection. + // If the TLS configuration is not empty, it will be applied to the client's options. + // If the TLS configuration is empty but the X-Token is provided, + // the X-Token will be applied as an interceptor along with an empty TLS configuration. + opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} + if ca.tls != nil { + fmt.Println("TRANSPORT") + opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(ca.tls))) + } else if ca.xtoken != "" { + fmt.Println("TOKEN") + authInterceptor := func(ctx context.Context, + method string, + req, reply interface{}, + cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, + opts ...grpc.CallOption) error { + ctx = metadata.AppendToOutgoingContext(ctx, "x-token", ca.xtoken) + return invoker(ctx, method, req, reply, cc, opts...) + } + // set the config with empty certificates along with the interceptor that will add x-token. + opts = append(opts, + grpc.WithTransportCredentials( + credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12}), + ), + grpc.WithUnaryInterceptor(authInterceptor), + ) + } + + client, err := grpc.NewClient( + endpoint, + opts..., + ) + if err != nil { + return err + } + // this ensures we can't start the node without core connection + client.Connect() + if !client.WaitForStateChange(ctx, connectivity.Ready) { + // hits the case when context is canceled + return fmt.Errorf("couldn't connect to core endpoint(%s): %w", endpoint, ctx.Err()) + } + ca.coreConn = client + + log.Infof("Connection with core endpoint(%s) established", endpoint) + return nil +} + func (ca *CoreAccessor) submitMsg( ctx context.Context, msg sdktypes.Msg, From 414fa5c8b54947800a0be8ea3c13bf60e8e872c2 Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Mon, 11 Nov 2024 15:06:51 +0200 Subject: [PATCH 5/9] improve godoc --- nodebuilder/core/tls.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/nodebuilder/core/tls.go b/nodebuilder/core/tls.go index 8cb0d2bce6..deabefb428 100644 --- a/nodebuilder/core/tls.go +++ b/nodebuilder/core/tls.go @@ -16,8 +16,16 @@ const ( xtoken = "xtoken.json" ) -// TLS parses the tls path and tries to configure the config with tls certificates. -// In returns an empty config in case the path was not specified. +// TLS creates a TLS configuration using the certificate and key files from the specified path. +// It constructs the full paths to the certificate and key files by joining the provided directory path +// with their respective file names. +// If either file is missing, it returns an os.ErrNotExist error. +// If the files exist, it loads the X.509 key pair from the specified files and sets up a tls.Config with a minimum version of TLS 1.2. +// Parameters: +// * tlsPath: The directory path where the TLS certificate ("cert.pem") and key ("key.pem") files are located. +// Returns: +// * A tls.Config structure configured with the provided certificate and key. +// * An error if the certificate or key file does not exist, or if loading the key pair fails. func TLS(tlsPath string) (*tls.Config, error) { certPath := filepath.Join(tlsPath, cert) keyPath := filepath.Join(tlsPath, key) @@ -39,6 +47,16 @@ type AuthToken struct { Token string `json:"x-token"` } +// XToken retrieves the authentication token from a JSON file at the specified path. +// It first constructs the full file path by joining the provided directory path with the token file name. +// If the file does not exist, it returns an os.ErrNotExist error. +// If the file exists, it reads the content and unmarshals it. +// If the field in the unmarshaled struct is empty, an error is returned indicating that the token is missing. +// Parameters: +// * xtokenPath: The directory path where the JSON file containing the X-Token is located. +// Returns: +// * The X-Token as a string if successfully retrieved. +// * An error if the file does not exist, reading fails, unmarshalling fails, or the token is empty. func XToken(xtokenPath string) (string, error) { xtokenPath = filepath.Join(xtokenPath, xtoken) exist := utils.Exists(xtokenPath) From 3829eebfae43431d588f4f40941bb06bb50be984 Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Mon, 11 Nov 2024 15:55:54 +0200 Subject: [PATCH 6/9] fix lint --- nodebuilder/core/flags.go | 3 +-- nodebuilder/core/tls.go | 3 ++- nodebuilder/state/core.go | 2 -- state/core_access.go | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/nodebuilder/core/flags.go b/nodebuilder/core/flags.go index c34facf901..b501155b0c 100644 --- a/nodebuilder/core/flags.go +++ b/nodebuilder/core/flags.go @@ -12,7 +12,7 @@ var ( coreRPCFlag = "core.rpc.port" coreGRPCFlag = "core.grpc.port" coreTLSPathFlag = "core.grpc.tls.path" - coreXTokenPathFlag = "core.grpc.xtoken.path" + coreXTokenPathFlag = "core.grpc.xtoken.path" //nolint:gosec ) // Flags gives a set of hardcoded Core flags. @@ -43,7 +43,6 @@ func Flags() *flag.FlagSet { "It should not include file names ('cert.pem' and 'key.pem'). "+ "If left empty, the client will be configured for an insecure (non-TLS) connection", ) - flags.String( coreXTokenPathFlag, "", diff --git a/nodebuilder/core/tls.go b/nodebuilder/core/tls.go index deabefb428..6ea710521b 100644 --- a/nodebuilder/core/tls.go +++ b/nodebuilder/core/tls.go @@ -20,7 +20,8 @@ const ( // It constructs the full paths to the certificate and key files by joining the provided directory path // with their respective file names. // If either file is missing, it returns an os.ErrNotExist error. -// If the files exist, it loads the X.509 key pair from the specified files and sets up a tls.Config with a minimum version of TLS 1.2. +// If the files exist, it loads the X.509 key pair from the specified files and sets up a tls.Config +// with a minimum version of TLS 1.2. // Parameters: // * tlsPath: The directory path where the TLS certificate ("cert.pem") and key ("key.pem") files are located. // Returns: diff --git a/nodebuilder/state/core.go b/nodebuilder/state/core.go index 8d48aa0bcf..239b2a2abb 100644 --- a/nodebuilder/state/core.go +++ b/nodebuilder/state/core.go @@ -33,7 +33,6 @@ func coreAccessor( *modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader], error, ) { - tls, err := core.TLS(corecfg.TLSPath) if err != nil && !errors.Is(err, os.ErrNotExist) { return nil, nil, nil, err @@ -52,6 +51,5 @@ func coreAccessor( FraudType: byzantine.BadEncoding, FraudServ: fraudServ, } - return ca, ca, sBreaker, err } diff --git a/state/core_access.go b/state/core_access.go index ede741e238..5c639830da 100644 --- a/state/core_access.go +++ b/state/core_access.go @@ -622,7 +622,8 @@ func (ca *CoreAccessor) startGRPCClient(ctx context.Context) error { req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, - opts ...grpc.CallOption) error { + opts ...grpc.CallOption, + ) error { ctx = metadata.AppendToOutgoingContext(ctx, "x-token", ca.xtoken) return invoker(ctx, method, req, reply, cc, opts...) } From 7bf3546930a3c4587a954961bae64597d7863429 Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Fri, 15 Nov 2024 12:57:30 +0200 Subject: [PATCH 7/9] fix comment --- nodebuilder/core/config.go | 2 +- state/core_access.go | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/nodebuilder/core/config.go b/nodebuilder/core/config.go index 843423f9a0..c3a4a77a1b 100644 --- a/nodebuilder/core/config.go +++ b/nodebuilder/core/config.go @@ -23,7 +23,7 @@ type Config struct { // It should not include file names('cert.pem' and 'key.pem'). // If left empty, the client will be configured for an insecure (non-TLS) connection. TLSPath string - // XTokenPath specifies the file path to the JSON file containing the X-Token for gRPC authentication. + // XTokenPath specifies the path to the directory with JSON file containing the X-Token for gRPC authentication. // The JSON file should have a key-value pair where the key is "x-token" and the value is the authentication token. // If left empty, the client will not include the X-Token in its requests. XTokenPath string diff --git a/state/core_access.go b/state/core_access.go index 5c639830da..0cc9a00031 100644 --- a/state/core_access.go +++ b/state/core_access.go @@ -613,10 +613,8 @@ func (ca *CoreAccessor) startGRPCClient(ctx context.Context) error { // the X-Token will be applied as an interceptor along with an empty TLS configuration. opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} if ca.tls != nil { - fmt.Println("TRANSPORT") opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(ca.tls))) } else if ca.xtoken != "" { - fmt.Println("TOKEN") authInterceptor := func(ctx context.Context, method string, req, reply interface{}, From 82c92e803a5a42e992d360189a6d348e2c46de41 Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Tue, 19 Nov 2024 11:26:02 +0200 Subject: [PATCH 8/9] add core.TLSEnabled --- nodebuilder/core/config.go | 3 +++ nodebuilder/core/flags.go | 31 ++++++++++++++++++++++++------- nodebuilder/core/tls.go | 9 ++++----- nodebuilder/state/core.go | 27 ++++++++++++++++++--------- state/core_access.go | 11 +++-------- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/nodebuilder/core/config.go b/nodebuilder/core/config.go index c3a4a77a1b..9ca72b0b9c 100644 --- a/nodebuilder/core/config.go +++ b/nodebuilder/core/config.go @@ -19,6 +19,9 @@ type Config struct { IP string RPCPort string GRPCPort string + // TLSEnabled specifies whether the connection is secure or not. + // PLEASE NOTE: it should be set to true in order to handle TLSPath and/or XTokenPath. + TLSEnabled bool // TLSPath specifies the directory path where the TLS certificates are stored. // It should not include file names('cert.pem' and 'key.pem'). // If left empty, the client will be configured for an insecure (non-TLS) connection. diff --git a/nodebuilder/core/flags.go b/nodebuilder/core/flags.go index b501155b0c..940b3d40ec 100644 --- a/nodebuilder/core/flags.go +++ b/nodebuilder/core/flags.go @@ -11,6 +11,7 @@ var ( coreFlag = "core.ip" coreRPCFlag = "core.rpc.port" coreGRPCFlag = "core.grpc.port" + coreTLS = "core.tls" coreTLSPathFlag = "core.grpc.tls.path" coreXTokenPathFlag = "core.grpc.xtoken.path" //nolint:gosec ) @@ -36,18 +37,26 @@ func Flags() *flag.FlagSet { DefaultGRPCPort, "Set a custom gRPC port for the core node connection. The --core.ip flag must also be provided.", ) + flags.Bool( + coreTLS, + false, + "Specifies whether TLS is enabled or not. Default: false", + ) flags.String( coreTLSPathFlag, "", "specifies the directory path where the TLS certificates are stored. "+ "It should not include file names ('cert.pem' and 'key.pem'). "+ - "If left empty, the client will be configured for an insecure (non-TLS) connection", + "NOTE: the path is parsed only if coreTLS enabled."+ + "If left empty, with disabled coreTLS, the client will be configured for "+ + "an insecure (non-TLS) connection", ) flags.String( coreXTokenPathFlag, "", "specifies the file path to the JSON file containing the X-Token for gRPC authentication. "+ "The JSON file should have a key-value pair where the key is 'x-token' and the value is the authentication token. "+ + "NOTE: the path is parsed only if coreTLS enabled."+ "If left empty, the client will not include the X-Token in its requests.", ) return flags @@ -76,14 +85,22 @@ func ParseFlags( cfg.GRPCPort = grpc } - if cmd.Flag(coreTLSPathFlag).Changed { - path := cmd.Flag(coreTLSPathFlag).Value.String() - cfg.TLSPath = path + enabled, err := cmd.Flags().GetBool(coreTLS) + if err != nil { + panic(err) } - if cmd.Flag(coreXTokenPathFlag).Changed { - path := cmd.Flag(coreXTokenPathFlag).Value.String() - cfg.XTokenPath = path + if enabled { + cfg.TLSEnabled = true + if cmd.Flag(coreTLSPathFlag).Changed { + path := cmd.Flag(coreTLSPathFlag).Value.String() + cfg.TLSPath = path + } + + if cmd.Flag(coreXTokenPathFlag).Changed { + path := cmd.Flag(coreXTokenPathFlag).Value.String() + cfg.XTokenPath = path + } } cfg.IP = coreIP return cfg.Validate() diff --git a/nodebuilder/core/tls.go b/nodebuilder/core/tls.go index 6ea710521b..3e36e898aa 100644 --- a/nodebuilder/core/tls.go +++ b/nodebuilder/core/tls.go @@ -20,8 +20,7 @@ const ( // It constructs the full paths to the certificate and key files by joining the provided directory path // with their respective file names. // If either file is missing, it returns an os.ErrNotExist error. -// If the files exist, it loads the X.509 key pair from the specified files and sets up a tls.Config -// with a minimum version of TLS 1.2. +// If the files exist, it loads the X.509 key pair from the specified files and sets up a tls.Config. // Parameters: // * tlsPath: The directory path where the TLS certificate ("cert.pem") and key ("key.pem") files are located. // Returns: @@ -35,7 +34,7 @@ func TLS(tlsPath string) (*tls.Config, error) { return nil, os.ErrNotExist } - cfg := &tls.Config{MinVersion: tls.VersionTLS12} + cfg := &tls.Config{} cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { return nil, err @@ -51,8 +50,8 @@ type AuthToken struct { // XToken retrieves the authentication token from a JSON file at the specified path. // It first constructs the full file path by joining the provided directory path with the token file name. // If the file does not exist, it returns an os.ErrNotExist error. -// If the file exists, it reads the content and unmarshals it. -// If the field in the unmarshaled struct is empty, an error is returned indicating that the token is missing. +// If the file exists, it reads the content and unmarshalls it. +// If the field in the unmarshalled struct is empty, an error is returned indicating that the token is missing. // Parameters: // * xtokenPath: The directory path where the JSON file containing the X-Token is located. // Returns: diff --git a/nodebuilder/state/core.go b/nodebuilder/state/core.go index 239b2a2abb..49aa3febf6 100644 --- a/nodebuilder/state/core.go +++ b/nodebuilder/state/core.go @@ -1,6 +1,7 @@ package state import ( + "crypto/tls" "errors" "os" @@ -33,16 +34,24 @@ func coreAccessor( *modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader], error, ) { - tls, err := core.TLS(corecfg.TLSPath) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return nil, nil, nil, err - } - xtoken, err := core.XToken(corecfg.XTokenPath) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return nil, nil, nil, err - } - opts = append(opts, state.WithTLSConfig(tls), state.WithXToken(xtoken)) + if corecfg.TLSEnabled { + tlsCfg, err := core.TLS(corecfg.TLSPath) + switch err { + case nil: + case os.ErrNotExist: + // set an empty config if path is empty under `TLSEnabled=true` + tlsCfg = &tls.Config{} + default: + return nil, nil, nil, err + } + + xtoken, err := core.XToken(corecfg.XTokenPath) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, nil, nil, err + } + opts = append(opts, state.WithTLSConfig(tlsCfg), state.WithXToken(xtoken)) + } ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, network.String(), opts...) diff --git a/state/core_access.go b/state/core_access.go index 0cc9a00031..874310d135 100644 --- a/state/core_access.go +++ b/state/core_access.go @@ -614,7 +614,8 @@ func (ca *CoreAccessor) startGRPCClient(ctx context.Context) error { opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} if ca.tls != nil { opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(ca.tls))) - } else if ca.xtoken != "" { + } + if ca.xtoken != "" { authInterceptor := func(ctx context.Context, method string, req, reply interface{}, @@ -625,13 +626,7 @@ func (ca *CoreAccessor) startGRPCClient(ctx context.Context) error { ctx = metadata.AppendToOutgoingContext(ctx, "x-token", ca.xtoken) return invoker(ctx, method, req, reply, cc, opts...) } - // set the config with empty certificates along with the interceptor that will add x-token. - opts = append(opts, - grpc.WithTransportCredentials( - credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12}), - ), - grpc.WithUnaryInterceptor(authInterceptor), - ) + opts = append(opts, grpc.WithUnaryInterceptor(authInterceptor)) } client, err := grpc.NewClient( From 06bab7b1ff9c4539fba8bef63214d842f387c526 Mon Sep 17 00:00:00 2001 From: vgonkivs Date: Tue, 19 Nov 2024 12:50:03 +0200 Subject: [PATCH 9/9] fix lint --- nodebuilder/core/tls.go | 6 +++++- nodebuilder/state/core.go | 11 +++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/nodebuilder/core/tls.go b/nodebuilder/core/tls.go index 3e36e898aa..da8b7b1267 100644 --- a/nodebuilder/core/tls.go +++ b/nodebuilder/core/tls.go @@ -16,6 +16,10 @@ const ( xtoken = "xtoken.json" ) +func EmptyTLSConfig() *tls.Config { + return &tls.Config{MinVersion: tls.VersionTLS12} +} + // TLS creates a TLS configuration using the certificate and key files from the specified path. // It constructs the full paths to the certificate and key files by joining the provided directory path // with their respective file names. @@ -34,7 +38,7 @@ func TLS(tlsPath string) (*tls.Config, error) { return nil, os.ErrNotExist } - cfg := &tls.Config{} + cfg := EmptyTLSConfig() cert, err := tls.LoadX509KeyPair(certPath, keyPath) if err != nil { return nil, err diff --git a/nodebuilder/state/core.go b/nodebuilder/state/core.go index 49aa3febf6..e32822dfc1 100644 --- a/nodebuilder/state/core.go +++ b/nodebuilder/state/core.go @@ -1,7 +1,6 @@ package state import ( - "crypto/tls" "errors" "os" @@ -34,14 +33,13 @@ func coreAccessor( *modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader], error, ) { - if corecfg.TLSEnabled { tlsCfg, err := core.TLS(corecfg.TLSPath) - switch err { - case nil: - case os.ErrNotExist: + switch { + case err == nil: + case errors.Is(err, os.ErrNotExist): // set an empty config if path is empty under `TLSEnabled=true` - tlsCfg = &tls.Config{} + tlsCfg = core.EmptyTLSConfig() default: return nil, nil, nil, err } @@ -52,6 +50,7 @@ func coreAccessor( } opts = append(opts, state.WithTLSConfig(tlsCfg), state.WithXToken(xtoken)) } + ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, network.String(), opts...)