-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ADDED] verify_cert_and_check_known_urls to tie subject alt name to url in cfg #1727
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests changes.
return "", opts.Gateway.Username == user | ||
if opts.Gateway.TLSMap || opts.Gateway.TLSImplicitAllow { | ||
return checkClientTLSCertSubject(c, func(user string, _ *ldap.DN, isDNSAltName bool) (string, bool) { | ||
if user == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In original code, is that possible that user
and Gateway.Username
be empty in TLSMap context? If so, this is changing the behavior. Is that intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that user should ever be empty. In that case the CA would have signed a cert with empty fields.
I'm also not sure. if you can even configure an empty user name.
This is more like a guard I added out of habit for my code.
Out of habit I also placed it at the top of the function.
Remove?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just asking, because maybe we need this check and it wasn't there before. Actually, looking at isGatewayAuthorized() top of func we already return true if opts.Gateway.Username == ""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function (outside of tests at least) is always called with a user, so we should not need this test.
But if we think that cert.EmailAddress, etc.. may contain (legally or maliciously) empty values and if that would cause a failure for dnsAltNameLabels(), then you could leave the check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just guard against something weird coming out of the cert. that said. I realized that it is missing for the cluster
if gw != nil && dnsAltNameMatches(labels, gw.URLs) { | ||
return "", true | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Help me understand if we are in this if
statement, and we did not return true yet, should then we fail here? Or is it intended that we fall back to TLSMap check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to go through all gateways.
Just because GW1 didn't contain a matching url does not mean that GW2 wouldn't.
Your comment would apply to the cluster case as well, there only one list exists.
I decided to support setting both flags (verify_and_map verify_and_implicit_allow) to true.
I did so primarily to avoid having to write the check to cause a config error if both are set.
change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My question is more: if opts.Gateway.TLSImplicitAllow is true, but isDNSAltName is false, it means what? That we are not in a client context and we should not perform this check anyway. But if isDNSAltName is true and we did not find a match, does that makes sense to fallback to tls_map check only? I don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if isDNSAltName is false then the argument user does not contain a value coming out of a DNS entry, hence it can't be used for matching, even if isDNSAltName allow is true.
When presented with an email for example, we shouldn't try to tokenize the ip address.
X509v3 extensions:
X509v3 Subject Alternative Name:
IP Address:127.0.0.1
We get a call where the name is 127.0.0.1 and isDNSAltName = false.
If tls_map happens to be true we check if 127.0.0.1 is configured as user.
if isDNSAltName is true and say the user is localhost, and we fail to find localhost in our config and if the user also enabled tls_map, why not see if the user localhost is configured?
if tls_map is not false, we'll default to false at the end of the function.
server/opts.go
Outdated
TLSTimeout float64 `json:"-"` | ||
TLSConfig *tls.Config `json:"-"` | ||
TLSMap bool `json:"-"` | ||
TLSImplicitAllow bool `json:"-"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, it is not clear to me what this option does. Default will be false, so can you describe to me what setting this boolean to true will mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the doc will say:
verify_and_implicit_allow| Only settable in a non client context where verify=true is the default (gateways/cluster). The incoming connections certificate's X509v3 Subject Alternative Name
DNS entries will be matched against all urls in the configuration context that contains this tls map. If a match is found the connection is accepted, otherwise rejected. Meaning for gateways we will match all DNS entries in the certificate against all gateway urls. For cluster we will match against all route urls. As a consequence of this, dynamic cluster growth may require config changes in other cluster where this flag is true. DNS name checking is performed according to https://tools.ietf.org/html/rfc6125#section-6.4.1 Only the full wildcard *
is supported for the left most label. This would be a way to keep cluster growth flexible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The explanation seem clear to me, but I am not sure about the option name. Maybe @philpennock and @davidkemper can comment on that?
@kozlovic @philpennock @davidkemper Talked to @philpennock , let's hold off on IPs for now. |
Maybe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.. let's see if others have some input for the new config option name.
Only works for gateways and routes. When true the subject alt DNS name must match one url in the corresponding configuration Signed-off-by: Matthias Hanel <mh@synadia.com>
had to change failing tests to use insecure as to not fail due to the outgoing connection being not trusted. Signed-off-by: Matthias Hanel <mh@synadia.com>
Signed-off-by: Matthias Hanel <mh@synadia.com>
…pt_known_urls This follows the suggestion by phil. I added the and to be similar to verify_and_map. I fixed a minor issue where the implicit verify could be overwriting an explicitly configured one. Signed-off-by: Matthias Hanel <mh@synadia.com>
10c0759
to
eda80ff
Compare
server/opts.go
Outdated
TLSConfig *tls.Config `json:"-"` | ||
TLSTimeout float64 `json:"tls_timeout,omitempty"` | ||
TLSMap bool `json:"-"` | ||
TLSAcceptKnownUrls bool `json:"-"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, I feel like this name sounds less restrictive when enabled than when it is disabled, which is not the case. Meaning that the default is false
, which sounds like the server is not accepting something, while in reality, when false it means that it may accept things that it should not.
Would TLSCheckKnownUrls
be better? I know we agreed on verify_and_accept_known_urls
but maybe we could also change that one with verify_and_check_known_urls
. If the verify_and_check_
seem strange, maybe having verify_cert_and_check_known_urls
lays out explicitly what this is about.
Signed-off-by: Matthias Hanel <mh@synadia.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Only works for gateways and routes. When true the subject alt DNS name
must match one url in the corresponding configuration
As discussed. At the very least have a look at the unit test cases in TestDNSAltNameMatching. Looking at certs to write my other tests I started to wonder if we should extend this to IPs too?
Also look for 127.0.0.1 and it's IPv6 variant. Opinions?
If yes, I'd be open to suggestions on which urls to provide in test/tls_test.go line 823, 891, 892
What I intend to include in the doc
verify_and_implicit_allow| Only settable in a non client context where verify=true is the default (gateways/cluster). The incoming connections certificate's
X509v3 Subject Alternative Name
DNS entries will be matched against all urls in the configuration context that contains this tls map. If a match is found the connection is accepted, otherwise rejected. Meaning for gateways we will match all DNS entries in the certificate against all gateway urls. For cluster we will match against all route urls. As a consequence of this, dynamic cluster growth may require config changes in other cluster where this flag is true. DNS name checking is performed according to https://tools.ietf.org/html/rfc6125#section-6.4.1 Only the full wildcard*
is supported for the left most label. This would be a way to keep cluster growth flexible.Signed-off-by: Matthias Hanel mh@synadia.com