diff --git a/go.mod b/go.mod index 3e6ad45..783717d 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ toolchain go1.23.1 require ( github.com/ethereum/go-ethereum v1.14.9 + github.com/flashbots/go-utils v0.8.2 github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/httplog/v2 v2.1.1 github.com/pelletier/go-toml/v2 v2.2.3 @@ -18,7 +19,6 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/flashbots/go-utils v0.8.2 // indirect github.com/holiman/uint256 v1.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/systemapi-config.toml b/systemapi-config.toml index 2425eba..886a90c 100644 --- a/systemapi-config.toml +++ b/systemapi-config.toml @@ -18,9 +18,10 @@ basic_auth_secret_salt = "D;%yL9TS:5PalS/d" # use a random string for the s # TLS configuration tls_enabled = true +tls_create_if_missing = true tls_cert_path = "cert.pem" tls_key_path = "key.pem" -tls_create_if_missing = true +tls_hosts = ["localhost", ""] [actions] echo_test = "echo test" diff --git a/systemapi/config.go b/systemapi/config.go index 1155aa9..51b416f 100644 --- a/systemapi/config.go +++ b/systemapi/config.go @@ -23,10 +23,11 @@ type systemAPIConfigGeneral struct { HTTPReadTimeoutMillis int `toml:"http_read_timeout_ms"` HTTPWriteTimeoutMillis int `toml:"http_write_timeout_ms"` - TLSEnabled bool `toml:"tls_enabled"` - TLSCertPath string `toml:"tls_cert_path"` - TLSKeyPath string `toml:"tls_key_path"` - TLSCreateIfMissing bool `toml:"tls_create_if_missing"` + TLSEnabled bool `toml:"tls_enabled"` + TLSCertPath string `toml:"tls_cert_path"` + TLSKeyPath string `toml:"tls_key_path"` + TLSCreateIfMissing bool `toml:"tls_create_if_missing"` + TLSHosts []string `toml:"tls_hosts"` } type SystemAPIConfig struct { diff --git a/systemapi/server.go b/systemapi/server.go index 0c6a355..8053069 100644 --- a/systemapi/server.go +++ b/systemapi/server.go @@ -79,8 +79,9 @@ func NewServer(log *httplog.Logger, cfg *SystemAPIConfig) (server *Server, err e // Load or create TLS certificate if cfg.General.TLSEnabled { - err = server.loadOrCreateTLSCert() + err = server.createTLSCertIfNotExists() if err != nil { + server.log.Error("Failed to create TLS certificate", "err", err) return nil, err } } @@ -190,6 +191,15 @@ func (s *Server) readPipeInBackground() { func (s *Server) Start() { s.log.Info("Starting HTTP server", "listenAddress", s.cfg.General.ListenAddr) + + if s.cfg.General.TLSEnabled { + s.log.Info("TLS enabled", "cert", s.cfg.General.TLSCertPath, "key", s.cfg.General.TLSKeyPath) + if err := s.srv.ListenAndServeTLS(s.cfg.General.TLSCertPath, s.cfg.General.TLSKeyPath); err != nil && !errors.Is(err, http.ErrServerClosed) { + s.log.Error("HTTP server failed", "err", err) + } + return + } + if err := s.srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { s.log.Error("HTTP server failed", "err", err) } diff --git a/systemapi/tls.go b/systemapi/tls.go index e8731f8..c1a5acb 100644 --- a/systemapi/tls.go +++ b/systemapi/tls.go @@ -1,12 +1,58 @@ package systemapi import ( + "errors" + "os" "time" "github.com/flashbots/go-utils/tls" ) -func (s *Server) loadOrCreateTLSCert() error { - _, _, err := tls.GenerateTLS(time.Hour*24*365, []string{}) - return err +// createTLSCertIfNotExists created a cert and key file if it doesn't exist yet +func (s *Server) createTLSCertIfNotExists() error { + log := s.log.With("cert", s.cfg.General.TLSCertPath, "key", s.cfg.General.TLSKeyPath) + _, err1 := os.Stat(s.cfg.General.TLSCertPath) + if err1 != nil && !os.IsNotExist(err1) { + return err1 + } + + _, err2 := os.Stat(s.cfg.General.TLSKeyPath) + if err2 != nil && !os.IsNotExist(err2) { + return err2 + } + + certFileExists := err1 == nil + keyFileExists := err2 == nil + if certFileExists && keyFileExists { + // Files exist, use them + log.Info("TLS cert and key found, using them") + return nil + } else if certFileExists || keyFileExists { + // Only one of the files exist, should not happen + return errors.New("both TLS cert and key files are required, but only one exists") + } + + // Files do not exist, should create them + if !s.cfg.General.TLSCreateIfMissing { + return errors.New("TLS cert and key files do not exist, but config is set to not create them") + } + + // Create them + cert, key, err := tls.GenerateTLS(time.Hour*24*365, s.cfg.General.TLSHosts) + if err != nil { + return err + } + + err = os.WriteFile(s.cfg.General.TLSCertPath, cert, 0o600) + if err != nil { + return err + } + + err = os.WriteFile(s.cfg.General.TLSKeyPath, key, 0o600) + if err != nil { + return err + } + + log.With("hosts", s.cfg.General.TLSHosts).Info("TLS cert and key files created") + return nil }