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

Add endpoint option to authenticate by client tls cert. #461

Merged
merged 2 commits into from
Jul 21, 2016

Conversation

andersbetner
Copy link
Contributor

I have added authentication by client certificate as per #402
I haven't added any tests yet.

  1. Does this pullrequest look all right?
  2. I did not add an option for ClientAuthType. I just picked and hardcoded the most sensible default value: RequireAndVerifyClientCert
  3. Should I add tests by basically duplicating the TestWithSNIConfigHandshake and TestWithSNIConfigRoute and then add client certification + client cert and CA cert in fixtures?

@andersbetner andersbetner force-pushed the client_tls_auth branch 2 times, most recently from cbafb7d to 8074718 Compare June 17, 2016 07:05
@emilevauge emilevauge added this to the 1.1 milestone Jun 17, 2016
@emilevauge
Copy link
Member

Hi @andersbetner, thanks for your contribution :)
I have few comments:

  • as we are in the process of releasing the 1.0.0 version, this PR will land in the 1.1.0 version (in few weeks).
  • I think we need to be able to have multiple client SSL certs. It would be interesting to change type of ClientCAFile.ClientCAFile from string to Certificates (and rename it then):
type TLS struct {
    Certificates          Certificates
    ClientCertificates    Certificates
}

WDYT?

/cc @vdemeester @samber

@andersbetner
Copy link
Contributor Author

@emilevauge
Actually the cert-file can contain multiple certs.
I have added tests and clarified the documentation. (and changed the config parameter to ClientCAsFile).

The name ClientCAs is a bit of a misnomer, it doesn't hold client certificates. It contains the public key of one or more certificate authorities that you trust to sign client certs.
The client has to present a certificate that is signed by one of the CA:s in the ClientCAsFile.
I created two test cases where one has two CA:s in the ClientCAsFile.

Since this PR involves security it would be great if more than my pair of eyes could have a look at the code.

@vdemeester
Copy link
Contributor

Seems good to me 😉
I kinda agree with @emilevauge on the fact that we should allow multiple values for ClientCAs (that each could have more public key in each 😛).

@emilevauge
Copy link
Member

emilevauge commented Jun 20, 2016

@andersbetner

The name ClientCAs is a bit of a misnomer, it doesn't hold client certificates. It contains the public key of one or more certificate authorities that you trust to sign client certs.
The client has to present a certificate that is signed by one of the CA:s in the ClientCAsFile.
I created two test cases where one has two CA:s in the ClientCAsFile.

True, obviously we cannot reuse Certificates type here.

Actually the cert-file can contain multiple certs.

Even if a file can contain multiple keys, I think it would be simpler to not force users to do that. Besides, the std library as been designed with that in mind: CertPool.AddCert https://golang.org/pkg/crypto/x509/#CertPool.AddCert. A slice of keys would allow both use case :)

Since this PR involves security it would be great if more than my pair of eyes could have a look at the code.

As soon as we agree on design, we will make a deep code review :)

@andersbetner
Copy link
Contributor Author

@emilevauge , @vdemeester
I have no problem with a slice, I just didn't think of it. I was so colored by how Nginx ssl_client_certificate and Apache SSLCACertificateFile wants all CA:s in one file.

I had a look around and it seems like Caddy does it like you suggested.

Just to make sure I understand.
Is this what you meant?

type TLS struct {
    Certificates  Certificates
    ClientCAFiles []string
}
[entryPoints.https]
address = ":443"
ClientCAFiles = ["ca1.pem", "ca2.pem"]
[entryPoints.https.tls]
  [[entryPoints.https.tls.certificates]]
    CertFile = "integration/fixtures/https/snitest.com.crt"
    KeyFile = "integration/fixtures/https/snitest.com.key"

It is a pity that the authentication is forced on all SNI-certs on the same listener (by the go library), but I guess we are not alone there: Caddy issue #849

@emilevauge
Copy link
Member

@andersbetner: Seems good.
You will also have to modify the entryPoints command line parser to include these client certs:

--entrypoints Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key' (default "map[]")

@emilevauge
Copy link
Member

Hi @andersbetner, I'm planning to get this PR in the 1.1 releases. Do you think it's possible ?

@andersbetner
Copy link
Contributor Author

@emilevauge
Sure, I was waiting for the 1.0 release.
I will rebase and make the changes to the config and command line.
Should I squash all changes into just two commit one for the changes to the code and one for the documentation? (that it should I sqash my future changes into the existing commits or does it not matter?

@emilevauge
Copy link
Member

@andersbetner it would be better to squash your commits yes :)

@andersbetner
Copy link
Contributor Author

@emilevauge
Added support for multiple CA-files as discussed earlier.
Tell me if you would like anything changed.

@@ -32,6 +32,7 @@ They can be defined using:
- a port (80, 443...)
- SSL (Certificates. Keys...)
- redirection to another entrypoint (redirect `HTTP` to `HTTPS`)
- authentication with a client certificate signed by a trusted CA
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add this to the existing line SSL (Certificates. Keys...) :)

@andersbetner
Copy link
Contributor Author

@emilevauge
I managed to get the config right for the tests but not in the documentation...

  • Fixed according to your comments.
  • Squashed the commit.
  • Rebased on top of master.

@emilevauge
Copy link
Member

Thanks @andersbetner !
Maybe we will change a bit https://github.com/containous/traefik/pull/461/files#diff-bee1b19602a9f84a06f44e111f79a479R96 in a futur PR. I'm not totally convinced by how we manage flags with entrypoints...
LGTM!

/cc @containous/traefik

@andersbetner
Copy link
Contributor Author

@emilevauge
Great, yeah I just made my addition to the flag syntax up. I have no problem with it being changed to something clearer.

@andersbetner
Copy link
Contributor Author

@emilevauge
Rebased

@emilevauge
Copy link
Member

/cc @containous/traefik

@vdemeester
Copy link
Contributor

LGTM 🐯

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

Successfully merging this pull request may close these issues.

4 participants