Import CA Cert as PrivateKeyEntry to HTTP Keystore - Solve Unable to create enrollment token Error

Problem

Yesterday I installed Elasticsearch for the first time, and after I configured the security manully according to the docs: Basic Security / Basic Security plus HTTPS, I try to generate token for Kibana, and I met the error:

ERROR: Unable to create an enrollment token. Elasticsearch node HTTP layer SSL configuration Keystore doesn't contain any PrivateKey entries where the associated certificate is a CA certificate

I searched some pages and didn't get the answer, then I found a discussion on StackOverflow, and it solved my problem. I think maybe I should share my experience with those newbies like me.


Solution

Step 1. Generate Keystore contains CA Cert and HTTP Keystore [optional]

Note: Usually we have done this step, so if you didn't do anything else to change these Keystores, skip this step.

Following Basic Security we will get a PKCS12 Keystore containing CA Cert, default filename is elastic-stack-ca.p12.

Following Basic Security plus HTTPS, we will get a PKCS12 Keystore contains a TrustedCertEntry that import from elastic-stack-ca.p12, the default filename of HTTP Keystore is http.p12.

Step 2. Import CA Cert Keystore to HTTP Keystore as PrivateKey type

keytool -importkeystore -destkeystore <filename-http-PKCS12> -srckeystore <filename-PKCS12-contains-CA-Cert.p12> -srcstoretype PKCS12

This step changes the CA Cert that was automatically imported into the original HTTP Keystore as TrustCertEntry to PrivateKeyEntry, and this is exactly what that ERROR tells us to do.

Importing keystore config/certs/es-ca.p12 to config/certs/http.p12...
Enter destination keystore password:
Enter source keystore password:
Existing entry alias ca exists, overwrite? [no]: yes
Entry for alias ca successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled

Check the result

And you can use following command to check:

keytool -keystore <filename-HTTP-PKCS12.p12> -list

The result should contains two PrivateKey entries like:

Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 2 entries

ca, Sep 5, 2022, PrivateKeyEntry,
Certificate fingerprint (SHA-256): 53:F4:9A:9D:56:A9:3A:AF:90:94:41:FA:D7:15:3F:DF:C1:39:AC:BA:FF:12:44:C0:36:4D:15:4C:20:14:1E:3D
http, Sep 5, 2022, PrivateKeyEntry,
Certificate fingerprint (SHA-256): EF:8D:78:EC:F0:C5:97:1B:7B:58:EF:5F:E3:73:A5:D0:7E:1B:FE:B3:75:B0:B4:D9:CB:80:FC:B3:8E:5D:A5:74

Before generating a new token, make sure you added the password for your private key to the security settings in Elasticsearch.

./bin/elasticsearch-keystore [show|add] xpack.security.http.ssl.keystore.secure_password

Re-Generate token

Now start the node, and re-generate your token:

./bin/elasticsearch-create-enrollment-token -s [kibana|node]
1 Like

@aold619 Did you test whether the generated enrollment-token is usable by Kibana?

I suspect it won't be usable because you added another (different) CA key/cert into the HTTP truststore. This makes the token generation process work. But the token will be generated with the CA that is not the one that signs your HTTP cert. Hence Kibana will fail to validate the HTTPS connection to Elasticsearch.

What you want is to add original CA's key to the truststore. The original CA is the one that you used to generate the http certs with the command ./bin/elasticsearch-certutil http. Maybe this is what you actually did? If so, could you please clarify this in Step 1?

Btw, we have a public issue to track this problem Generating enrolment token for Kibana should not require the CA key · Issue #89017 · elastic/elasticsearch · GitHub

2 Likes

@Yang_Wang
Thank you for correcting me! And sorry I posted this directly without further verification.

I can't connect Kibana, you're right. The following content is my fix.

For Step 1, I should generate HTTP PKCS follow Basic Security plus HTTPS, then use cmd in Step 2 to import previous PKCS generated by Basic Security to the HTTP PKCS

keytool -importkeystore -destkeystore <filename-your-http-PKCS-12> -srckeystore <filename-new-PKCS-12.p12> -srcstoretype PKCS12

Overwrite the existing entry:

Importing keystore config/certs/es-ca.p12 to config/certs/http.p12...
Enter destination keystore password:
Enter source keystore password:
Existing entry alias ca exists, overwrite? [no]: yes
Entry for alias ca successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled

Now if we check the http.p12, the default ca, TrustedCert Entry will become ca, PrivateKey Entry.

Enter keystore password:
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 2 entries

ca, Sep 7, 2022, PrivateKeyEntry,
Certificate fingerprint (SHA-256): 6D:19:EA:C5:37:FC:4B:4B:3C:34:43:E8:71:5C:2B:22:F3:E5:A0:23:B2:F8:91:51:D4:6E:C1:34:66:6E:49:42
http, Sep 7, 2022, PrivateKeyEntry,
Certificate fingerprint (SHA-256): 0D:F9:57:C6:DB:E6:93:31:3D:12:46:82:FE:EA:7F:AE:23:05:C2:49:A3:5A:7B:77:61:1A:2F:F2:E7:B3:DF:6D

I verified that bin/elasticsearch-create-enrollment-token is working, and I can also use this generated token to connect to Kibana.


Please review my fix step, and if it is correct, should I edit my main post to fix the error?

1 Like

Your fix looks correct to me.

That would be great. Thanks!

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.