-
Notifications
You must be signed in to change notification settings - Fork 162
Support TLS for Elasticsearch and Additional YAML for Kibana #187
Conversation
src/scripts/kibana-install.sh
Outdated
echo "elasticsearch.ssl.certificate: /etc/kibana/ssl/elasticsearch-http.crt" >> $KIBANA_CONF | ||
# A user may provide a certificate that would fail full verification mode, | ||
# so default to certificate mode which verifies that the provided certificate is signed | ||
# by a trusted authority (CA), but does not perform any hostname verification. |
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.
I think the template should take an optional CA certificate elasticsearchCaCertificate
and use certgen
to generate the elasticsearch node's HTTP and Transport certificates. This way we do not have to lower the verification mode.
Reusing the same HTTP/Transport certificate for multiple nodes is not something we should promote.
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.
To do that, you'd need to have the key for the CA, which is unlikely to be the case if they're using an existing CA.
For transport our recommendation is to have a cluster-specific CA. But for HTTP, there's a good chance they'd want to use their own CA so that their HTTP clients are already configured to trust it.
Using PKCS#12 for trust is little tricky. If the There's way around it - you could work out that the p12 doesn't have CA entries and add them, or fail. Or we could add a way to provide CAs separately. I'm just not sure if it's going to be a problem for Azure. |
0d506b5
to
edf5160
Compare
This commit adds support for securing HTTP and Transport layers with PKCS#12 archive certificates. This allows easier configuration for a cluster that has a commercial license.
This commit adds certificate verification mode for TLS for Http and Transport layer. Since a user can supply a certificate that would fail full verification mode, default to certificate mode.
This commit always passes the password for a PKCS#12 archive cert to openssl, to convert to PEM format, even when the password is an empty string. Use the insecure flag when calling localhost over HTTPS with curl. Since the subject name in certificate used to secure the HTTP layer may not match host name localhost (it's likely to be tied to a public domain name), the --cacert flag for curl cannot be used.
This commit sets elasticsearch.ssl.verify: false for Kibana 5.2.0 and older. Kibana connects to Elasticsearch through an internal load balancer IP address which will likely fail verification which will also verify hostname, so disable verification by default for these versions.
This commit adds detail to specify that the Kibana cert and key are in PEM format. Support PKCS#12 archive in future would be useful.
This commit updates integration tests to use the parameters-file argument to pass the parameters to azure cli. Since parameters can now contain base 64 encoded certificates, the input can be longer than the maximum characters allowed in Windows (8192). Add generated certificates for integration tests.
This commit adds a --test parameter to be able to filter the integration tests that should be run. The parameter value is a regular expression string.
Include additional parameters in README. Add notes for additional arguments for npm run test
This commit adds the certificate CA to requests made in integration tests
This commit changes the integration test that tests the yaml configuration parameters to whitelist any indices starting with a dot; the .security index is too restrictive for the indices created by alerting/watcher.
This commit removes the hostname verification check used by the node's request module. Since all certs used are self-signed, hostname verification will fail. Tests still verify the CA.
This commit adds a --nodestroy parameter that when passed, does not delete resource groups after integration tests
@Mpdreamz @elastic/es-security This PR is now ready to review again. Some important points:
The following changes have been made:
Versions of Elasticsearch and Kibana less than 5.3.0 have been removed from the template as they are either EOL or very soon to be EOL. The changes of most pertinence are the handling and configuration of certs in elasticsearch-ubuntu.install.sh and kibana-install.sh |
Since last review, I've rebased from |
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
Do we need esTransportSecurity
though wether esTransportCaCertBlob
is specified or not could toggle whether to self sign or not.
Same for esHttpSecurity
do we want to support No
and no esHttpCertBlob
?
|
||
if [[ -f $BIN_DIR/elasticsearch-certutil || -f $BIN_DIR/x-pack/certutil ]]; then | ||
local CERTUTIL=$BIN_DIR/elasticsearch-certutil | ||
if [[ ! -f $CERTUTIL ]]; then |
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.
👍 was looking for version checks but this is better.
@@ -146,13 +190,16 @@ posts for further information | |||
</td><td><code>Standard_A2</code></td></tr> | |||
|
|||
<tr><td>kibanaCertBlob</td><td>string</td> | |||
<td>A Base-64 encoded form of the certificate (.crt) to secure HTTPS communication between the browser and Kibana.</td><td><code>""</code></td></tr> | |||
<td>A Base-64 encoded form of the certificate (.crt) in PEM format to secure HTTPS communication between the browser and Kibana.</td><td><code>""</code></td></tr> |
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.
A PEM certificate will always be a base64 encoded DER certificate so Base-64 encoded form
sounds superfluous I think
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.
I agree that PEM will already be base 64, but I'd like to keep the description here for consistency, and think it's a good idea to keep the process for including certs consistent across all the cert parameters i.e. as a consumer of the template, if I need to add certs in whatever format, I know that I always need to base 64 encode the contents and pass that as the parameter.
I'll add an example to the README of how to pass certificates to the template, to make it clear.
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.
i.e. as a consumer of the template, if I need to add certs in whatever format
Then maybe it's worth stating that we support other formats? Indeed Elasticsearch supports reading DER encoded certificates. Then again, as a consumer, if I have a DER certificate and I need to Base64 encode it in order to use it in the template, I am effectively converting it to a PEM certificate, so in essence we do only support PEM certificates.
Just a comment though, not a request for an additional change. I'd write this differently, but I don't have a so strong opinion on how it should be written here.
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.
Perhaps it would be more clear if I remove the in PEM format
part, and leave as before? This way, whether providing a PEM cert or DER cert, so long as it's base 64 encoded (I appreciate that PEM is already base 64 😃), the certificate will work.
|
||
<tr><td>kibanaKeyBlob</td><td>securestring</td> | ||
<td>A Base-64 encoded form of the private key (.key) to secure HTTPS communication between the browser and Kibana.</td><td><code>""</code></td></tr> | ||
<td>A Base-64 encoded form of the private key (.key) in PEM format to secure HTTPS communication between the browser and Kibana.</td><td><code>""</code></td></tr> |
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.
Again PEM keys will always be Base64 encoded.
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.
Similar to #187 (comment)
I'll add an example to the README of how to pass certificates to the template, to make it clear.
README.md
Outdated
</td><td><code>No</code></td></tr> | ||
|
||
<tr><td>esHttpCertBlob</td><td>string</td> | ||
<td>A Base-64 encoded form of the PKCS#12 archive (.p12/.pfx) certificate to secure communication for HTTP layer to Elasticsearch. <strong>X-Pack plugin must be installed</strong> |
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.
I assume you don't want to pass the PKCS#12 Keystores as Base64 encoded strings but rather pass the file directly as a param right ? This goes for the rest of the settings below.
Rephrase to something like: A PKCS#12 archive (.p12/.pfx) containing the key and certificate needed to secure communication for the HTTP layer of Elasticsearch ?
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.
The PKCS#12 archives need to be base 64 encoded as all parameters are passed over HTTP to the template, whether the template is part of a Marketplace offering or hosted publicly.
If we end up exposing the ability for users to upload certificate files in the Azure Marketplace UI, The file upload control will base 64 encode content to pass it to the template
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.
Just re-read this comment. I'll update the description to make it more clear.
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.
My point here is that the way it is written now , it looks like we're asking users to take a PKCS#12 archive, find a way to represent its bytes in Base64 format and use that string here. I'm not familiar with how Azure templates work but I assumed there is an easy way to add the actual binary file here instead of its Base64 string representation.
If we do need a Base64 string with the encoded contents of the PKCS#12 archive, we could add an example of how to get them ( in bash or powershell ) ?
Also I still think that the PKCS#12 archive certificate part sounds strange as there are two nouns. If the containing the key and certificate I suggested above sounds too long, maybe consider dropping the certificate
from the original description to keep it simple ?
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.
we're asking users to take a PKCS#12 archive, find a way to represent its bytes in Base64 format and use that string here. I'm not familiar with how Azure templates work but I assumed there is an easy way to add the actual binary file here instead of its Base64 string representation.
Yes, that's what we're asking users to do, and it's the way the contents of files are typically provided when deploying Azure resources.
Also I still think that the PKCS#12 archive certificate part sounds strange as there are two nouns. If the containing the key and certificate I suggested above sounds too long, maybe consider dropping the certificate from the original description to keep it simple ?
I agree, I'll update to your suggestion "containing the key and certificate" 👍
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.
I agree, I'll update to your suggestion "containing the key and certificate" +1
I'd update that here (in the Parameters table) too.
README.md
Outdated
|
||
<tr><td>esHttpCertPassword</td><td>securestring</td> | ||
<td>The password for the PKCS#12 archive (.p12/.pfx) certificate to secure communication for HTTP layer to Elasticsearch. Optional as the archive may not be encrypted. <br /><br /> | ||
If using <code>esHttpCaCertBlob</code>, this password will be used to encrypt the private key of generated certificates. |
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.
I would argue in favor of adding an extra parameter to be used for encrypting the generated private keys below, and use this only as the password of the esHttpCertBlob
if any.
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.
I think the description is incorrect here; when a CA cert is passed to generate certs for the HTTP layer, esHttpCertPassword
can be used as the passphrase for the generated PKCS#12 archives. I'll update the description to make this clearer.
README.md
Outdated
<td>Either <code>Yes</code> or <code>No</code> to configure SSL/TLS for the HTTP layer of Elasticsearch. <strong>X-Pack plugin must be installed and either <code>esHttpCertBlob</code> or <code>esHttpCaCertBlob</code> provided</strong></strong> | ||
</td><td><code>No</code></td></tr> | ||
|
||
<tr><td>esHttpCertBlob</td><td>string</td> |
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.
Maybe archive instead of blob for the rest of this ?
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.
I'd like to stick to using the parameter names for this. The *Blob
suffix has been used in the template for encoded parameters, so would like to stick to this for consistency.
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.
Re-read this comment. I think renaming the PKCS#12 archive parameters would make sense e.g.
esHttpCaCertBlob
-> esHttpCaArchiveBlob
However, the Application Gateway parameter for providing a PKCS#12 archive that has been in the template for over a year is called appGatewayCertBlob
, so think *CertBlob
would make for a more consistent naming approach, even though the parameter name is less/not technically correct.
README.md
Outdated
|
||
**_and_** | ||
|
||
* supply the public key in CER format for the certificate within the PKCS#12 archive |
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.
.cer
is just a suffix, there is no CER
format .openssl pkcs12 -in http_cert.p12 -out public_key.cer -clcerts -nokeys
will export the certificate in PEM format.
Also this is not just the public key, but rather the certificate.
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.
I agree 😄 I was sticking to the same terminology that Microsoft has used in their documentation for enabling end-to-end encryption with Application Gateway (see Note at point 7). I'll update to indicate this is the certificate
README.md
Outdated
<strong>Required when selecting <code>gateway</code> for load balancing.</strong> | ||
</td><td><code>""</code></td></tr> | ||
|
||
<tr><td>appGatewayEsHttpCertPublicKey</td><td>securestring</td> | ||
<td>The Base-64 encoded public key (.cer) for the certificate used to secure the HTTP layer of Elasticsearch. Used by the Application Gateway to whitelist certificates used by the backend pool. Required when using <code>esHttpCertBlob</code> to secure the HTTP layer of Elasticsearch and selecting <code>gateway</code> for load balancing. <strong>X-Pack plugin must be installed</strong> |
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.
The Base-64 encoded public key (.cer) for the certificate
== The certificate
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.
Will update 👍
README.md
Outdated
passphrase can be passed with `esTransportCertPassword` to encrypt the generated certificate | ||
on each node. | ||
|
||
A new CA PKCS#12 archive can be generated using [Elastic's certutil command](https://www.elastic.co/guide/en/elasticsearch/reference/current/certutil.html). The simplest command to generate a CA cert is |
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.
The expectation here is that users will download Elasticsearch on their own and run certutil
? It doesn't sound very streamlined experience, but I don't have any good alternative options to suggest.
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.
I'll make it clear that this is just a suggestion for how to create a CA cert, but that they may already have one, or could generate one in other ways e.g. through PowerShell
@Mpdreamz I agree that they are superfluous. We could configure/generate/persist certificates on node VMs independently of enabling HTTP or Transport TLS i.e. be able to pass certs, to set them up on the VMs, but pass |
This commit renames the mainTemplate appGatewayEsHttpCertPublicKey to simply appGatewayEsHttpCertBlob, to indicate that the parameter is the public key and should be provided Base-64 encoded.
This commit addresses the PR comments to improve the descriptions for each of the parameters, and include a section on how to pass certificate related parameters.
README.md
Outdated
</td><td><code>No</code></td></tr> | ||
|
||
<tr><td>esHttpCertBlob</td><td>string</td> | ||
<td>A Base-64 encoded form of the PKCS#12 archive (.p12/.pfx) certificate to secure communication for HTTP layer to Elasticsearch. <strong>X-Pack plugin must be installed</strong> |
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.
My point here is that the way it is written now , it looks like we're asking users to take a PKCS#12 archive, find a way to represent its bytes in Base64 format and use that string here. I'm not familiar with how Azure templates work but I assumed there is an easy way to add the actual binary file here instead of its Base64 string representation.
If we do need a Base64 string with the encoded contents of the PKCS#12 archive, we could add an example of how to get them ( in bash or powershell ) ?
Also I still think that the PKCS#12 archive certificate part sounds strange as there are two nouns. If the containing the key and certificate I suggested above sounds too long, maybe consider dropping the certificate
from the original description to keep it simple ?
* **TLS for communication with Elasticsearch via the HTTP layer through an external load balancer** | ||
* **TLS for communication with Elasticsearch via the HTTP layer through Application Gateway** | ||
* **TLS for communication between Elasticsearch nodes via the Transport layer** | ||
* **TLS for communication beween the browser and Kibana** |
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.
This gets configured below https://github.com/elastic/azure-marketplace/pull/187/files#diff-04c6e90faac2675aa89e2176d2eec7d8R192
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.
It's optional in the template to configure TLS, but really want to point out at the top of the README that you should be configuring this!
@@ -146,13 +190,16 @@ posts for further information | |||
</td><td><code>Standard_A2</code></td></tr> | |||
|
|||
<tr><td>kibanaCertBlob</td><td>string</td> | |||
<td>A Base-64 encoded form of the certificate (.crt) to secure HTTPS communication between the browser and Kibana.</td><td><code>""</code></td></tr> | |||
<td>A Base-64 encoded form of the certificate (.crt) in PEM format to secure HTTPS communication between the browser and Kibana.</td><td><code>""</code></td></tr> |
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.
i.e. as a consumer of the template, if I need to add certs in whatever format
Then maybe it's worth stating that we support other formats? Indeed Elasticsearch supports reading DER encoded certificates. Then again, as a consumer, if I have a DER certificate and I need to Base64 encode it in order to use it in the template, I am effectively converting it to a PEM certificate, so in essence we do only support PEM certificates.
Just a comment though, not a request for an additional change. I'd write this differently, but I don't have a so strong opinion on how it should be written here.
README.md
Outdated
|
||
**_and_** | ||
|
||
* supply the public certificate in CER format from the PKCS#12 archive |
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.
s/CER/PEM
@jkakavas Really appreciate your time in looking at this. I think I've now addressed all of your comments, if you have a chance to take another look. |
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 discussion!
@russcam what would be the downsides of removing them? I'm +1 to not supporting No and no certblob. E.g if you pass one we'll use that otherwise we use self genned ones. |
No downside to removing them now; happy to do so as it's two less parameters 😄 |
This PR adds
/etc/kibana/kibana.yml
config fileThe template has supported TLS to Elasticsearch from a public IP address through the use of Application Gateway for some time. With such a configuration however, offload happens on the Application Gateway, and inter-node communication on the Transport layer is still unencrypted.
This PR allows PKCS#12 archive certs to be passed base64 encoded to be used for TLS of HTTP and Transport layers. For Elasticsearch 5.x which does not support PKCS#12 format, the archive is converted to PEM format. If a certificate is passed for the HTTP layer, Kibana is also configured to use this certificate.
Some important notes:
certificate
which verifies that the provided certificate is signed by a trusted authority (CA), but does not perform hostname verification.certificate
for the Elasticsearch HTTP cert for 5.3.0+which verifies that the provided certificate is signed by a trusted authority (CA), but does not perform hostname verification. Kibana communicates with Elasticsearch through the network IP address of the internal load balancer.certificate
verification only. Additionally, if the key has a passphrase, this is removed, as these versions of Kibana do not support passing a passphrase for the key.