Skip to content

Commit

Permalink
add Kerberos support to Elasticsearch output
Browse files Browse the repository at this point in the history
  • Loading branch information
kvch committed Apr 28, 2020
1 parent f24f744 commit 7df97a1
Show file tree
Hide file tree
Showing 38 changed files with 2,302 additions and 17 deletions.
9 changes: 9 additions & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7957,6 +7957,15 @@ License type (autodetected): Apache-2.0
Apache License 2.0


--------------------------------------------------------------------
Dependency: gopkg.in/jcmturner/goidentity.v3
Version: v3.0.0
License type (autodetected): Apache-2.0
./vendor/gopkg.in/jcmturner/goidentity.v3/LICENSE:
--------------------------------------------------------------------
Apache License 2.0


--------------------------------------------------------------------
Dependency: gopkg.in/jcmturner/gokrb5.v7
Version: v7.3.0
Expand Down
17 changes: 17 additions & 0 deletions auditbeat/auditbeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,23 @@ setup.kibana:
# Configure curve types for ECDHE-based cipher suites
#ssl.curve_types: []

# 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


#================================ Logging ======================================
Expand Down
17 changes: 17 additions & 0 deletions filebeat/filebeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,23 @@ setup.kibana:
# Configure curve types for ECDHE-based cipher suites
#ssl.curve_types: []

# 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


#================================ Logging ======================================
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ require (
github.com/hashicorp/golang-lru v0.5.2-0.20190520140433-59383c442f7d // indirect
github.com/insomniacslk/dhcp v0.0.0-20180716145214-633285ba52b2
github.com/jcmturner/gofork v1.0.0 // indirect
github.com/jcmturner/gokrb5 v8.3.0+incompatible
github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901
github.com/josephspurrier/goversioninfo v0.0.0-20190209210621-63e6d1acd3dd
Expand Down Expand Up @@ -158,9 +159,10 @@ require (
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb
google.golang.org/grpc v1.27.1
gopkg.in/inf.v0 v0.9.0
gopkg.in/jcmturner/gokrb5.v7 v7.3.0 // indirect
gopkg.in/jcmturner/gokrb5.v7 v7.3.0
gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528
gopkg.in/yaml.v2 v2.2.8
honnef.co/go/tools v0.0.1-2019.2.3
howett.net/plist v0.0.0-20181124034731-591f970eefbb
k8s.io/api v0.0.0-20190722141453-b90922c02518
k8s.io/apimachinery v0.0.0-20190719140911-bfcf53abc9f8
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200121105743-0d940dd29fd2 h1:DW6WrARxK5J+o8uAKCiACi5wy9EK1UzrsCpGBPsKHAA=
github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200121105743-0d940dd29fd2/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
github.com/elastic/beats v7.6.2+incompatible h1:jHdLv83KURaqWUC6f55iMyVP6LYZrgElfeqxKWcskVE=
github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 h1:lnDkqiRFKm0rxdljqrj3lotWinO9+jFmeDXIC4gvIQs=
github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3/go.mod h1:aPqzac6AYkipvp4hufTyMj5PDIphF3+At8zr7r51xjY=
github.com/elastic/ecs v1.5.0 h1:/VEIBsRU4ecq2+U3RPfKNc6bFyomP6qnthYEcQZu8GU=
Expand Down Expand Up @@ -411,6 +412,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jcmturner/gokrb5 v8.3.0+incompatible h1:AioBP0aPxhEAJbOOploDQFImWN+aWEWs4u6DtWVSTwA=
github.com/jcmturner/gokrb5 v8.3.0+incompatible/go.mod h1:0Q5eFyVvYsEsZ8xl1A/jUqhXvxUp/X9ELrJm+zieq5E=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
Expand Down
17 changes: 17 additions & 0 deletions heartbeat/heartbeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,23 @@ setup.kibana:
# Configure curve types for ECDHE-based cipher suites
#ssl.curve_types: []

# 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


#================================ Logging ======================================
Expand Down
17 changes: 17 additions & 0 deletions journalbeat/journalbeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,23 @@ setup.kibana:
# Configure curve types for ECDHE-based cipher suites
#ssl.curve_types: []

# 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


#================================ Logging ======================================
Expand Down
17 changes: 17 additions & 0 deletions libbeat/_meta/config.reference.yml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,23 @@ setup.kibana:
# Configure curve types for ECDHE-based cipher suites
#ssl.curve_types: []

# 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


#================================ Logging ======================================
Expand Down
54 changes: 54 additions & 0 deletions libbeat/common/transport/kerberos/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package kerberos

import (
"fmt"
"net/http"
"net/url"

krbclient "gopkg.in/jcmturner/gokrb5.v7/client"
krbconfig "gopkg.in/jcmturner/gokrb5.v7/config"
"gopkg.in/jcmturner/gokrb5.v7/keytab"
"gopkg.in/jcmturner/gokrb5.v7/spnego"
)

type Client struct {
spClient *spnego.Client
}

func NewClient(config *Config, httpClient *http.Client, esurl string) (*Client, error) {
var krbClient *krbclient.Client
krbConf, err := krbconfig.Load(config.ConfigPath)
if err != nil {
return nil, fmt.Errorf("error creating Kerberos client: %+v", err)
}

switch config.AuthType {
case AUTH_KEYTAB:
kTab, err := keytab.Load(config.KeyTabPath)
if err != nil {
return nil, fmt.Errorf("cannot load keytab file %s: %+v", config.KeyTabPath, err)
}
krbClient = krbclient.NewClientWithKeytab(config.Username, config.Realm, kTab, krbConf)
case AUTH_PASSWORD:
krbClient = krbclient.NewClientWithPassword(config.Username, config.Realm, config.Password, krbConf)
default:
return nil, InvalidAuthType
}

parsedURL, err := url.Parse(esurl)
if err != nil {
return nil, fmt.Errorf("cannot parse elasticsearch URL %s: %v", esurl, err)
}
spn := fmt.Sprintf("HTTP/%s@%s", parsedURL.Hostname(), config.Realm)
return &Client{
spClient: spnego.NewClient(krbClient, httpClient, spn),
}, nil
}

func (c *Client) Do(req *http.Request) (*http.Response, error) {
return c.spClient.Do(req)
}

func (c *Client) CloseIdleConnections() {
c.spClient.CloseIdleConnections()
}
15 changes: 11 additions & 4 deletions libbeat/common/transport/kerberos/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@

package kerberos

import "fmt"
import (
"errors"
"fmt"
)

type AuthType uint

Expand All @@ -30,6 +33,8 @@ const (
)

var (
InvalidAuthType = errors.New("invalid authentication type")

authTypes = map[string]AuthType{
authPassword: AUTH_PASSWORD,
authKeytabStr: AUTH_KEYTAB,
Expand Down Expand Up @@ -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:
if c.Username == "" {
return fmt.Errorf("password authentication is selected for Kerberos, but username is not configured")
}
if c.Password == "" {
return fmt.Errorf("password authentication is selected for Kerberos, but password is not configured")
}
}

if c.AuthType == AUTH_KEYTAB {
case AUTH_KEYTAB:
if c.KeyTabPath == "" {
return fmt.Errorf("keytab authentication is selected for Kerberos, but path to keytab is not configured")
}
default:
return InvalidAuthType
}

return nil
Expand Down
4 changes: 3 additions & 1 deletion libbeat/esleg/eslegclient/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"time"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/common/transport/kerberos"
"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"
)

Expand All @@ -32,7 +33,8 @@ type config struct {
Params map[string]string `config:"parameters"`
Headers map[string]string `config:"headers"`

TLS *tlscommon.Config `config:"ssl"`
TLS *tlscommon.Config `config:"ssl"`
Kerberos *kerberos.Config `config:"kerberos"`

ProxyURL string `config:"proxy_url"`
ProxyDisable bool `config:"proxy_disable"`
Expand Down
47 changes: 37 additions & 10 deletions libbeat/esleg/eslegclient/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,23 @@ import (

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/common/transport"
"github.com/elastic/beats/v7/libbeat/common/transport/kerberos"
"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"
"github.com/elastic/beats/v7/libbeat/logp"
"github.com/elastic/beats/v7/libbeat/testing"
)

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

// Connection manages the connection for a given client.
type Connection struct {
ConnectionSettings

Encoder BodyEncoder
HTTP *http.Client
HTTP esHTTPClient

version common.Version
log *logp.Logger
Expand All @@ -55,7 +61,8 @@ type ConnectionSettings struct {
APIKey string
Headers map[string]string

TLS *tlscommon.TLSConfig
TLS *tlscommon.TLSConfig
Kerberos *kerberos.Config

OnConnectCallback func() error
Observer transport.IOStatser
Expand Down Expand Up @@ -120,20 +127,39 @@ func NewConnection(s ConnectionSettings) (*Connection, error) {
}
}

return &Connection{
ConnectionSettings: s,
HTTP: &http.Client{
var httpClient esHTTPClient
httpClient = &http.Client{
Transport: &http.Transport{
Dial: dialer.Dial,
DialTLS: tlsDialer.Dial,
TLSClientConfig: s.TLS.ToConfig(),
Proxy: proxy,
IdleConnTimeout: s.IdleConnTimeout,
},
Timeout: s.Timeout,
}

if s.Kerberos != nil {
c := &http.Client{
Transport: &http.Transport{
Dial: dialer.Dial,
DialTLS: tlsDialer.Dial,
TLSClientConfig: s.TLS.ToConfig(),
Proxy: proxy,
IdleConnTimeout: s.IdleConnTimeout,
},
Timeout: s.Timeout,
},
Encoder: encoder,
log: logp.NewLogger("esclientleg"),
}
httpClient, err = kerberos.NewClient(s.Kerberos, c, s.URL)
if err != nil {
return nil, err
}
logp.Info("kerberos client created")
}

return &Connection{
ConnectionSettings: s,
HTTP: httpClient,
Encoder: encoder,
log: logp.NewLogger("esclientleg"),
}, nil
}

Expand Down Expand Up @@ -190,6 +216,7 @@ func NewClients(cfg *common.Config) ([]Connection, error) {
Proxy: proxyURL,
ProxyDisable: config.ProxyDisable,
TLS: tlsConfig,
Kerberos: config.Kerberos,
Username: config.Username,
Password: config.Password,
APIKey: config.APIKey,
Expand Down
Loading

0 comments on commit 7df97a1

Please sign in to comment.