-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Support for per-vu TLS configuration (grpc.Client.connect only) #3159
Support for per-vu TLS configuration (grpc.Client.connect only) #3159
Conversation
…nd custom (self-signed) RootCAs You can now use self-signed ca-certificates when authenticating with TLS. Using the `cacerts` property of an options `tlsAuth` object, you can now indicate the CA certificate(s) that k6 will use to verify the server certificates your tests will access. CA certificates must be in `pem` format and multiple CA certificates can be included. ```javascript export const options = { tlsAuth: [ { cacerts: [open("cacerts.pem")], cert: open("cert.pem"), key: open("cert-key.pem"), password: "cert-passphrase", domains: ["grpcbin.test.k6.io"], // Deprecated }, ], }; ``` You can also now use per-vu TLS configuration on `grpc.Client` `connect` params. Previously, `grpc.Client` `connect` made use of a shared (immutable) `tls.Config` cloned into every VU. Now, the `connect` `params` argument can contain a `tlsconfig` key that maps to the `TLSAuth` struct. This will create a per-vu TLS configuration for the `grpc.Client` allowing you to connect to multiple mTLS endpoints in a single VU. Note: the global tls.Config will remain unmodified. ```javascript const params = { plaintext: false, tlsconfig: { cacerts: ["cacerts.pem"], cert: "cert.pem", key: "key.pem", password: "cert-passphrase", domains: ["grpcbin.test.notk6.io"], // Deprecated } }; const hostPort = "grpcbin.test.notk6.io:9001"; const client = new grpc.Client(); client.connect(hostPort, params); ```
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.
Hi there, thanks a lot for this PR! 🙇
I think it makes sense to do this for the gRPC client, but I'm not so sure about the global tlsAuth
change. And I'd like to see some gRPC tests for this.
Added tests around tls password and encrypted certificate key
Thank you for your feedback @imiric. I've addressed all of the feedback requests and added some (admittedly not 100% coverage) test cases for the new connectParams (I've also modified the PR description and title to reflect the narrower scope of this). Please let me know what more I can do to facilitate this PR. I noticed the |
…alhostKey and localhostEncryptedKey. (Used the same approach `net/http/internal/testcert/testcert.go` uses)
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 in general! Thanks for the contribution 🙇
I have left a bunch of change requests and some questions.
My two concerns (which are not inline) are:
- Organizational - we now have an experimental grpc module where we have some changes. This change will now need to be transfered there. While we might've prefered it the other way around. cc @olegbespalov
- API one - k6 has problems with big files arguably with the handling of any files to be honest, just big ones make it worse. This particular case seems okay to me. Especially if users figure out how to load the key/cert once . Whihc arguably is doable with a SharedArray with element per each cert+key+password. My other problem is that currently you went with the
key
andcert
being strings instead of binary data. Which I guess is based on what formats golang supports? I do ask the same question inline.
And both of those questions could've been answered if we had an issue to discuss this before hand.
p.s. Your example in the description shows "cert" (and all the other big options) as what looks like file names. But they are actually the contents of those. I would prefer to have the example either just use open("./cert.pem")
or be the string (with a lot of ...
) that is the actual contents. As in this way it is confusing for both me as reviewer and likely anyone else who in the future tries to figure out what was added here.
Nice catch. Thank you. Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com>
Nice catch. Thank you. Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com>
Added positive and negative test cases for grpc client connect with tls parameter
Update js/modules/k6/grpc/client.go lib/options.go should also be updated Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com>
…ith-rootcas' into feature/per-vu-grpc-tls-config-with-rootcas
I've updated my trivial examples with |
I believe I've addressed all of the feedback so far. Please let me know what else I can do to prepare this for v0.46.0. |
Unsure why the test passes locally but fails in CI
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! thanks for the contribution.
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, left a few non-blocking suggestions 👍
Thanks for the contribution!
Co-authored-by: Oleg Bespalov <olegbespalov@gmail.com>
c35a3b1
Co-authored-by: Oleg Bespalov <olegbespalov@gmail.com>
Co-authored-by: Oleg Bespalov <olegbespalov@gmail.com>
Co-authored-by: Oleg Bespalov <olegbespalov@gmail.com>
Co-authored-by: Mihail Stoykov <312246+mstoykov@users.noreply.github.com>
af7770c
I approved the requested changes but unfortunately one of them broke a couple tests :) I've fixed them I believe. Sorry for the ping-pong! |
For future reference while squashing the changes I did delete the mention of the global But unfortunately did not fix the example to use the actual contents of a pem file and instead it still has the pem file name 🤦 . This likely doesn't really matter as both the current PR body and any documentation will have this correct. |
I updated the example to use “open”. 🤔On Jul 12, 2023, at 12:07 PM, Mihail Stoykov ***@***.***> wrote:
For future reference while squashing the changes I did delete the mention of the global tlsAuth.
But unfortunately did not fix the example to use the actual contents of a pem file and instead it still has the pem file name 🤦 .
This likely doesn't really matter as both the current PR body and any documentation will have this correct.
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: ***@***.***>
|
@chrismoran-mica I should've been more specific. This wasn't your fault. Arguably you could've changed the commit message and force pushed, but I would probably also forget to do it or not even think of it. I should've just been more careful and arguably just written a completely knew message when squashing. It is my fault |
* This is a port of the PR changes found here: grafana/k6#3159 Note: The bad auth/bad certificate tests appear to be very inconsistent. In grafana/k6 I had to remove the timeout for them to pass in CI. Removing the timeout in grafana/xk6-grpc caused the tests to fail locally. This may need to be investigated or a bug raised to determine if k6 is not raising grpc connection errors on bad authentication until context deadline.
What? and Why?
You can now use per-vu TLS configuration on
grpc.Client
connect
params. Previously,grpc.Client
connect
made use of a shared (immutable)tls.Config
cloned into every VU. Now, theconnect
params
argument can contain atls
key that loosely resembles theTLSAuth
struct. This willcreateallow a per-vu TLS configuration for thegrpc.Client
* allowing you to connect to multiple mTLS endpoints in a single VU. Note: the global tls.Config will remain unmodified.*Note: the
grpc.Client
, onceconnect
ed will utilize the param tlsconfig regardless of the VU that uses thegrpc.Client
. In order to truly have per-vu tls configuration steps must be taken on the test to ensure each VU uses thegrpc.Client
with its custom tlsconfig.For example, in my use case I use multiple VUs to connect to a configurable number of endpoints. Each of these endpoints are mTLS secured with potentially different CA-signed certificates. Each VU will use the
grpc.Client
with the tlsconfig targeting the relevant endpoint. As an implementation of this may not be obvious, I've included a trivial example below. Allowing different VUs to use different endpoint values I assume is trivial (or it can be considered an exercise for the reader).HINT: one way would be to load a
SharedArray
(orSharedArray
s) with shards of data. Each index in theSharedArray
(s) would be used by aVU
. So if you have 10 sets of data and run 10VU
s, you can have eachVU
pull from their own index in theSharedArray
s.Usage:
Checklist
I have added tests for my changes.make lint
) and all checks pass.make ci-like-lint
) and all checks pass.make tests
) and all tests pass.Related PR(s)/Issue(s)
This PR does not close an issue but it does reference at least one conversation about per-vu mTLS: https://community.k6.io/t/grpc-mtls-per-vu-iteration/1868