diff --git a/app.go b/app.go index 126ed861..0ad33605 100644 --- a/app.go +++ b/app.go @@ -120,9 +120,10 @@ type DERPConfig struct { } type CLIConfig struct { - Address string - APIKey string - Timeout time.Duration + Address string + APIKey string + Timeout time.Duration + Insecure bool } // Headscale represents the base app of the service. diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 072e3040..84ff977b 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -2,6 +2,7 @@ package cli import ( "context" + "crypto/tls" "encoding/json" "errors" "fmt" @@ -60,6 +61,7 @@ func LoadConfig(path string) error { viper.SetDefault("grpc_listen_addr", ":50443") viper.SetDefault("cli.timeout", "5s") + viper.SetDefault("cli.insecure", false) if err := viper.ReadInConfig(); err != nil { return fmt.Errorf("fatal error reading config file: %w", err) @@ -325,9 +327,10 @@ func getHeadscaleConfig() headscale.Config { }, CLI: headscale.CLIConfig{ - Address: viper.GetString("cli.address"), - APIKey: viper.GetString("cli.api_key"), - Timeout: viper.GetDuration("cli.timeout"), + Address: viper.GetString("cli.address"), + APIKey: viper.GetString("cli.api_key"), + Timeout: viper.GetDuration("cli.timeout"), + Insecure: viper.GetBool("cli.insecure"), }, } } @@ -411,8 +414,22 @@ func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc. grpc.WithPerRPCCredentials(tokenAuth{ token: apiKey, }), - grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), ) + + if cfg.CLI.Insecure { + tlsConfig := &tls.Config{ + InsecureSkipVerify: true, + } + + grpcOptions = append(grpcOptions, + grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)), + ) + + } else { + grpcOptions = append(grpcOptions, + grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), + ) + } } log.Trace().Caller().Str("address", address).Msg("Connecting via gRPC") diff --git a/docs/remote-cli.md b/docs/remote-cli.md index 5ff2f4a0..5ba27ee0 100644 --- a/docs/remote-cli.md +++ b/docs/remote-cli.md @@ -5,7 +5,7 @@ - A workstation to run `headscale` (could be Linux, macOS, other supported platforms) - A `headscale` server (version `0.13.0` or newer) - Access to create API keys (local access to the `headscale` server) -- `headscale` _must_ be served over TLS/HTTPS with a _trusted_ certificate +- `headscale` _must_ be served over TLS/HTTPS - Remote access does _not_ support unencrypted traffic. - Port `50443` must be open in the firewall (or port overriden by `grpc_listen_addr` option) @@ -89,4 +89,5 @@ Checklist: - Make sure you have the _same_ `headscale` version on your server and workstation - Make sure you use version `0.13.0` or newer. - Verify that your TLS certificate is valid and trusted - - If you do not have access to a trusted certificate (e.g. from Let's Encrypt), add your self signed certificate to the trust store of your OS. + - If you do not have access to a trusted certificate (e.g. from Let's Encrypt), add your self signed certificate to the trust store of your OS or + - Set `HEADSCALE_CLI_INSECURE` to 0 in your environement