diff --git a/command/server/config/config.go b/command/server/config/config.go index 6ec9c61824..177028d9e4 100644 --- a/command/server/config/config.go +++ b/command/server/config/config.go @@ -32,6 +32,8 @@ type Config struct { JSONRPCBlockRangeLimit uint64 `json:"json_rpc_block_range_limit" yaml:"json_rpc_block_range_limit"` JSONLogFormat bool `json:"json_log_format" yaml:"json_log_format"` CorsAllowedOrigins []string `json:"cors_allowed_origins" yaml:"cors_allowed_origins"` + TLSCertFile string `json:"tls_cert_file" yaml:"tls_cert_file"` + TLSKeyFile string `json:"tls_key_file" yaml:"tls_key_file"` Relayer bool `json:"relayer" yaml:"relayer"` @@ -144,6 +146,8 @@ func DefaultConfig() *Config { AccessControlAllowOrigins: []string{"*"}, }, LogFilePath: "", + TLSCertFile: "", + TLSKeyFile: "", JSONRPCBatchRequestLimit: DefaultJSONRPCBatchRequestLimit, JSONRPCBlockRangeLimit: DefaultJSONRPCBlockRangeLimit, Relayer: false, diff --git a/command/server/params.go b/command/server/params.go index e88a754ca8..5faa467196 100644 --- a/command/server/params.go +++ b/command/server/params.go @@ -37,6 +37,8 @@ const ( devFlag = "dev" corsOriginFlag = "access-control-allow-origins" logFileLocationFlag = "log-to" + tlsCertFileLocationFlag = "tls-cert-file" + tlsKeyFileLocationFlag = "tls-key-file" relayerFlag = "relayer" @@ -183,6 +185,8 @@ func (p *serverParams) generateConfig() *server.Config { LogLevel: hclog.LevelFromString(p.rawConfig.LogLevel), JSONLogFormat: p.rawConfig.JSONLogFormat, LogFilePath: p.logFileLocation, + TLSCertFile: p.rawConfig.TLSCertFile, + TLSKeyFile: p.rawConfig.TLSKeyFile, Relayer: p.relayer, MetricsInterval: p.rawConfig.MetricsInterval, diff --git a/command/server/server.go b/command/server/server.go index 3479a6f669..bca5a60202 100644 --- a/command/server/server.go +++ b/command/server/server.go @@ -214,6 +214,20 @@ func setFlags(cmd *cobra.Command) { "write all logs to the file at specified location instead of writing them to console", ) + cmd.Flags().StringVar( + ¶ms.rawConfig.TLSCertFile, + tlsCertFileLocationFlag, + defaultConfig.TLSCertFile, + "path to TLS cert file, if no file is provided then TLS is not used", + ) + + cmd.Flags().StringVar( + ¶ms.rawConfig.TLSKeyFile, + tlsKeyFileLocationFlag, + defaultConfig.TLSKeyFile, + "path to TLS key file, if no file is provided then TLS is not used", + ) + cmd.Flags().BoolVar( ¶ms.rawConfig.Relayer, relayerFlag, diff --git a/e2e-polybft/e2e/jsonrpc_test.go b/e2e-polybft/e2e/jsonrpc_test.go index 9198f4d697..ca6babe01f 100644 --- a/e2e-polybft/e2e/jsonrpc_test.go +++ b/e2e-polybft/e2e/jsonrpc_test.go @@ -26,6 +26,7 @@ func TestE2E_JsonRPC(t *testing.T) { cluster := framework.NewTestCluster(t, 4, framework.WithPremine(types.Address(acct.Address())), + // framework.WithHTTPS("/etc/ssl/certs/ssl-cert-snakeoil.pem", "/etc/ssl/private/ssl-cert-snakeoil.key"), ) defer cluster.Stop() diff --git a/e2e-polybft/framework/test-cluster.go b/e2e-polybft/framework/test-cluster.go index a6332dd70d..ed763d2df7 100644 --- a/e2e-polybft/framework/test-cluster.go +++ b/e2e-polybft/framework/test-cluster.go @@ -146,6 +146,9 @@ type TestClusterConfig struct { VotingDelay uint64 logsDirOnce sync.Once + + TLSCertFile string + TLSKeyFile string } func (c *TestClusterConfig) Dir(name string) string { @@ -463,6 +466,13 @@ func WithPredeploy(predeployString string) ClusterOption { } } +func WithHTTPS(certFile string, keyFile string) ClusterOption { + return func(h *TestClusterConfig) { + h.TLSCertFile = certFile + h.TLSKeyFile = keyFile + } +} + func isTrueEnv(e string) bool { return strings.ToLower(os.Getenv(e)) == "true" } @@ -805,6 +815,8 @@ func (c *TestCluster) InitTestServer(t *testing.T, config.Relayer = nodeType.IsSet(Relayer) config.NumBlockConfirmations = c.Config.NumBlockConfirmations config.BridgeJSONRPC = bridgeJSONRPC + config.TLSCertFile = c.Config.TLSCertFile + config.TLSKeyFile = c.Config.TLSKeyFile }) // watch the server for stop signals. It is important to fix the specific diff --git a/e2e-polybft/framework/test-server.go b/e2e-polybft/framework/test-server.go index 22ccfc76a1..80c8f4ff51 100644 --- a/e2e-polybft/framework/test-server.go +++ b/e2e-polybft/framework/test-server.go @@ -39,6 +39,8 @@ type TestServerConfig struct { Relayer bool NumBlockConfirmations uint64 BridgeJSONRPC string + TLSCertFile string + TLSKeyFile string } type TestServerConfigCallback func(*TestServerConfig) @@ -65,7 +67,13 @@ func (t *TestServer) GrpcAddr() string { } func (t *TestServer) JSONRPCAddr() string { - return fmt.Sprintf("http://%s:%d", hostIP, t.config.JSONRPCPort) + if t.config.TLSCertFile != "" && t.config.TLSKeyFile != "" { + host, _ := os.Hostname() + + return fmt.Sprintf("https://%s:%d", host, t.config.JSONRPCPort) + } else { + return fmt.Sprintf("http://%s:%d", hostIP, t.config.JSONRPCPort) + } } func (t *TestServer) BridgeJSONRPCAddr() string { @@ -165,6 +173,10 @@ func (t *TestServer) Start() { "--jsonrpc", fmt.Sprintf(":%d", config.JSONRPCPort), // minimal number of child blocks required for the parent block to be considered final "--num-block-confirmations", strconv.FormatUint(config.NumBlockConfirmations, 10), + // TLS certificate file + "--tls-cert-file", config.TLSCertFile, + // TLS key file + "--tls-key-file", config.TLSKeyFile, } if len(config.LogLevel) > 0 { diff --git a/jsonrpc/jsonrpc.go b/jsonrpc/jsonrpc.go index bfae70b15b..e6519c1a85 100644 --- a/jsonrpc/jsonrpc.go +++ b/jsonrpc/jsonrpc.go @@ -71,6 +71,8 @@ type Config struct { ConcurrentRequestsDebug uint64 WebSocketReadLimit uint64 + TLSCertFile string + TLSKeyFile string } // NewJSONRPC returns the JSONRPC http server @@ -107,7 +109,7 @@ func NewJSONRPC(logger hclog.Logger, config *Config) (*JSONRPC, error) { } func (j *JSONRPC) setupHTTP() error { - j.logger.Info("http server started", "addr", j.config.Addr.String()) + j.logger.Info("http server starting...", "addr", j.config.Addr.String()) lis, err := net.Listen("tcp", j.config.Addr.String()) if err != nil { @@ -130,12 +132,24 @@ func (j *JSONRPC) setupHTTP() error { ReadHeaderTimeout: 60 * time.Second, } - go func() { - if err := srv.Serve(lis); err != nil { - j.logger.Error("closed http connection", "err", err) - } - }() + if j.config.TLSCertFile != "" && j.config.TLSKeyFile != "" { + j.logger.Info("https cert file", j.config.TLSCertFile) + j.logger.Info("https key file", j.config.TLSKeyFile) + + go func() { + if err := srv.ServeTLS(lis, j.config.TLSCertFile, j.config.TLSKeyFile); err != nil { + j.logger.Error("closed https connection", "err", err) + } + }() + } else { + go func() { + if err := srv.Serve(lis); err != nil { + j.logger.Error("closed http connection", "err", err) + } + }() + } + j.logger.Info("http server started", "addr", j.config.Addr.String()) return nil } diff --git a/server/config.go b/server/config.go index b1ed771ed3..c33743894e 100644 --- a/server/config.go +++ b/server/config.go @@ -42,6 +42,10 @@ type Config struct { LogFilePath string + TLSCertFile string + + TLSKeyFile string + Relayer bool MetricsInterval time.Duration diff --git a/server/server.go b/server/server.go index e464aa2a13..94544447ff 100644 --- a/server/server.go +++ b/server/server.go @@ -869,6 +869,8 @@ func (s *Server) setupJSONRPC() error { BlockRangeLimit: s.config.JSONRPC.BlockRangeLimit, ConcurrentRequestsDebug: s.config.JSONRPC.ConcurrentRequestsDebug, WebSocketReadLimit: s.config.JSONRPC.WebSocketReadLimit, + TLSCertFile: s.config.TLSCertFile, + TLSKeyFile: s.config.TLSKeyFile, } srv, err := jsonrpc.NewJSONRPC(s.logger, conf)