diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e17667..4abca03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Unreleased + +* [BREAKING] Rename the `SSL_DOMAIN` env to `TLS_DOMAIN` (#13) + ## v0.1.3 / 2024-03-21 * Disable transparent proxy compression (#11) diff --git a/README.md b/README.md index c573126..68e5fdb 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ applications. It runs alongside the Puma webserver to provide a few additional features that help your app run efficiently and safely on the open Internet: - HTTP/2 support -- Automatic SSL certificate management with Let's Encrypt +- Automatic TLS certificate management with Let's Encrypt - Basic HTTP caching of public assets - X-Sendfile support and compression, to efficiently serve static files @@ -14,9 +14,9 @@ and most features are automatically enabled with sensible defaults. The goal is that simply running your Puma server with Thruster should be enough to get a production-ready setup. -The only exception to this is SSL provisioning: in order for Thruster to -provision SSL certificates, it needs to know which domain those certificates -should be for. So to use SSL, you need to set the `SSL_DOMAIN` environment +The only exception to this is TLS provisioning: in order for Thruster to +provision TLS certificates, it needs to know which domain those certificates +should be for. So to use TLS, you need to set the `TLS_DOMAIN` environment variable. If you don't set this variable, Thruster will run in HTTP-only mode. Thruster also wraps the Puma process so that you can use it without managing @@ -59,10 +59,10 @@ with `thrust`. For example: $ thrust bin/rails server ``` -Or with automatic SSL: +Or with automatic TLS: ```sh -$ SSL_DOMAIN=myapp.example.com thrust bin/rails server +$ TLS_DOMAIN=myapp.example.com thrust bin/rails server ``` @@ -74,25 +74,25 @@ environment variables that you can set. | Variable Name | Description | Default Value | |-----------------------|---------------------------------------------------------------------------------|---------------| -| `SSL_DOMAIN` | The domain name to use for SSL provisioning. If not set, SSL will be disabled. | None | +| `TLS_DOMAIN` | The domain name to use for TLS provisioning. If not set, TLS will be disabled. | None | | `TARGET_PORT` | The port that your Puma server should run on. Thruster will set `PORT` to this value when starting your server. | 3000 | | `CACHE_SIZE` | The size of the HTTP cache in bytes. | 64MB | | `MAX_CACHE_ITEM_SIZE` | The maximum size of a single item in the HTTP cache in bytes. | 1MB | | `X_SENDFILE_ENABLED` | Whether to enable X-Sendfile support. Set to `0` or `false` to disable. | Enabled | | `MAX_REQUEST_BODY` | The maximum size of a request body in bytes. Requests larger than this size will be refused; `0` means no maximum size is enforced. | `0` | -| `STORAGE_PATH` | The path to store Thruster's internal state. Provisioned SSL certificates will be stored here, so that they will not need to be requested every time your application is started. | `./storage/thruster` | +| `STORAGE_PATH` | The path to store Thruster's internal state. Provisioned TLS certificates will be stored here, so that they will not need to be requested every time your application is started. | `./storage/thruster` | | `BAD_GATEWAY_PAGE` | Path to an HTML file to serve when the backend server returns a 502 Bad Gateway error. If there is no file at the specific path, Thruster will serve an empty 502 response instead. Because Thruster boots very quickly, a custom page can be a useful way to show that your application is starting up. | `./public/502.html` | | `HTTP_PORT` | The port to listen on for HTTP traffic. | 80 | | `HTTPS_PORT` | The port to listen on for HTTPS traffic. | 443 | | `HTTP_IDLE_TIMEOUT` | The maximum time in seconds that a client can be idle before the connection is closed. | 60 | | `HTTP_READ_TIMEOUT` | The maximum time in seconds that a client can take to send the request headers and body. | 30 | | `HTTP_WRITE_TIMEOUT` | The maximum time in seconds during which the client must read the response. | 30 | -| `ACME_DIRECTORY` | The URL of the ACME directory to use for SSL certificate provisioning. | `https://acme-v02.api.letsencrypt.org/directory` (Let's Encrypt production) | -| `EAB_KID` | The EAB key identifier to use when provisioning SSL certificates, if required. | None | -| `EAB_HMAC_KEY` | The Base64-encoded EAB HMAC key to use when provisioning SSL certificates, if required. | None | +| `ACME_DIRECTORY` | The URL of the ACME directory to use for TLS certificate provisioning. | `https://acme-v02.api.letsencrypt.org/directory` (Let's Encrypt production) | +| `EAB_KID` | The EAB key identifier to use when provisioning TLS certificates, if required. | None | +| `EAB_HMAC_KEY` | The Base64-encoded EAB HMAC key to use when provisioning TLS certificates, if required. | None | | `DEBUG` | Set to `1` or `true` to enable debug logging. | Disabled | To prevent naming clashes with your application's own environment variables, Thruster's environment variables can optionally be prefixed with `THRUSTER_`. -For example, `SSL_DOMAIN` can also be written as `THRUSTER_SSL_DOMAIN`. Whenever +For example, `TLS_DOMAIN` can also be written as `THRUSTER_TLS_DOMAIN`. Whenever a prefixed variable is set, it will take precedence over the unprefixed version. diff --git a/internal/config.go b/internal/config.go index eff8ce4..a22d6f2 100644 --- a/internal/config.go +++ b/internal/config.go @@ -45,7 +45,7 @@ type Config struct { XSendfileEnabled bool MaxRequestBody int - SSLDomain string + TLSDomain string ACMEDirectoryURL string EAB_KID string EAB_HMACKey string @@ -81,7 +81,7 @@ func NewConfig() (*Config, error) { XSendfileEnabled: getEnvBool("X_SENDFILE_ENABLED", true), MaxRequestBody: getEnvInt("MAX_REQUEST_BODY", defaultMaxRequestBody), - SSLDomain: getEnvString("SSL_DOMAIN", ""), + TLSDomain: getEnvString("TLS_DOMAIN", ""), ACMEDirectoryURL: getEnvString("ACME_DIRECTORY", defaultACMEDirectoryURL), EAB_KID: getEnvString("EAB_KID", ""), EAB_HMACKey: getEnvString("EAB_HMAC_KEY", ""), diff --git a/internal/config_test.go b/internal/config_test.go index cd8f7b0..8353c89 100644 --- a/internal/config_test.go +++ b/internal/config_test.go @@ -9,6 +9,27 @@ import ( "github.com/stretchr/testify/require" ) +func TestConfig_tls(t *testing.T) { + t.Run("with no ENV", func(t *testing.T) { + usingProgramArgs(t, "thruster", "echo", "hello") + + c, err := NewConfig() + require.NoError(t, err) + + assert.Equal(t, "", c.TLSDomain) + }) + + t.Run("with TLS_DOMAIN", func(t *testing.T) { + usingProgramArgs(t, "thruster", "echo", "hello") + usingEnvVar(t, "TLS_DOMAIN", "example.com") + + c, err := NewConfig() + require.NoError(t, err) + + assert.Equal(t, "example.com", c.TLSDomain) + }) +} + func TestConfig_defaults(t *testing.T) { usingProgramArgs(t, "thruster", "echo", "hello") diff --git a/internal/server.go b/internal/server.go index e58c58f..598e8b0 100644 --- a/internal/server.go +++ b/internal/server.go @@ -31,7 +31,7 @@ func (s *Server) Start() { httpAddress := fmt.Sprintf(":%d", s.config.HttpPort) httpsAddress := fmt.Sprintf(":%d", s.config.HttpsPort) - if s.config.SSLDomain != "" { + if s.config.TLSDomain != "" { manager := s.certManager() s.httpServer = s.defaultHttpServer(httpAddress) @@ -44,7 +44,7 @@ func (s *Server) Start() { go s.httpServer.ListenAndServe() go s.httpsServer.ListenAndServeTLS("", "") - slog.Info("Server started", "http", httpAddress, "https", httpsAddress, "ssl_domain", s.config.SSLDomain) + slog.Info("Server started", "http", httpAddress, "https", httpsAddress, "tls_domain", s.config.TLSDomain) } else { s.httpsServer = nil s.httpServer = s.defaultHttpServer(httpAddress) @@ -73,13 +73,13 @@ func (s *Server) certManager() *autocert.Manager { client := &acme.Client{DirectoryURL: s.config.ACMEDirectoryURL} binding := s.externalAccountBinding() - slog.Debug("SSL: initializing", "directory", client.DirectoryURL, "using_eab", binding != nil) + slog.Debug("TLS: initializing", "directory", client.DirectoryURL, "using_eab", binding != nil) return &autocert.Manager{ Cache: autocert.DirCache(s.config.StoragePath), Client: client, ExternalAccountBinding: binding, - HostPolicy: autocert.HostWhitelist(s.config.SSLDomain), + HostPolicy: autocert.HostWhitelist(s.config.TLSDomain), Prompt: autocert.AcceptTOS, } }