Skip to content
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 mutual TLS #39

Closed
AustinC opened this issue Feb 11, 2021 · 14 comments
Closed

Support for mutual TLS #39

AustinC opened this issue Feb 11, 2021 · 14 comments
Assignees

Comments

@AustinC
Copy link

AustinC commented Feb 11, 2021

Is there a way to communicate with a docker engine that requires mutual TLS connections?
Thanks for your efforts on this library.

@lispyclouds
Copy link
Collaborator

Thanks! It should be possible as mentioned in https://github.com/into-docker/unixsocket-http#tls but I need to write the HTTPS protocol support into clj-docker-client first. I have some other issues to push in the coming days and will take this into account too! 😄

@lispyclouds lispyclouds self-assigned this Feb 12, 2021
lispyclouds added a commit that referenced this issue Feb 14, 2021
@lispyclouds
Copy link
Collaborator

lispyclouds commented Feb 14, 2021

@AustinC I have implemented the first version of support for mTLS. It turned out to be much more complex than I anticipated 🙁
Could you have a look before I can be sure of it and make a release? Here are the steps to follow:

  • Clone this repo
  • Make a change in the version to 1.0.3
  • Build and install locally lein install
  • Have docker ready at lets say https://localhost:8000
  • Fetch the private key, cert and the CA file from docker, I was using docker-in-docker to test and they are in /certs/client/ca.pem(CA) /certs/client/key.pem(private key) and /certs/client/cert.pem(cert)
  • Generate a pkcs12 cert from the private key and cert, using openssl: openssl pkcs12 -export -inkey key.pem -in cert.pem -out mtls.p12. Hit enter 2x for not setting a password.
  • Fire up a clojure REPL with lispyclouds/clj-docker-client 1.0.3 loaded
  • Make a client like in the docs but with :mtls options like:
    (def http-tls-ping
      (client {:category :_ping
               :conn     {:uri  "https://localhost:8000"
                          :mtls {:ca       "ca.pem"
                                 :key      "mtls.p12"
                                 :password ""}}}))
  • Invoke the ping, this should return "OK"
    (invoke http-tls-ping {:op :SystemPing})
  • Try out other stuff if those things works too?

Any feedback here would be really helpful for me specially around your user experience and if you have better ideas please do share! This seems to be weirdly complex.

@lispyclouds
Copy link
Collaborator

@xsc Do you have some better ideas for this implementation? Would be really helpful if you do! 😄

lispyclouds added a commit that referenced this issue Feb 14, 2021
lispyclouds added a commit that referenced this issue Feb 14, 2021
@xsc
Copy link
Member

xsc commented Feb 14, 2021

@lispyclouds At the very least we should not require users to convert between key formats, I think. :)

I've previously (5 years ago!) written a pem-reader which I now pulled into the into-docker organization (release is still pending, though). The caveat with that one would be that it does not yet support passphrases. :/

But there are other libraries we could have a look at, e.g. pem-keystore. Most of the ones I've seen pull in BouncyCastle, which is a comparatively large dependency.

(And generally, once stable, we might want to consider extracting the :builder-fn creation functionality into a tiny utility library, since that would allow us to use it in other contexts.)

@xsc
Copy link
Member

xsc commented Feb 14, 2021

Using pem-reader and okhttp-tls for mTLS/TLS to use the files produced by docker:dind: into-docker/unixsocket-http#7

@lispyclouds
Copy link
Collaborator

@xsc This is awesome! I definitely think this is better and we should work with the pems produced by docker. I could not get a good way of loading those pems with java/clj given my limited knowledge on these formats 🙁 Also since this is kinda docker specific, would it make sense to implement this as part of this rather than unixsocket-http?

@xsc
Copy link
Member

xsc commented Feb 15, 2021

@lispyclouds I'd not have it in unixsocket-http, which is why I was thinking of maybe making it a tiny utility library. However, I'd be perfectly fine with battle-testing it in clj-docker-client, and if there ever is a big wave of requests to make it standalone, let's do it. 😄

Ah, and don't forget the caveat about passphrases not being supported - that could be a problem.

@lispyclouds
Copy link
Collaborator

lispyclouds commented Feb 15, 2021

@xsc I too am thinking of using the pem-reader as a dep in clj-docker-client and yes let it rip for a while. And do the lib pulling and maybe the password support when needed. I pull in the code you wrote as an example with the pem-reader dep. Would you make it 1.0.0? Or should we go ahead with the SNAPSHOT release?

I guess expecting a non password protected key is less intrusive than a whole different format 😄

@xsc
Copy link
Member

xsc commented Feb 15, 2021

Let me make some last adjustments tonight, then I'll release 1.0.0.

@lispyclouds
Copy link
Collaborator

Awesome! I'll get the code ready in the meantime.

lispyclouds added a commit that referenced this issue Feb 15, 2021
@lispyclouds
Copy link
Collaborator

lispyclouds commented Feb 15, 2021

@AustinC the simpler version of the code is pushed now, similar to the above comment, the steps to test are:

  • Clone this repo
  • Make a change in the version to 1.0.3
  • Build and install locally lein install
  • Have docker ready at lets say https://localhost:8000
  • Fetch the private key, cert and the CA file from docker, I was using docker-in-docker to test and they are in /certs/client/ca.pem(CA) /certs/client/key.pem(private key) and /certs/client/cert.pem(cert)
  • Fire up a clojure REPL with lispyclouds/clj-docker-client 1.0.3 loaded
  • Make a client like in the docs but with :mtls options like:
      (def http-tls-ping
      (client {:category :_ping
               :conn     {:uri  "https://localhost:8000"
                          :mtls {:ca   "ca.pem"
                                 :key  "key.pem"
                                 :cert "cert.pem"}}}))
  • Invoke the ping, this should return "OK"
    (invoke http-tls-ping {:op :SystemPing})
  • The caveat here ls password protected PEM files aren't supported yet, can think of it if needed.

When @xsc is ready with the 1.0.0 release of pem-reader, I can cut the 1.0.3 release of this.
Happy testing! 😄

@AustinC
Copy link
Author

AustinC commented Feb 16, 2021

@lispyclouds
My organization has docker engines secured following the instructions here: https://docs.docker.com/engine/security/protect-access/#use-tls-https-to-protect-the-docker-daemon-socket
On the client side this results in three .pem formatted files, just like in your last example, so this API looks good to me.
If we are able to test this pre-release I will surely let you know.
Thanks, -Austin

@lispyclouds
Copy link
Collaborator

@AustinC this is great to hear! If possible could you share maybe how you folks are using the lib? That would be of great help in improving the usability of this!

@lispyclouds
Copy link
Collaborator

Implemented in 1.0.3

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

No branches or pull requests

3 participants