diff --git a/deploy/docker/docker-compose-rift.yml b/deploy/docker/docker-compose-rift.yml index 825b228..0dc5b33 100644 --- a/deploy/docker/docker-compose-rift.yml +++ b/deploy/docker/docker-compose-rift.yml @@ -28,7 +28,7 @@ services: restart: unless-stopped user: "0:0" ports: - - "127.0.0.1:18080:8080" + - "0.0.0.0:18080:8080" # TODO: revert to 127.0.0.1 once mc-proxy is deployed volumes: - /srv/metacrypt:/srv/metacrypt depends_on: diff --git a/internal/config/config.go b/internal/config/config.go index c975ed7..5c98c1d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -46,6 +46,10 @@ type WebConfig struct { VaultGRPC string `toml:"vault_grpc"` // VaultCACert is the path to the CA certificate used to verify the vault's TLS cert. VaultCACert string `toml:"vault_ca_cert"` + // VaultSNI overrides the TLS server name used to verify the vault's + // certificate. Use when the dial address (e.g., a container hostname) + // does not match any SAN on the vault's TLS certificate. + VaultSNI string `toml:"vault_sni"` // TLSCert and TLSKey are optional. If empty, the web server uses plain HTTP // (suitable for deployment behind a TLS-terminating reverse proxy). TLSCert string `toml:"tls_cert"` diff --git a/internal/webserver/client.go b/internal/webserver/client.go index cbe3e9e..f2b677f 100644 --- a/internal/webserver/client.go +++ b/internal/webserver/client.go @@ -31,10 +31,16 @@ type VaultClient struct { } // NewVaultClient dials the vault gRPC server and returns a client. -func NewVaultClient(addr, caCertPath string, logger *slog.Logger) (*VaultClient, error) { +// NewVaultClient creates a gRPC client to the metacrypt vault API server. +// If sni is non-empty, it overrides the TLS server name for certificate +// verification (use when the dial address doesn't match a cert SAN). +func NewVaultClient(addr, caCertPath, sni string, logger *slog.Logger) (*VaultClient, error) { logger.Debug("connecting to vault", "addr", addr, "ca_cert", caCertPath) - tlsCfg := &tls.Config{MinVersion: tls.VersionTLS13} + tlsCfg := &tls.Config{MinVersion: tls.VersionTLS13} //nolint:gosec // TLS 1.3 minimum + if sni != "" { + tlsCfg.ServerName = sni + } if caCertPath != "" { logger.Debug("loading vault CA certificate", "path", caCertPath) pemData, err := os.ReadFile(caCertPath) //nolint:gosec diff --git a/internal/webserver/server.go b/internal/webserver/server.go index c7cb2d0..5d3bfbb 100644 --- a/internal/webserver/server.go +++ b/internal/webserver/server.go @@ -143,7 +143,7 @@ func (ws *WebServer) resolveUser(id string) string { // New creates a new WebServer. It dials the vault gRPC endpoint. func New(cfg *config.Config, logger *slog.Logger) (*WebServer, error) { logger.Info("connecting to vault", "addr", cfg.Web.VaultGRPC, "ca_cert", cfg.Web.VaultCACert) - vault, err := NewVaultClient(cfg.Web.VaultGRPC, cfg.Web.VaultCACert, logger) + vault, err := NewVaultClient(cfg.Web.VaultGRPC, cfg.Web.VaultCACert, cfg.Web.VaultSNI, logger) if err != nil { return nil, fmt.Errorf("webserver: connect to vault: %w", err) }