diff --git a/config-example.yaml b/config-example.yaml index ba81ba5d..548868ce 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -40,6 +40,11 @@ grpc_listen_addr: 127.0.0.1:50443 # are doing. grpc_allow_insecure: false +# Use separate a certificate for gRPC, this overwrites +# the global certificate. +grpc_tls_cert_path: "" +grpc_tls_key_path: "" + # The Noise section includes specific configuration for the # TS2021 Noise protocol noise: diff --git a/hscontrol/app.go b/hscontrol/app.go index a29e53dc..b9238f4f 100644 --- a/hscontrol/app.go +++ b/hscontrol/app.go @@ -631,9 +631,27 @@ func (h *Headscale) Serve() error { // https://github.com/soheilhy/cmux/issues/68 // https://github.com/soheilhy/cmux/issues/91 + grpcTlsConfig := &tls.Config{ + NextProtos: []string{"http/1.1"}, + Certificates: make([]tls.Certificate, 1), + MinVersion: tls.VersionTLS12, + } + + if h.cfg.TLS.GRPCCertPath == "" && h.cfg.TLS.GRPCKeyPath == "" { + grpcTlsConfig = tlsConfig + } else { + grpcTlsConfig.Certificates[0], err = tls.LoadX509KeyPair(h.cfg.TLS.GRPCCertPath, h.cfg.TLS.GRPCKeyPath) + + if err != nil { + log.Error().Err(err).Msg("Failed to set up gRPC TLS configuration") + + return err + } + } + var grpcServer *grpc.Server var grpcListener net.Listener - if tlsConfig != nil || h.cfg.GRPCAllowInsecure { + if grpcTlsConfig != nil || h.cfg.GRPCAllowInsecure { log.Info().Msgf("Enabling remote gRPC at %s", h.cfg.GRPCAddr) grpcOptions := []grpc.ServerOption{ @@ -646,9 +664,9 @@ func (h *Headscale) Serve() error { ), } - if tlsConfig != nil { + if grpcTlsConfig != nil { grpcOptions = append(grpcOptions, - grpc.Creds(credentials.NewTLS(tlsConfig)), + grpc.Creds(credentials.NewTLS(grpcTlsConfig)), ) } else { log.Warn().Msg("gRPC is running without security") diff --git a/hscontrol/types/config.go b/hscontrol/types/config.go index 022d1279..5f66b70b 100644 --- a/hscontrol/types/config.go +++ b/hscontrol/types/config.go @@ -99,6 +99,8 @@ type DatabaseConfig struct { type TLSConfig struct { CertPath string KeyPath string + GRPCCertPath string + GRPCKeyPath string LetsEncrypt LetsEncryptConfig } @@ -303,6 +305,12 @@ func GetTLSConfig() TLSConfig { KeyPath: util.AbsolutePathFromConfigPath( viper.GetString("tls_key_path"), ), + GRPCCertPath: util.AbsolutePathFromConfigPath( + viper.GetString("grpc_tls_cert_path"), + ), + GRPCKeyPath: util.AbsolutePathFromConfigPath( + viper.GetString("grpc_tls_key_path"), + ), } }