Skip to content

Commit

Permalink
Add SSL support and update clients (#18)
Browse files Browse the repository at this point in the history
This commit updated the Enterprise Search clients to version >= 7.16, < 9, adding support for the following SSL configurations: ssl_certificate_authorities, ssl_truststore_path, ssl_truststore_password, ssl_truststore_type, ssl_verification_mode, ssl_supported_protocols and ssl_cipher_suites.

The Swiftype endpoints support for both plugins App Search and Workplace Search were removed, and the legacy options were marked as deprecated.

It also fixed the sprintf format support for the Workplace Search source configuration

---------

Co-authored-by: andsel <selva.andre@gmail.com>
  • Loading branch information
edmocosta and andsel committed Nov 7, 2023
1 parent 41d51a6 commit 92f2d4e
Show file tree
Hide file tree
Showing 29 changed files with 1,294 additions and 437 deletions.
2 changes: 2 additions & 0 deletions .ci/Dockerfile
Expand Up @@ -16,6 +16,8 @@ ENV DISTRIBUTION=$DISTRIBUTION
# INTEGRATION="true" while integration testing (false-y by default)
ARG INTEGRATION
ENV INTEGRATION=$INTEGRATION
ARG SECURE_INTEGRATION
ENV SECURE_INTEGRATION=$SECURE_INTEGRATION
RUN gem install bundler -v '< 2'
WORKDIR /usr/share/plugins/plugin
RUN bundle install --with test ci
Expand Down
15 changes: 11 additions & 4 deletions .ci/docker-compose.override.yml
Expand Up @@ -14,6 +14,8 @@ services:
- DISTRIBUTION_SUFFIX=${DISTRIBUTION_SUFFIX}
- INTEGRATION=${INTEGRATION:-false}
- SECURE_INTEGRATION=${SECURE_INTEGRATION:-false}
depends_on:
- enterprise_search

elasticsearch:
build:
Expand All @@ -37,8 +39,7 @@ services:
soft: -1
hard: -1
ports:
- 9200:9200
# networks: ['stack']
- "9200:9200"

enterprise_search:
build:
Expand All @@ -54,6 +55,12 @@ services:
- ENT_SEARCH_DEFAULT_PASSWORD=password
- secret_management.encryption_keys=[changeme]
- allow_es_settings_modification=true
- ent_search.ssl.enabled=${SECURE_INTEGRATION:-false}
- ent_search.ssl.keystore.path=/certificates/root_keystore.jks
- ent_search.ssl.keystore.password=changeme
volumes:
- ../spec/fixtures/certificates:/certificates
ports:
- 3002:3002

- "3002:3002"
depends_on:
- elasticsearch
9 changes: 8 additions & 1 deletion .ci/logstash-run.sh
Expand Up @@ -4,6 +4,13 @@
set -ex

export USER='logstash'

source .ci/retrieve_app_search_credentials.sh

bundle exec rspec spec && bundle exec rspec spec --tag integration
if [[ "$SECURE_INTEGRATION" == "true" ]]; then
extra_tag_args=" --tag secure_integration:true"
else
extra_tag_args="--tag ~secure_integration:true"
fi

bundle exec rspec --format=documentation spec/unit --tag ~integration:true --tag ~secure_integration:true && bundle exec rspec --format=documentation --tag integration $extra_tag_args spec/integration
16 changes: 12 additions & 4 deletions .ci/retrieve_app_search_credentials.sh
@@ -1,9 +1,11 @@
#!/bin/bash

function wait_for_enterprise_search {
url="${1?url is required}"
local continue=1
set +e
while [ $continue -gt 0 ]; do
curl --connect-timeout 5 --max-time 10 --retry 10 --retry-delay 30 --retry-max-time 120 -s -o /dev/null ${ENTERPRISE_SEARCH_URL}/login
curl --connect-timeout 5 --max-time 10 --retry 10 --retry-delay 30 --retry-max-time 120 -s -o /dev/null --insecure ${url}/login
continue=$?
if [ $continue -gt 0 ]; then
sleep 1
Expand All @@ -13,14 +15,20 @@ function wait_for_enterprise_search {

function load_api_keys {
local CREDENTIALS_URL="${ENTERPRISE_SEARCH_URL}/as/credentials/collection?page%5Bcurrent%5D=1"
echo $(curl -u${ENTERPRISE_SEARCH_USERNAME}:${ENTERPRISE_SEARCH_PASSWORD} -s ${CREDENTIALS_URL} | sed -E "s/.*(${1}-[[:alnum:]]{24}).*/\1/")
echo $(curl -u${ENTERPRISE_SEARCH_USERNAME}:${ENTERPRISE_SEARCH_PASSWORD} -s ${CREDENTIALS_URL} --insecure | sed -E "s/.*(${1}-[[:alnum:]]{24}).*/\1/")
}

export ENTERPRISE_SEARCH_USERNAME=${ENTERPRISE_SEARCH_USERNAME:-"enterprise_search"}
export ENTERPRISE_SEARCH_PASSWORD=${ENTERPRISE_SEARCH_PASSWORD:-"password"}
export ENTERPRISE_SEARCH_URL=${ENTERPRISE_SEARCH_URL:-"http://enterprise_search:3002"}
export SECURE_INTEGRATION=${SECURE_INTEGRATION:-false}

if [[ "$SECURE_INTEGRATION" == "true" ]]; then
export ENTERPRISE_SEARCH_URL=${ENTERPRISE_SEARCH_URL:-"https://enterprise_search:3002"}
else
export ENTERPRISE_SEARCH_URL=${ENTERPRISE_SEARCH_URL:-"http://enterprise_search:3002"}
fi

wait_for_enterprise_search
wait_for_enterprise_search $ENTERPRISE_SEARCH_URL

export APP_SEARCH_PRIVATE_KEY=`load_api_keys private`
export APP_SEARCH_SEARCH_KEY=`load_api_keys search`
Expand Down
7 changes: 6 additions & 1 deletion .travis.yml
Expand Up @@ -3,5 +3,10 @@ import:

env:
- DISTRIBUTION=default ELASTIC_STACK_VERSION=7.x
- DISTRIBUTION=default ELASTIC_STACK_VERSION=7.x SECURE_INTEGRATION=true
- DISTRIBUTION=default ELASTIC_STACK_VERSION=7.x SNAPSHOT=true
- DISTRIBUTION=default ELASTIC_STACK_VERSION=8.x SNAPSHOT=true
- DISTRIBUTION=default ELASTIC_STACK_VERSION=7.x SNAPSHOT=true SECURE_INTEGRATION=true
- DISTRIBUTION=default ELASTIC_STACK_VERSION=8.x
- DISTRIBUTION=default ELASTIC_STACK_VERSION=8.x SECURE_INTEGRATION=true
- DISTRIBUTION=default ELASTIC_STACK_VERSION=8.x SNAPSHOT=true
- DISTRIBUTION=default ELASTIC_STACK_VERSION=8.x SNAPSHOT=true SECURE_INTEGRATION=true
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,10 @@
## 3.0.0
- Bumped Enterprise Search clients to version `>= 7.16`, `< 9` [#18](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/18)
- Added support to SSL configurations (`ssl_certificate_authorities`, `ssl_truststore_path`, `ssl_truststore_password`, `ssl_truststore_type`, `ssl_verification_mode`, `ssl_supported_protocols` and `ssl_cipher_suites`)
- [BREAKING] Swiftype endpoints are no longer supported for both plugins App Search and Workplace Search
- The App Search deprecated options `host` and `path` were removed
- Fixed the sprintf format support for the Workplace Search `source` configuration

## 2.2.1
- Fix, change implementation of connectivity check method to be compatible with version `v8.0+` of Workplace Search [#16](https://github.com/logstash-plugins/logstash-integration-elastic_enterprise_search/pull/16)

Expand Down
10 changes: 10 additions & 0 deletions README.md
Expand Up @@ -88,6 +88,16 @@ bin/plugin install --no-verify
```
- Start Logstash and proceed to test the plugin

### Thoubleshooting integration test failures
Integration tests uses some certificates fixtures. These security artifacts has 1 year expiration, so time to time
they would trigger errors due to bad certificate.
To regenerate use:
```sh
> cd spec/fixture/certificates
> ./generate.sh
```
Re-run locally the integration tests (with Docker scripts) and if it's green again create a PR to update.

## Contributing

All contributions are welcome: ideas, patches, documentation, bug reports, complaints, and even something you drew up on a napkin.
Expand Down
117 changes: 77 additions & 40 deletions docs/output-elastic_app_search.asciidoc
Expand Up @@ -50,10 +50,15 @@ This plugin supports the following configuration options plus the
| <<plugins-{type}s-{plugin}-api_key>> |<<password,password>>|Yes
| <<plugins-{type}s-{plugin}-document_id>> |<<string,string>>|No
| <<plugins-{type}s-{plugin}-engine>> |<<string,string>>|Yes
| <<plugins-{type}s-{plugin}-host>> |<<string,string>>|No
| <<plugins-{type}s-{plugin}-path>> |<<string,string>>|No
| <<plugins-{type}s-{plugin}-ssl_certificate_authorities>> |list of <<path,path>>|No
| <<plugins-{type}s-{plugin}-ssl_cipher_suites>> |list of <<string,string>>|No
| <<plugins-{type}s-{plugin}-ssl_supported_protocols>> |<<string,string>>|No
| <<plugins-{type}s-{plugin}-ssl_truststore_password>> |<<password,password>>|No
| <<plugins-{type}s-{plugin}-ssl_truststore_path>> |<<path,path>>|No
| <<plugins-{type}s-{plugin}-ssl_truststore_type>> |<<string,string>>|No
| <<plugins-{type}s-{plugin}-ssl_verification_mode>> |<<string,string>>, one of `["full", "none"]`|No
| <<plugins-{type}s-{plugin}-timestamp_destination>> |<<string,string>>|No
| <<plugins-{type}s-{plugin}-url>> |<<string,string>>|No
| <<plugins-{type}s-{plugin}-url>> |<<string,string>>|Yes
|=======================================================================

Also see <<plugins-{type}s-{plugin}-common-options>> for a list of options supported by all
Expand All @@ -67,7 +72,7 @@ output plugins.
* Value type is <<password,password>>
* There is no default value

The private API Key with write permissions. Visit the https://app.swiftype.com/as/credentials[Credentials] in the App Search dashboard to find the key associated with your account.
The private API Key with write permissions. Visit the App Search API keys reference [page](https://www.elastic.co/guide/en/app-search/current/authentication.html#authentication-api-keys) for more information.

[id="plugins-{type}s-{plugin}-document_id"]
===== `document_id`
Expand Down Expand Up @@ -125,50 +130,83 @@ output {
}
----------------------------------

[id="plugins-{type}s-{plugin}-host"]
===== `host`
[id="plugins-{type}s-{plugin}-ssl_certificate_authorities"]
===== `ssl_certificate_authorities`

* Value type is <<string,string>>
* There is no default value
* Value type is a list of <<path,path>>
* There is no default value for this setting

The hostname of the App Search SaaS API that is associated with your App Search account.
This is used only by Swiftype App Search, and has the form of `host-1ab2cd`.
Set this when using the https://swiftype.com/documentation/app-search/getting-started [Swiftype App Search managed service].
The .cer or .pem files to validate the server's certificate.

NOTE: This is valid only for Swiftype SaaS AppSearch accounts, could be removed in future versions.
NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_truststore_path>> at the same time.

[source,ruby]
----------------------------------
output {
elastic_app_search {
api_key => "private-somethingsecrethere"
host => "host-1ab2cd"
}
}
----------------------------------
[id="plugins-{type}s-{plugin}-ssl_cipher_suites"]
===== `ssl_cipher_suites`
* Value type is a list of <<string,string>>
* There is no default value for this setting

[id="plugins-{type}s-{plugin}-path"]
===== `path`
The list of cipher suites to use, listed by priorities.
Supported cipher suites vary depending on the Java and protocol versions.

[id="plugins-{type}s-{plugin}-ssl_supported_protocols"]
===== `ssl_supported_protocols`

* Value type is <<string,string>>
* Default value is `/api/as/v1/`
* Allowed values are: `'TLSv1.1'`, `'TLSv1.2'`, `'TLSv1.3'`
* Default depends on the JDK being used. With up-to-date Logstash, the default is `['TLSv1.2', 'TLSv1.3']`.
`'TLSv1.1'` is not considered secure and is only provided for legacy applications.

List of allowed SSL/TLS versions to use when establishing a connection to the Elasticsearch cluster.

The `path` setting is used only for Swiftype SaaS AppSearch and could be removed in future versions.
If configured, it needs the `host` which refers to a Swiftype's AppSearch instance.
For Java 8 `'TLSv1.3'` is supported only since **8u262** (AdoptOpenJDK), but requires that you set the
`LS_JAVA_OPTS="-Djdk.tls.client.protocols=TLSv1.3"` system property in Logstash.

Note: When connecting to a https://www.elastic.co/downloads/app-search[self-managed Elastic App Search] the path is appended to the `url` parameter.
NOTE: If you configure the plugin to use `'TLSv1.1'` on any recent JVM, such as the one packaged with Logstash,
the protocol is disabled by default and needs to be enabled manually by changing `jdk.tls.disabledAlgorithms` in
the *$JDK_HOME/conf/security/java.security* configuration file. That is, `TLSv1.1` needs to be removed from the list.

[source,ruby]
----------------------------------
output {
elastic_app_search {
api_key => "private-somethingsecrethere"
url => "https://localhost:3002"
path => "/api"
}
}
----------------------------------
[id="plugins-{type}s-{plugin}-ssl_truststore_password"]
===== `ssl_truststore_password`

* Value type is <<password,password>>
* There is no default value for this setting.

Set the truststore password

[id="plugins-{type}s-{plugin}-ssl_truststore_path"]
===== `ssl_truststore_path`

* Value type is <<path,path>>
* There is no default value for this setting.

The truststore to validate the server's certificate.
It can be either `.jks` or `.p12`.

NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_certificate_authorities>> at the same time.

[id="plugins-{type}s-{plugin}-ssl_truststore_type"]
===== `ssl_truststore_type`

* Value can be any of: `jks`, `pkcs12`
* If not provided, the value will be inferred from the truststore filename.

The format of the truststore file. It must be either `jks` or `pkcs12`.

[id="plugins-{type}s-{plugin}-ssl_verification_mode"]
===== `ssl_verification_mode`

* Value can be any of: `full`, `none`
* Default value is `full`

Defines how to verify the certificates presented by another party in the TLS connection:

`full` validates that the server certificate has an issue date that’s within
the not_before and not_after dates; chains to a trusted Certificate Authority (CA), and
has a hostname or IP address that matches the names within the certificate.

`none` performs no certificate validation.

WARNING: Setting certificate verification to `none` disables many security benefits of SSL/TLS, which is very dangerous. For more information on disabling certificate verification please read https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf

[id="plugins-{type}s-{plugin}-timestamp_destination"]
===== `timestamp_destination`
Expand All @@ -188,10 +226,9 @@ To keep the timestamp field, set this value to the name of the field where you w
===== `url`

* Value type is <<string,string>>
* There is no default value
* Default value is `http://localhost:3002`

The value of the API endpoint in the form of a URL. Note: The value of the of the `path` setting will be will be appended to this URL.
Set this when using the https://www.elastic.co/downloads/app-search[self-managed Elastic App Search].
The value of the API endpoint in the form of a URL.

[id="plugins-{type}s-{plugin}-common-options"]
include::{include_path}/{type}.asciidoc[]
Expand Down

0 comments on commit 92f2d4e

Please sign in to comment.