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 Kerberos support to Elasticsearch output #17927

Merged
merged 11 commits into from
Apr 29, 2020

Conversation

kvch
Copy link
Contributor

@kvch kvch commented Apr 23, 2020

What does this PR do?

This PR adds support for Kerberos authentication to Elasticsearch output.

Configuration

Users can authenticate using either passwords or keytabs.

The option service_name is not exposed as in case of ES it has be HTTP. Thus, the SPN of the output is always HTTP/{output.elasticsearch.host}@{output.elasticsearch.kerberos.realm}.

# Authentication type to use with Kerberos. Available options: keytab, password.
#kerberos.auth_type: password

# Path to the keytab file. It is used when auth_type is set to keytab.
#kerberos.keytab: /etc/elastic.keytab

# Path to the Kerberos configuration.
#kerberos.config_path: /etc/krb5.conf

# Name of the Kerberos user.
#kerberos.username: elastic

# Password of the Kerberos user. It is used when auth_type is set to password.
#kerberos.password: changeme

# Kerberos realm.
#kerberos.realm: ELASTIC

Architecture

Kerberos authentication is implemented by using the spnego.Client from gopkg.in/jcmturner/gokrb5/v7.5. It is an HTTP client which is able to authenticate to a Kerberos KDC and get the required session key to authenticate to Elasticsearch.

In order to use the client when communicating with ES, I introduced a new interface named esHTTPClient with the following functions:

type esHTTPClient interface {
	Do(req *http.Request) (resp *http.Response, err error)
	CloseIdleConnections()
}

So the newly created kerberos.Client and http.Client can be used in Connection.

The only drawback of this solution is that it is not compatible with github.com/elastic/go-elasticsearch. The main issue is the constructor of that package only lets us configure http.Transport. However, http.Transport should be used for authentication according to Golang documentation. For the record, it is possible to implement Kerberos authentication in a special RoundTripper, but I am not a huge fan of that approach as the Golang docs advise against it.

Reference:

Testing

I am planning to add tests in a follow-up PR. I wanted to raise this first, so we can agree on the selected architecture.

Why is it important?

Users now can authenticate to Kerberos-aware Elasticsearch instances.

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have made corresponding change to the default configuration files
  • I have added tests that prove my fix is effective or that my feature works
  • I have added an entry in CHANGELOG.next.asciidoc or CHANGELOG-developer.next.asciidoc.

@kvch kvch added [zube]: In Review Team:Services (Deprecated) Label for the former Integrations-Services team labels Apr 23, 2020
@kvch kvch requested review from ycombinator and urso April 23, 2020 09:04
@kvch kvch requested review from a team as code owners April 23, 2020 09:04
@elasticmachine
Copy link
Collaborator

Pinging @elastic/integrations-services (Team:Services)

@kvch kvch force-pushed the feature-libbeat-kerberos-elasticsearch branch from 73c4256 to 03daa15 Compare April 23, 2020 16:47
@kvch kvch force-pushed the feature-libbeat-kerberos-elasticsearch branch from 1ceba6e to f213960 Compare April 24, 2020 10:43
@kvch kvch force-pushed the feature-libbeat-kerberos-elasticsearch branch from f213960 to d88714d Compare April 24, 2020 12:33
@ycombinator
Copy link
Contributor

The only drawback of this solution is that it is not compatible with github.com/elastic/go-elasticsearch. The main issue is the constructor of that package only lets us configure http.Transport. However, http.Transport should be used for authentication according to Golang documentation. For the record, it is possible to implement Kerberos authentication in a special RoundTripper, but I am not a huge fan of that approach as the Golang docs advise against it.

WDYT about starting a discussion issue about this in https://github.com/elastic/go-elasticsearch?

ycombinator
ycombinator approved these changes Apr 24, 2020
Copy link
Contributor

@ycombinator ycombinator left a comment

Choose a reason for hiding this comment

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

Gave an LGTM too early, sorry! I assume you want to add docs (https://www.elastic.co/guide/en/beats/filebeat/current/elasticsearch-output.html) and a CHANGELOG entry to this PR as well?

@ycombinator ycombinator self-requested a review April 24, 2020 12:41
@@ -59,19 +64,21 @@ func (t *AuthType) Unpack(value string) error {
}

func (c *Config) Validate() error {
if c.AuthType == AUTH_PASSWORD {
switch c.AuthType {
case AUTH_PASSWORD:
Copy link

Choose a reason for hiding this comment

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

nits: Do not use C like screaming identifiers for consts. Plus add the actual type to the const if we already have an enum type. Do we need to export the consts or not?

I understand these have not been introduced in this PR, but would be nice to cleanup existing code a little when we touch it :)

Copy link
Contributor

Choose a reason for hiding this comment

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

TIL the all-caps identifiers are also known as screaming identifiers! 😄

@urso
Copy link

urso commented Apr 24, 2020

How about adding an enabled setting to the kerberos configuration namespace? We have enabled for almost everything else, even ssl settings have an enabled setting.

@urso
Copy link

urso commented Apr 27, 2020

LGTM. Can you please add a changelog?

@kvch kvch force-pushed the feature-libbeat-kerberos-elasticsearch branch from d765e52 to 89b44b8 Compare April 28, 2020 12:05
@@ -0,0 +1,85 @@
[[configuration-kerberos]]
Copy link
Member

Choose a reason for hiding this comment

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

It looks like you haven't included this file anywhere. It's not being built, which is why the link here fails.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for your help!

@elasticmachine
Copy link
Collaborator

💔 Build Failed

Pipeline View Test View Changes Artifacts preview stats

Expand to view the summary

Build stats

Test stats 🧪

Test Results
Failed 0
Passed 6509
Skipped 1112
Total 7621

Steps errors

Expand to view the steps failures

  • Name: Make -C generator/_templates/metricbeat test
    • Description: make -C generator/_templates/metricbeat test

    • Result: FAILURE

    • Duration: 3 min 33 sec<

    • Start Time: 2020-04-28T17:53:44.387+0000

Log output

Expand to view the last 100 lines of log output

[2020-04-28T18:36:35.719Z] WARNING: Its probable that you had pre-existing python installation
[2020-04-28T18:36:35.719Z] WARNING: Installed to: C:\Python27
[2020-04-28T18:36:35.719Z] WARNING: Installation folder is not the default. Not changing permissions. Please ensure your installation is secure.
[2020-04-28T18:36:35.719Z]   python3 can be automatically uninstalled.
[2020-04-28T18:36:35.719Z] Environment Vars (like PATH) have changed. Close/reopen your shell to
[2020-04-28T18:36:35.719Z]  see the changes (or in powershell/cmd.exe just type `refreshenv`).
[2020-04-28T18:36:35.719Z]  The install of python3 was successful.
[2020-04-28T18:36:35.719Z]   Software installed as 'exe', install location is likely default.
[2020-04-28T18:36:35.719Z] 
[2020-04-28T18:36:35.719Z] python v3.8.2 [Approved]
[2020-04-28T18:36:35.719Z] python package files install completed. Performing other installation steps.
[2020-04-28T18:36:35.979Z] Get-BinRoot is going to be deprecated in v1 and removed in v2. It has been replaced with Get-ToolsLocation (starting with v0.9.10), however many packages no longer require a special separate directory since package folders no longer have versions on them. Some do though and should continue to use Get-ToolsLocation.
[2020-04-28T18:36:48.181Z] Warning: Old installation path "C:\Python27" detected.
[2020-04-28T18:36:48.181Z] This package will continue to install python there unless you uninstall
[2020-04-28T18:36:48.181Z] python from there and remove the "C:\Python27" folder. If you decide
[2020-04-28T18:36:48.181Z] to do that, reinstall this package with the -force parameter and it will
[2020-04-28T18:36:48.181Z] install to the Chocolatey bin root.
[2020-04-28T18:36:48.181Z] 
[2020-04-28T18:36:48.181Z] python v2.7.11 is already installed. Skipping unnecessary download
[2020-04-28T18:36:48.181Z] and installation. If you have installed python in "C:\Python27"
[2020-04-28T18:36:48.181Z] and you want to use the Chocolatey bin root as installation path instead,
[2020-04-28T18:36:48.181Z] uninstall python from the control panel, remove the "C:\Python27"
[2020-04-28T18:36:48.181Z] folder and reinstall this package with the -force parameter.
[2020-04-28T18:36:48.181Z] 
[2020-04-28T18:36:48.181Z] Environment Vars (like PATH) have changed. Close/reopen your shell to
[2020-04-28T18:36:48.181Z]  see the changes (or in powershell/cmd.exe just type `refreshenv`).
[2020-04-28T18:36:48.181Z]  The install of python was successful.
[2020-04-28T18:36:48.181Z]   Software install location not explicitly set, could be in package or
[2020-04-28T18:36:48.181Z]   default install location if installer.
[2020-04-28T18:36:48.181Z] 
[2020-04-28T18:36:48.181Z] Chocolatey installed 4/4 packages. 
[2020-04-28T18:36:48.181Z]  See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).
[2020-04-28T18:36:48.181Z] 
[2020-04-28T18:36:48.181Z] C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats>python --version 
[2020-04-28T18:36:48.181Z] Python 3.8.2
[2020-04-28T18:36:48.181Z] 
[2020-04-28T18:36:48.181Z] C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats>where python 
[2020-04-28T18:36:48.181Z] C:\Python38\python.exe
[2020-04-28T18:36:48.181Z] C:\Python27\python.exe
[2020-04-28T18:36:48.245Z] Running in C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\auditbeat
[2020-04-28T18:36:48.570Z] 
[2020-04-28T18:36:48.570Z] C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\auditbeat>mage  build unitTest 
[2020-04-28T18:37:35.609Z] >> build: Building auditbeat
[2020-04-28T18:38:23.080Z] SUMMARY:
[2020-04-28T18:38:23.080Z]   Fail:     0
[2020-04-28T18:38:23.080Z]   Skip:     1
[2020-04-28T18:38:23.080Z]   Pass:     146
[2020-04-28T18:38:23.080Z]   Packages: 13
[2020-04-28T18:38:23.080Z]   Duration: 2m32.2587354s
[2020-04-28T18:38:23.080Z]   Coverage Report: C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\x-pack\functionbeat\build\TEST-go-unit.html
[2020-04-28T18:38:23.080Z]   JUnit Report:    C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\x-pack\functionbeat\build\TEST-go-unit.xml
[2020-04-28T18:38:23.080Z]   Output File:     C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\x-pack\functionbeat\build\TEST-go-unit.out
[2020-04-28T18:38:23.080Z] >> go test: Unit Test Passed
[2020-04-28T18:38:43.788Z] Generated fields.yml for auditbeat to C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\auditbeat\fields.yml
[2020-04-28T18:38:43.788Z] >> go test: Unit Testing
[2020-04-28T18:39:59.967Z] >> python test: Unit Testing
[2020-04-28T18:40:50.700Z] SUMMARY:
[2020-04-28T18:40:50.700Z]   Fail:     0
[2020-04-28T18:40:50.700Z]   Skip:     4
[2020-04-28T18:40:50.700Z]   Pass:     66
[2020-04-28T18:40:50.700Z]   Packages: 4
[2020-04-28T18:40:50.700Z]   Duration: 1m58.5519763s
[2020-04-28T18:40:50.700Z]   Coverage Report: C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\auditbeat\build\TEST-go-unit.html
[2020-04-28T18:40:50.700Z]   JUnit Report:    C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\auditbeat\build\TEST-go-unit.xml
[2020-04-28T18:40:50.700Z]   Output File:     C:\Users\jenkins\workspace\Beats_beats-beats-mbp_PR-17927\src\github.com\elastic\beats\auditbeat\build\TEST-go-unit.out
[2020-04-28T18:40:50.700Z] >> go test: Unit Test Passed
[2020-04-28T18:41:07.892Z] WARNING: You are using pip version 19.2.3, however version 20.1 is available.
[2020-04-28T18:41:07.892Z] You should consider upgrading via the 'python -m pip install --upgrade pip' command.
[2020-04-28T18:41:07.892Z] S..
[2020-04-28T18:41:07.892Z] [success] 67.13% test_base.Test.test_export_function: 0.2361s
[2020-04-28T18:41:07.892Z] [success] 32.87% test_base.Test.test_export_function_invalid_conf: 0.1156s
[2020-04-28T18:41:07.892Z] ----------------------------------------------------------------------
[2020-04-28T18:41:07.892Z] Ran 3 tests in 0.352s
[2020-04-28T18:41:07.892Z] 
[2020-04-28T18:41:07.892Z] OK (SKIP=1)
[2020-04-28T18:41:07.892Z] >> python test: Unit Testing Complete
[2020-04-28T18:41:07.982Z] Recording test results
[2020-04-28T18:41:12.526Z] Archiving artifacts
[2020-04-28T18:41:58.574Z] >> python test: Unit Testing
[2020-04-28T18:43:06.682Z] WARNING: You are using pip version 19.2.3, however version 20.1 is available.
[2020-04-28T18:43:06.682Z] You should consider upgrading via the 'python -m pip install --upgrade pip' command.
[2020-04-28T18:43:06.682Z] S.S.SSSS
[2020-04-28T18:43:06.682Z] [success] 84.77% test_file_integrity.Test.test_non_recursive: 1.4469s
[2020-04-28T18:43:06.682Z] [success] 15.23% test_base.Test.test_start_stop: 0.2599s
[2020-04-28T18:43:06.682Z] ----------------------------------------------------------------------
[2020-04-28T18:43:06.682Z] Ran 8 tests in 1.709s
[2020-04-28T18:43:06.682Z] 
[2020-04-28T18:43:06.682Z] OK (SKIP=6)
[2020-04-28T18:43:06.682Z] >> python test: Unit Testing Complete
[2020-04-28T18:43:07.081Z] Recording test results
[2020-04-28T18:43:15.868Z] Archiving artifacts
[2020-04-28T18:44:02.767Z] Cancelling nested steps due to timeout
[2020-04-28T18:44:02.964Z] Failed in branch Filebeat x-pack
[2020-04-28T18:44:04.586Z] Running on Jenkins in /var/lib/jenkins/workspace/Beats_beats-beats-mbp_PR-17927
[2020-04-28T18:44:05.278Z] [INFO] getVaultSecret: Getting secrets
[2020-04-28T18:44:05.417Z] Masking supported pattern matches of $VAULT_ADDR or $VAULT_ROLE_ID or $VAULT_SECRET_ID
[2020-04-28T18:44:06.601Z] + chmod 755 generate-build-data.sh
[2020-04-28T18:44:06.601Z] + ./generate-build-data.sh https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Beats/beats-beats-mbp/PR-17927/ https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Beats/beats-beats-mbp/PR-17927/runs/11 FAILURE 7331619
[2020-04-28T18:44:07.512Z] INFO: curl https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Beats/beats-beats-mbp/PR-17927/runs/11/steps/?limit=10000 -o steps-info.json
[2020-04-28T18:44:08.856Z] INFO: curl https://beats-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/Beats/beats-beats-mbp/PR-17927/runs/11/tests/?status=FAILED -o tests-errors.json

@kvch
Copy link
Contributor Author

kvch commented Apr 29, 2020

Failing tests are unrelated.

@kvch kvch merged commit f66b079 into elastic:master Apr 29, 2020
@kvch kvch added the needs_backport PR is waiting to be backported to other branches. label Apr 29, 2020
@zube zube bot added [zube]: Done and removed [zube]: In Review needs_backport PR is waiting to be backported to other branches. labels Apr 29, 2020
@kvch kvch added the needs_backport PR is waiting to be backported to other branches. label Apr 29, 2020
@kvch kvch removed the needs_backport PR is waiting to be backported to other branches. label Apr 29, 2020
kvch added a commit to kvch/beats that referenced this pull request Apr 29, 2020
This PR adds support for Kerberos authentication to Elasticsearch output.

Users can authenticate using either passwords or keytabs.

The option `service_name` is not exposed as in case of ES it has be `HTTP`. Thus, the [SPN](https://web.mit.edu/kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-user/What-is-a-Kerberos-Principal_003f.html) of the output is always `HTTP/{output.elasticsearch.host}@{output.elasticsearch.kerberos.realm}`.

```yaml

```
(cherry picked from commit f66b079)
@kvch kvch added the v7.8.0 label Apr 29, 2020
kvch added a commit that referenced this pull request Apr 30, 2020
…ut (#18080)

* Add Kerberos support to Elasticsearch output (#17927)

This PR adds support for Kerberos authentication to Elasticsearch output.

Users can authenticate using either passwords or keytabs.

The option `service_name` is not exposed as in case of ES it has be `HTTP`. Thus, the [SPN](https://web.mit.edu/kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-user/What-is-a-Kerberos-Principal_003f.html) of the output is always `HTTP/{output.elasticsearch.host}@{output.elasticsearch.kerberos.realm}`.

```yaml

```
(cherry picked from commit f66b079)

* "fix" reference template
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libbeat release-highlight Team:Services (Deprecated) Label for the former Integrations-Services team v7.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants