refactoring

This commit is contained in:
Justin Angel 2022-02-20 09:06:14 -05:00
parent 1b2fff4337
commit 385dd9cc34
5 changed files with 38 additions and 32 deletions

49
app.go
View file

@ -94,7 +94,7 @@ type Config struct {
TLSCertPath string
TLSKeyPath string
TLSClientAuthMode string
TLSClientAuthMode tls.ClientAuthType
ACMEURL string
ACMEEmail string
@ -153,6 +153,27 @@ type Headscale struct {
requestedExpiryCache *cache.Cache
}
// Look up the TLS constant relative to user-supplied TLS client
// authentication mode. If an unknown mode is supplied, the default
// value, tls.RequireAnyClientCert, is returned. The returned boolean
// indicates if the supplied mode was valid.
func LookupTLSClientAuthMode(mode string) (tls.ClientAuthType, bool) {
switch mode {
case DisabledClientAuth:
// Client cert is _not_ required.
return tls.NoClientCert, true
case RelaxedClientAuth:
// Client cert required, but _not verified_.
return tls.RequireAnyClientCert, true
case EnforcedClientAuth:
// Client cert is _required and verified_.
return tls.RequireAndVerifyClientCert, true
default:
// Return the default when an unknown value is supplied.
return tls.RequireAnyClientCert, false
}
}
// NewHeadscale returns the Headscale app.
func NewHeadscale(cfg Config) (*Headscale, error) {
privKey, err := readOrCreatePrivateKey(cfg.PrivateKeyPath)
@ -655,17 +676,12 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) {
log.Warn().Msg("Listening with TLS but ServerURL does not start with https://")
}
clientAuthMode, err := h.GetClientAuthMode()
if err != nil {
return nil, err
}
log.Info().Msg(fmt.Sprintf(
"Client authentication (mTLS) is \"%s\". See the docs to learn about configuring this setting.",
h.cfg.TLSClientAuthMode))
tlsConfig := &tls.Config{
ClientAuth: clientAuthMode,
ClientAuth: h.cfg.TLSClientAuthMode,
NextProtos: []string{"http/1.1"},
Certificates: make([]tls.Certificate, 1),
MinVersion: tls.VersionTLS12,
@ -677,25 +693,6 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) {
}
}
// Look up the TLS constant relative to user-supplied TLS client
// authentication mode.
func (h *Headscale) GetClientAuthMode() (tls.ClientAuthType, error) {
switch h.cfg.TLSClientAuthMode {
case DisabledClientAuth:
// Client cert is _not_ required.
return tls.NoClientCert, nil
case RelaxedClientAuth:
// Client cert required, but _not verified_.
return tls.RequireAnyClientCert, nil
case EnforcedClientAuth:
// Client cert is _required and verified_.
return tls.RequireAndVerifyClientCert, nil
default:
return tls.NoClientCert, Error("Invalid tls_client_auth_mode provided: " +
h.cfg.TLSClientAuthMode)
}
}
func (h *Headscale) setLastStateChangeToNow(namespace string) {
now := time.Now().UTC()
lastStateUpdate.WithLabelValues("", "headscale").Set(float64(now.Unix()))

Binary file not shown.

View file

@ -30,6 +30,7 @@ const (
)
func LoadConfig(path string) error {
viper.SetConfigName("config")
if path == "" {
viper.AddConfigPath("/etc/headscale/")
@ -87,9 +88,15 @@ func LoadConfig(path string) error {
errorText += "Fatal config error: server_url must start with https:// or http://\n"
}
clientAuthMode := viper.GetString("tls_client_auth_mode")
if clientAuthMode != "disabled" && clientAuthMode != "relaxed" && clientAuthMode != "enforced" {
errorText += "Invalid tls_client_auth_mode supplied. Accepted values: disabled, relaxed, enforced."
_, authModeValid := headscale.LookupTLSClientAuthMode(viper.GetString("tls_client_auth_mode"))
if !authModeValid {
errorText += fmt.Sprintf(
"Invalid tls_client_auth_mode supplied: %s. Accepted values: %s, %s, %s.",
viper.GetString("tls_client_auth_mode"),
headscale.DisabledClientAuth,
headscale.RelaxedClientAuth,
headscale.EnforcedClientAuth)
}
if errorText != "" {
@ -280,6 +287,8 @@ func getHeadscaleConfig() headscale.Config {
log.Warn().Msgf("'ip_prefixes' not configured, falling back to default: %v", prefixes)
}
tlsClientAuthMode, _ := headscale.LookupTLSClientAuthMode(viper.GetString("tls_client_auth_mode"))
return headscale.Config{
ServerURL: viper.GetString("server_url"),
Addr: viper.GetString("listen_addr"),
@ -310,7 +319,7 @@ func getHeadscaleConfig() headscale.Config {
TLSCertPath: absPath(viper.GetString("tls_cert_path")),
TLSKeyPath: absPath(viper.GetString("tls_key_path")),
TLSClientAuthMode: viper.GetString("tls_client_auth_mode"),
TLSClientAuthMode: tlsClientAuthMode,
DNSConfig: dnsConfig,

View file

@ -97,7 +97,7 @@ tls_letsencrypt_hostname: ""
# - disabled: client authentication disabled
# - relaxed: client certificate is required but not verified
# - enforced: client certificate is required and verified
tls_client_auth_mode: disabled
tls_client_auth_mode: relaxed
# Path to store certificates and metadata needed by
# letsencrypt

View file

@ -33,7 +33,7 @@ tls_key_path: ""
### Configuring Mutual TLS Authentication (mTLS)
mTLS is a method by which an HTTPS server authenticates clients, e.g. Tailscale,
using TLS certificates. The capability can be configured by by applying one of
using TLS certificates. The capability can be configured by applying one of
the following values to the `tls_client_auth_mode` setting in the configuration
file.