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

Deprecate cert gen without a CA and add self-signed option #64037

Merged
merged 16 commits into from
Nov 29, 2020

Conversation

ywangd
Copy link
Member

@ywangd ywangd commented Oct 22, 2020

Generating a CA on the fly is an attempt at workflow optimisation that was inherited from certgen. There are potential pitfalls with this approach. Overall it is recommended to separate the step of CA creation and mandate a CA to be specified when generating certificate.

This PR add a deprecation message if the cert command is used without specifying a CA. A follow up PR will throw error for this usage in 8.0.

For use case where we explicitly trust a certificate without needing a CA, e.g. SAML message signing, the PR adds a --self-signed option to the cert sub-command to generate self-signed certificate.

Relates: #61884

@ywangd ywangd added >enhancement :Security/Security Security issues without another label v8.0.0 v7.11.0 labels Oct 22, 2020
@ywangd ywangd requested a review from tvernum October 22, 2020 08:20
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-security (:Security/Security)

@elasticmachine elasticmachine added the Team:Security Meta label for security team label Oct 22, 2020
@ywangd
Copy link
Member Author

ywangd commented Oct 22, 2020

@lcawl
Copy link
Contributor

lcawl commented Oct 22, 2020

Does the example in this section of the SAML guide need to be updated to use a CA too?: https://www.elastic.co/guide/en/elasticsearch/reference/master/saml-guide-authentication.html#_generating_certificates_and_keys

Copy link
Contributor

@lcawl lcawl left a comment

Choose a reason for hiding this comment

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

One comment, otherwise LGTM

@jkakavas
Copy link
Member

Does the example in this section of the SAML guide need to be updated to use a CA too?: https://www.elastic.co/guide/en/elasticsearch/reference/master/saml-guide-authentication.html#_generating_certificates_and_keys

In SAML we don't use PKI but explicit trust of certificates so keeping the CA keys around is not necessary. This was actually one of the cases where the behavior we are now deprecating and removing was helpful and made sense. Instead of doing a 2 step process just for the sake of using certutilhere, could we have an example with openssl ?

@tvernum
Copy link
Contributor

tvernum commented Oct 26, 2020

Is it worth adding a --self-signed option to certutil cert to cater for the SAML use case?

@ywangd
Copy link
Member Author

ywangd commented Oct 26, 2020

This was actually one of the cases where the behavior we are now deprecating and removing was helpful and made sense. Instead of doing a 2 step process just for the sake of using certutilhere, could we have an example with openssl ?

Thakns for this info. For me, replacing it with openssl has a few downsides:

  • Introduces another dependency. IIUC, elasticsearch-certutil was created to (at least partially) avoid having to use openssl. So would it feel backwards if we have to turn back to openssl?
  • Most other places (if not all) uses openssl, so it is inconsistent.
  • As I understand it, openssl has some inconsistency/installation issues across different OS (though it may not be an issue for the req command that we need here).
  • The existing saml-guide doc page needs some more wording changes to accomodate the openssl replacement

Is it worth adding a --self-signed option to certutil cert to cater for the SAML use case?

This is plausible when you need only a single cert. However, it could be problematic when creating multiple certificates. If users try to use it this for multiple nodes, it will at least cause confusion. We could forbid generating mulitple certs if --self-signed is requested. But even with that, it could still cause confusion in a TLS context, since our docs differentiate between cert and CA most of the times (if not all the time). There is also a minor difference between using two calls (ca and cert, or cert with on the fly CA) and self-signed certificate. The self-signed cert has TRUE value for the CA attribute while the other one has it as FALSE. I don't think it really matter in our use case. Just bring it up in case there are unobvious issues.

So given the above information, I wonder whether we should re-evaluate our decision on this issue, i.e. whether we should disallow generating CA on the fly entirely? By disallowing it, two-step process is always required to generate CA and certs. Does it go against "easier security setup" idea that we try to uphold? Or will "security-on-by-default" provide a different solution to make this worry obsolete?

PS: Another place we generate CA and certs together is for configuring TLS in docker.

@jkakavas
Copy link
Member

Is it worth adding a --self-signed option to certutil cert to cater for the SAML use case?

This sounds like a good idea to me.

Introduces another dependency. IIUC, elasticsearch-certutil was created to (at least partially) avoid having to use openssl. So would it feel backwards if we have to turn back to openssl?

I don't see this as a dependency, but merely as a suggestion as to how one can generate a keypair (more?) easily if openssl is available. We can have instructions with certutil (only|too), it's just two commands instead of one.

The existing saml-guide doc page needs some more wording changes to accomodate the openssl replacement

Making changes is not a downside in my opinion.

As I understand it, openssl has some inconsistency/installation issues across different OS (though it may not be an issue for the req command that we need here).

I don't think there is any problematic behavior wrt to key/certificate generation ( especially for certificates that are merely public key containers )

However, it could be problematic when creating multiple certificates. If users try to use it this for multiple nodes, it will at least cause confusion

I think there is that much we can do to prevent misuse of the tools we create. In the same line of thinking, nothing prevents a user to generate a new CA and cert on each node if they are not familiar enough with PKI and certificates.

. But even with that, it could still cause confusion in a TLS context, since our docs differentiate between cert and CA most of the times (if not all the time)

Can you explain your concern?

The self-signed cert has TRUE value for the CA attribute while the other one has it as FALSE. I don't think it really matter in our use case

+1

So given the above information, I wonder whether we should re-evaluate our decision on this issue, i.e. whether we should disallow generating CA on the fly entirely? By disallowing it, two-step process is always required to generate CA and certs. Does it go against "easier security setup" idea that we try to uphold? Or will "security-on-by-default" provide a different solution to make this worry obsolete?

I don't think we should re-evaluate. Security on by default would probably not replace our existing tooling with other solutions and I don't see this as making it more difficult for users to set up TLS. The SAML use case affects a fraction of our users since a) request signing is not enabled by default and b) response encryption is not commonly used. I think that a --self-signed makes sense for the SAML case (or for a "I just want a quick key/certificate that I can set on my local node and I know what I'm doing" use case) but even if we don't add it, I expect that the users needing it might not depend on certutil to create their signing/encryption key pairs either way - or they will be ok issuing two certutil commands.

@ywangd
Copy link
Member Author

ywangd commented Oct 26, 2020

But even with that, it could still cause confusion in a TLS context, since our docs differentiate between cert and CA most of the times (if not all the time)

Can you explain your concern?

What I mean is that our docs talk about separate CA and cert in most places (if not all places). When configuring TLS, the examples have different values (files) for certificate_authorities and certificate (except for p12 truststore where it's an all-in-one). Self-signed certificate will be a new thing for our docs. I was wondering whether this could be confusing users because 1) certificate_authorities and certificate will have the same value when configuring TLS and 2) if we do want to explain it, feels like we will be adding docs just for something that is rarely recommended. These are minor concerns. I am actually not too worried about them. Just raise it as discussion point.

Based on the discussion, I think a new --self-signed option is the way to go. I think it makes sense for it to be part of this PR. Will work on it.

@ywangd
Copy link
Member Author

ywangd commented Nov 4, 2020

@tvernum @lcawl @jkakavas The latest push added the --self-signed option as discussed, also updated relevant docs. Could you please take another look? Thanks!

@ywangd ywangd requested review from lcawl and jkakavas November 4, 2020 05:48
Copy link
Member

@jkakavas jkakavas left a comment

Choose a reason for hiding this comment

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

Just a few comments and suggestions. Can we also update the PR description to mention the self-signed option?

docs/reference/commands/certutil.asciidoc Outdated Show resolved Hide resolved
docs/reference/commands/certutil.asciidoc Outdated Show resolved Hide resolved
docs/reference/commands/certutil.asciidoc Outdated Show resolved Hide resolved
@@ -505,11 +505,11 @@ support. Since PEM format is the most commonly supported format, the examples
below will generate certificates in that format.

Using the <<certutil,`elasticsearch-certutil` tool>>, you can generate a
signing certificate with the following command:
self-signed certificate with the following command:
Copy link
Member

Choose a reason for hiding this comment

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

The most important characteristic is that this is a signing certificate (used to sign SAML messages), not that it is a self-signed one. I'd suggest we revert this change

Copy link
Member Author

Choose a reason for hiding this comment

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

You are right. Reverted.

x-pack/docs/en/security/authentication/saml-guide.asciidoc Outdated Show resolved Hide resolved
@@ -807,7 +819,8 @@ void generateAndWriteSignedCertificates(Path output, boolean writeZipFile, Optio
} else {
final String fileName = entryBase + ".p12";
outputStream.putNextEntry(new ZipEntry(fileName));
writePkcs12(fileName, outputStream, certificateInformation.name.originalName, pair, caInfo.certAndKey.cert,
writePkcs12(fileName, outputStream, certificateInformation.name.originalName, pair,
Copy link
Member

Choose a reason for hiding this comment

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

I also think we don't need to add a certificate entry too when we create a self-signed PKCS12, but did we check?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a good point and it turns out the check is missing ...
I now augumented testCreateCaAndMultipleInstances to test p12 generation for self-signed cert.

Copy link
Member

Choose a reason for hiding this comment

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

My point was actually about the construction of the PKCS#12 bundle and whether or not it suffices to add a private key entry with the key and certificate, or if we also need to add a trusted certificate entry with the certificate too. I believe we don't and other tooling ( keytool, openssl ) seem to agree too :)

Copy link
Contributor

@tvernum tvernum left a comment

Choose a reason for hiding this comment

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

Sorry, It looks like I had these comments pending for a week or so & didn't submit them...

@@ -211,6 +217,9 @@ wish to password-protect your PEM keys, then do not specify
`--pem`:: Generates certificates and keys in PEM format instead of PKCS#12. This
parameter cannot be used with the `csr` parameter.

`--self-signed`:: Generates self-signed certificates. This parameter is only
applicable to the `cert` parameter.
Copy link
Contributor

Choose a reason for hiding this comment

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

I have a concern, which might not be a big deal, that some people will see this option and use it in places where they shouldn't.
For all TLS scenarios, we recommend having a separation between the CA and the node cert, and I think we want to keep recommending that.
So, are there words we can put here that discourage people from using it for TLS?

Copy link
Member Author

Choose a reason for hiding this comment

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

I added a note to state this option should be used with care.

@@ -505,11 +505,11 @@ support. Since PEM format is the most commonly supported format, the examples
below will generate certificates in that format.

Using the <<certutil,`elasticsearch-certutil` tool>>, you can generate a
signing certificate with the following command:
self-signed certificate with the following command:
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this should change. It is a signing certificate, it just happens to also be self-signed.

Copy link
Member Author

Choose a reason for hiding this comment

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

You are right. Ioannis said the same. It's reverted. Thanks.

@@ -167,8 +167,9 @@ public static void main(String[] args) throws Exception {

static final String CA_EXPLANATION =
" * All certificates generated by this tool will be signed by a certificate authority (CA).\n" +
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't strictly true anymore. Do we care?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ioannis has kindly offered suggestion and it should be accurate now.

Co-authored-by: Ioannis Kakavas <ikakavas@protonmail.com>
Copy link
Member

@jkakavas jkakavas left a comment

Choose a reason for hiding this comment

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

LGTM, I'll defer more scrutiny of the wording changes to Lisa and Tim

@@ -807,7 +819,8 @@ void generateAndWriteSignedCertificates(Path output, boolean writeZipFile, Optio
} else {
final String fileName = entryBase + ".p12";
outputStream.putNextEntry(new ZipEntry(fileName));
writePkcs12(fileName, outputStream, certificateInformation.name.originalName, pair, caInfo.certAndKey.cert,
writePkcs12(fileName, outputStream, certificateInformation.name.originalName, pair,
Copy link
Member

Choose a reason for hiding this comment

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

My point was actually about the construction of the PKCS#12 bundle and whether or not it suffices to add a private key entry with the key and certificate, or if we also need to add a trusted certificate entry with the certificate too. I believe we don't and other tooling ( keytool, openssl ) seem to agree too :)

…ck/security/cli/CertificateTool.java

Co-authored-by: Ioannis Kakavas <ikakavas@protonmail.com>
@tvernum tvernum changed the title Deprecate certificate genereation without specifying a CA Deprecate certificate generation without specifying a CA Nov 18, 2020
All certificates that are generated by this command are signed by a CA unless
the `--self-signed` parameter is specified. You can provide your own CA with the
`--ca` or `--ca-cert` and `--ca-key` parameters. Otherwise, the command automatically generates a new CA for you.
deprecated:[7.11.0,"Generating certificates without specifying a CA certificate and key is deprecated. In the next major version you must provide a CA certificate unless the `--self-signed` option is specified."]
Copy link
Contributor

Choose a reason for hiding this comment

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

deprecated:[7.11.0,"Generating certificates without specifying a CA certificate and key is deprecated. In the next major version you must provide a CA certificate unless the --self-signed option is specified."]

I've combined this information into a single paragraph so that it's (hopefully) clearer what's deprecated.

…ck/security/cli/CertificateTool.java

Co-authored-by: Lisa Cawley <lcawley@elastic.co>
GenerateCertificateCommand() {
super("generate X.509 certificates and keys");
acceptCertificateGenerationOptions();
selfSigned = parser.accepts("self-signed", "generate self signed certificates (takes precedence over the ca options)");
Copy link
Contributor

Choose a reason for hiding this comment

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

Why would this take precedence rather than being an error?

If a user enters

certutil cert --ca foo.p12 --self-signed

that's contradictory, and I would expect it to be an error, but it actually would generate a self signed cert, and ignore the CA. That seems wrong to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, Thanks. I misunderstood the existing behaviour of --ca and --ca-cert. The two plus the new --self-signed should be mutually exclusive. It is now fixed.

ywangd and others added 3 commits November 20, 2020 22:59
@ywangd ywangd requested a review from tvernum November 20, 2020 12:34
Copy link
Contributor

@tvernum tvernum left a comment

Choose a reason for hiding this comment

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

LGTM

@ywangd ywangd changed the title Deprecate certificate generation without specifying a CA Deprecate cert gen without a CA and add self-signed option Nov 29, 2020
@ywangd ywangd merged commit bdd99b2 into elastic:master Nov 29, 2020
ywangd added a commit to ywangd/elasticsearch that referenced this pull request Nov 29, 2020
…4037)

Generating a CA on the fly is an attempt at workflow optimisation that was
inherited from certgen. There are potential pitfalls with this approach. Overall
it is recommended to separate the step of CA creation and mandate a CA to be
specified when generating certificate.

This PR add a deprecation message if the cert command is used without specifying
a CA. A follow up PR will throw error for this usage in 8.0.

For use case where we explicitly trust a certificate without needing a CA, e.g.
SAML message signing, the PR adds a --self-signed option to the cert sub-command
to generate self-signed certificate.
ywangd added a commit that referenced this pull request Nov 29, 2020
…65575)

Generating a CA on the fly is an attempt at workflow optimisation that was
inherited from certgen. There are potential pitfalls with this approach. Overall
it is recommended to separate the step of CA creation and mandate a CA to be
specified when generating certificate.

This PR add a deprecation message if the cert command is used without specifying
a CA. A follow up PR will throw error for this usage in 8.0.

For use case where we explicitly trust a certificate without needing a CA, e.g.
SAML message signing, the PR adds a --self-signed option to the cert sub-command
to generate self-signed certificate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>deprecation :Security/Security Security issues without another label Team:Security Meta label for security team v7.11.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants