-
Notifications
You must be signed in to change notification settings - Fork 928
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
feat(core): added support of the TLS certificates along with x-token authorisation token for the gRPC connection #3954
base: main
Are you sure you want to change the base?
Changes from all commits
c36f1cc
644dfb8
8c0f88b
50e78e8
92850d1
8514d94
06ff955
5c497e0
46b8c55
04b307b
eb5f81e
8db528f
3ce38b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,9 +8,11 @@ import ( | |
) | ||
|
||
var ( | ||
coreFlag = "core.ip" | ||
coreRPCFlag = "core.rpc.port" | ||
coreGRPCFlag = "core.grpc.port" | ||
coreFlag = "core.ip" | ||
coreRPCFlag = "core.rpc.port" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you rebase, you won't need this anymore and also won't need to specify so |
||
coreGRPCFlag = "core.grpc.port" | ||
coreTLS = "core.tls" | ||
coreXTokenPathFlag = "core.xtoken.path" //nolint:gosec | ||
) | ||
|
||
// Flags gives a set of hardcoded Core flags. | ||
|
@@ -34,6 +36,19 @@ 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( | ||
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 | ||
} | ||
|
||
|
@@ -60,6 +75,18 @@ func ParseFlags( | |
cfg.GRPCPort = grpc | ||
} | ||
|
||
enabled, err := cmd.Flags().GetBool(coreTLS) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
if enabled { | ||
cfg.TLSEnabled = true | ||
if cmd.Flag(coreXTokenPathFlag).Changed { | ||
path := cmd.Flag(coreXTokenPathFlag).Value.String() | ||
cfg.XTokenPath = path | ||
} | ||
} | ||
cfg.IP = coreIP | ||
return cfg.Validate() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package core | ||
|
||
import ( | ||
"crypto/tls" | ||
"encoding/json" | ||
"errors" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/celestiaorg/celestia-node/libs/utils" | ||
) | ||
|
||
const ( | ||
cert = "cert.pem" | ||
key = "key.pem" | ||
xtoken = "xtoken.json" | ||
) | ||
|
||
func EmptyTLSConfig() *tls.Config { | ||
return &tls.Config{MinVersion: tls.VersionTLS12} | ||
} | ||
|
||
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 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: | ||
// * 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) | ||
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 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
package state | ||
|
||
import ( | ||
"errors" | ||
"os" | ||
|
||
"github.com/cosmos/cosmos-sdk/crypto/keyring" | ||
|
||
libfraud "github.com/celestiaorg/go-fraud" | ||
|
@@ -30,14 +33,23 @@ func coreAccessor( | |
*modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader], | ||
error, | ||
) { | ||
ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, corecfg.IP, corecfg.GRPCPort, | ||
network.String(), opts...) | ||
if corecfg.TLSEnabled { | ||
// set an empty config if path is empty under `TLSEnabled=true` | ||
tlsCfg := core.EmptyTLSConfig() | ||
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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
ca, err := state.NewCoreAccessor(keyring, string(keyname), sync, | ||
corecfg.IP, corecfg.GRPCPort, network.String(), opts...) | ||
|
||
sBreaker := &modfraud.ServiceBreaker[*state.CoreAccessor, *header.ExtendedHeader]{ | ||
Service: ca, | ||
FraudType: byzantine.BadEncoding, | ||
FraudServ: fraudServ, | ||
} | ||
|
||
return ca, ca, sBreaker, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this if we just provide a TLSPath?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we need it for a use case when we have to provide an empty config.