Conversation
kradalby
left a comment
There was a problem hiding this comment.
Could you add a test to verify that the values work as intended and a failure case to verify failure?
And add the entry to config-example.yaml with some docs (and linking to the tls doc)
|
|
||
| viper.SetDefault("tls_letsencrypt_cache_dir", "/var/www/.cache") | ||
| viper.SetDefault("tls_letsencrypt_challenge_type", "HTTP-01") | ||
| viper.SetDefault("tls_client_auth_mode", "disabled") |
There was a problem hiding this comment.
This default is different than the current setting, how come?
There was a problem hiding this comment.
Please correct me if I'm wrong, but I think Tailscale doesn't support client certificates right now.
The current default, RequireAnyClientCert, prevents connections over TLS unless any cert is provided by the client.
If I'm not overlooking something, then this means that Tailscale can't interact with Headscale when it's configured to use TLS.
There was a problem hiding this comment.
If I'm not overlooking something, then this means that Tailscale can't interact with Headscale when it's configured to use TLS.
Hmm, I am not sure what this means? I am running my headscale with TLS?
There was a problem hiding this comment.
How curious! All of my browsers throw a bad ssl error unless a client certificate is supplied, then it works as expected.
I'm using the config parameters to point at cert values for letsencrypt files I already have on hand.
I believe issue #254 reflects the same outcome.
Do we have a misconfiguration somewhere or something?
There was a problem hiding this comment.
Hmm, happy to make it configurable so users with this problem can at least test them, however, there are many successful users (me included) and I think think there is a reason to change the default for everyone.
My current setup has tls set in nginx, but a week ago, I used the letsencrypt built in to headscale.
So yep, let's get it in, but, we should not change the default.
There was a problem hiding this comment.
Agreed! Sorry for the confusion there.
Should have things buttoned up tonight/early tomorrow.
There was a problem hiding this comment.
Alrighty, the latest commit preserves the original default.
| the following values to the `tls_client_auth_mode` setting in the configuration | ||
| file. | ||
|
|
||
| | Value | Behavior | |
There was a problem hiding this comment.
This file needs to be ran through prettier
There was a problem hiding this comment.
It has now been ran through prettier. My bad on the oversight.
| } | ||
|
|
||
| var clientAuthMode tls.ClientAuthType | ||
| if h.cfg.TLSClientAuthMode == "disabled" { |
There was a problem hiding this comment.
This should be a switch statement, and the alternatives should be Constants.
There was a problem hiding this comment.
Good call. I'm new to Go, so thank you for this critique. Much less typing in a switch statement.
There was a problem hiding this comment.
In the latest commit, I moved this logic to a new function to make testing a bit simpler and implemented a switch statement.
…to configurable-mtls
…to configurable-mtls
kradalby
left a comment
There was a problem hiding this comment.
Looking like its get there, I think this might be a way to simplify the flow a bit and remove some redundant checks.
| TLSKeyPath string | ||
| TLSCertPath string | ||
| TLSKeyPath string | ||
| TLSClientAuthMode string |
There was a problem hiding this comment.
- I would argue that you can just use the
tls.ClientAuthTypetype here.
| clientAuthMode, err := h.GetClientAuthMode() | ||
| if err != nil { | ||
| return nil, err | ||
| } |
There was a problem hiding this comment.
- Then remove this ( or cut it for later )
|
|
||
| tlsConfig := &tls.Config{ | ||
| ClientAuth: tls.RequireAnyClientCert, | ||
| ClientAuth: clientAuthMode, |
There was a problem hiding this comment.
- Then do this:
| ClientAuth: clientAuthMode, | |
| ClientAuth: h.cfg.TLSClientAuthMode, |
| 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." | ||
| } |
There was a problem hiding this comment.
- Then instead here call the
h.GetClientAuthModefunction and check the error instead of having thatif.
| TLSKeyPath: absPath(viper.GetString("tls_key_path")), | ||
| TLSCertPath: absPath(viper.GetString("tls_cert_path")), | ||
| TLSKeyPath: absPath(viper.GetString("tls_key_path")), | ||
| TLSClientAuthMode: viper.GetString("tls_client_auth_mode"), |
There was a problem hiding this comment.
- Then just set it here if there was no error in 4.:
| TLSClientAuthMode: viper.GetString("tls_client_auth_mode"), | |
| TLSClientAuthMode: clientAuthMode, |
| # - disabled: client authentication disabled | ||
| # - relaxed: client certificate is required but not verified | ||
| # - enforced: client certificate is required and verified | ||
| tls_client_auth_mode: disabled |
There was a problem hiding this comment.
This should be relaxed to reflect the default.
| tls_client_auth_mode: disabled | |
| tls_client_auth_mode: relaxed |
| ### 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 |
There was a problem hiding this comment.
Duplicate wording? by by applying one of
|
@Arch4ngel Looks good, last few things is just make the linters happy, and add a line to the changelog under TBD. Good job :) |
Thanks for your patience on this! Work consumed me for a few weeks. |
|
Need another run of |
The Problem
Currently, mTLS is set to require any certificate from clients when TLS is enabled. Verification of the certificate is not performed by Headscale, and as far as I can tell, there isn't a way to configure the Tailscale client to accept TLS certificate for authentication.
Implemented Solution
This merge makes mTLS configurable by adding a configuration parameter to
config.yaml. It's disabled via thedisabledvalue by default and can be configured to require any certificate (relaxed) or require and verify (enforced) a client certificate.Related Issues