Skip to content
This repository has been archived by the owner on Dec 15, 2020. It is now read-only.

Support TLS client certificate enrollment #1120

Closed
marpaia opened this issue Jan 27, 2017 · 10 comments
Closed

Support TLS client certificate enrollment #1120

marpaia opened this issue Jan 27, 2017 · 10 comments

Comments

@marpaia
Copy link
Contributor

marpaia commented Jan 27, 2017

osquery supports two forms of client authentication:

  • shared secret authentication via the "enroll_secret"
  • TLS client certificate enrollment

Right now Kolide only supports the shared secret enrollment, but customers have been asking for TLS client certificate enrollment. The documentation for specifying the client certificate and key can be found here: https://osquery.readthedocs.io/en/stable/deployment/remote/#tls-client-auth-enrollment.

@groob
Copy link
Contributor

groob commented Feb 14, 2017

Right now we use a single port/hostname for ALL endpoints, including the osqueryd ones.
Adding client certificate auth in the Go server config will require those certificates for every endpoint, even the one service the frontend. I don't think we want to do that.

Here's a few possibilities:

  • require cert auth for the whole kolide server (undesirable)
  • listen for osqueryd traffic on a port other than the one serving the frontend
  • use SNI with client auth so that it's the same port, but requiring a different hostname
  • punt on the whole thing and ask advanced users to terminate all TLS traffic(including client certificate authentication upstream at a load balancer) This is possible today and would not require any additional code.

aside: Building this functionality into a cloud offering would be simpler as we can always serve the TLS endpoints by a completely different backend and do path based routing there.

@murphybytes
Copy link
Contributor

I think the first option is a non starter.

Option 2 Feasible but messy, requiring quite a but of new code. That's what I've been exploring as a solution currently.

So the SNI option would require a CNAME to alias the kolide host? That might not be too bad.

I think that given the effort that this is likely to take if we are to implement #2 your point about focusing our efforts on the cloud offering is a better option.

@murphybytes
Copy link
Contributor

According to @theopolis the osquery tls plugin supports SNI so that might be the way to go, since you can define a function in tls.Config to handle it

@groob
Copy link
Contributor

groob commented Feb 14, 2017

It's still per server, not per-endpoint

@murphybytes
Copy link
Contributor

So if I understand this correctly, using SNI, the only way to get this to work, would be to have the osquery endpoints served on a different port?

@groob
Copy link
Contributor

groob commented Feb 14, 2017

different port, or different hostname are both options

@somethingnew2-0
Copy link

somethingnew2-0 commented Oct 29, 2017

As far as I can tell and with a little experimentation with the Go TLS stack it appears it is possible to do client certificate based authentication per endpoint by specifying VerifyClientCertIfGiven in your ClientAuthType of your TLS Server Config. This is instead of using the strongest option RequireAndVerifyClientCert which would require every connection on the entire server to have a valid client certificate.

After specifying VerifyClientCertIfGiven you can access the validated client certificate in each request handler in the http.Request.TLS.VerifiedChains struct. Similar to how the authenticatedHost method works right now in the fleet endpoint handlers.

One added benefit is that you can still specify a VerifyPeerCertificate callback function in your TLS Server Config to verify that the correct OU, DN, etc. is authorized for any client certificate sent.

I might try to see if I can get this working.

@groob
Copy link
Contributor

groob commented Oct 29, 2017

VerifyClientCertIfGiven will still request the certificate, so the user logging in to the UI will be prompted for a client certificate each time they refresh the page.

As mentioned in the discussion above, the hard part is not having the server ask for/verify a cert but the fact that TLS auth is applied globally per server:port not per HTTP route.

The correct answer to this issue is to use nginx or HAproxy in front of fleet and terminate all the osquery endpoints with TLS certificates.

@somethingnew2-0
Copy link

somethingnew2-0 commented Oct 29, 2017

From my experimentation with Chrome, Safari, and Firefox I don't see any browser prompting for a client certificate when using VerifyClientCertIfGiven or even when using RequireAndVerifyClientCert. The former allows the request through, while the latter doesn't. Maybe it's because I don't have any client certificates configured in my browsers?

@directionless
Copy link
Contributor

I don't think this is on our current agenda, so it does not seem worth keeping open.

@zwass Feel free to re-open if you'd rather keep it in that state.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants