diff --git a/app.go b/app.go index 0ad33605..ba87fcc7 100644 --- a/app.go +++ b/app.go @@ -69,6 +69,7 @@ type Config struct { ServerURL string Addr string GRPCAddr string + GRPCAllowInsecure bool EphemeralNodeInactivityTimeout time.Duration IPPrefixes []netaddr.IPPrefix PrivateKeyPath string @@ -567,8 +568,7 @@ func (h *Headscale) Serve() error { // https://github.com/soheilhy/cmux/issues/68 // https://github.com/soheilhy/cmux/issues/91 - // If TLS has been enabled, set up the remote gRPC server - if tlsConfig != nil { + if tlsConfig != nil || h.cfg.GRPCAllowInsecure { log.Info().Msgf("Enabling remote gRPC at %s", h.cfg.GRPCAddr) grpcOptions := []grpc.ServerOption{ @@ -578,7 +578,14 @@ func (h *Headscale) Serve() error { zerolog.NewUnaryServerInterceptor(), ), ), - grpc.Creds(credentials.NewTLS(tlsConfig)), + } + + if tlsConfig != nil { + grpcOptions = append(grpcOptions, + grpc.Creds(credentials.NewTLS(tlsConfig)), + ) + } else { + log.Warn().Msg("gRPC is running without security") } grpcServer := grpc.NewServer(grpcOptions...) @@ -586,12 +593,7 @@ func (h *Headscale) Serve() error { v1.RegisterHeadscaleServiceServer(grpcServer, newHeadscaleV1APIServer(h)) reflection.Register(grpcServer) - var grpcListener net.Listener - // if tlsConfig != nil { - // grpcListener, err = tls.Listen("tcp", h.cfg.GRPCAddr, tlsConfig) - // } else { - grpcListener, err = net.Listen("tcp", h.cfg.GRPCAddr) - // } + grpcListener, err := net.Listen("tcp", h.cfg.GRPCAddr) if err != nil { return fmt.Errorf("failed to bind to TCP address: %w", err) } @@ -600,8 +602,6 @@ func (h *Headscale) Serve() error { log.Info(). Msgf("listening and serving gRPC on: %s", h.cfg.GRPCAddr) - } else { - log.Info().Msg("TLS is not configured, not enabling remote gRPC") } // diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 9a3f84d8..85dcae71 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -59,6 +59,7 @@ func LoadConfig(path string) error { viper.SetDefault("unix_socket_permission", "0o770") viper.SetDefault("grpc_listen_addr", ":50443") + viper.SetDefault("grpc_allow_insecure", false) viper.SetDefault("cli.timeout", "5s") viper.SetDefault("cli.insecure", false) @@ -281,9 +282,11 @@ func getHeadscaleConfig() headscale.Config { } return headscale.Config{ - ServerURL: viper.GetString("server_url"), - Addr: viper.GetString("listen_addr"), - GRPCAddr: viper.GetString("grpc_listen_addr"), + ServerURL: viper.GetString("server_url"), + Addr: viper.GetString("listen_addr"), + GRPCAddr: viper.GetString("grpc_listen_addr"), + GRPCAllowInsecure: viper.GetBool("grpc_allow_insecure"), + IPPrefixes: prefixes, PrivateKeyPath: absPath(viper.GetString("private_key_path")), BaseDomain: baseDomain, diff --git a/config-example.yaml b/config-example.yaml index 4fc06c97..ba0c653f 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -23,6 +23,12 @@ listen_addr: 0.0.0.0:8080 # valid certificates. grpc_listen_addr: 0.0.0.0:50443 +# Allow the gRPC admin interface to run in INSECURE +# mode. This is not recommended as the traffic will +# be unencrypted. Only enable if you know what you +# are doing. +grpc_allow_insecure: false + # Private key used encrypt the traffic between headscale # and Tailscale clients. # The private key file which will be