TLS controls for the LDAP connection
The LDAP connection now supports using a custom CA certificate chain or skipping all TLS certificate checks.
This commit is contained in:
parent
12634b9ffa
commit
842a4be87e
3 changed files with 49 additions and 25 deletions
|
@ -52,8 +52,7 @@ go build
|
||||||
To Do
|
To Do
|
||||||
------
|
------
|
||||||
|
|
||||||
* Allow unchecked TLS
|
* Add TLS options (skip checks / specify CA) for the Graylog API.
|
||||||
* Actually make the CA certificate option work
|
|
||||||
* Read object ownership using `grn_permissions` to preserve privileges on users'
|
* Read object ownership using `grn_permissions` to preserve privileges on users'
|
||||||
own objects
|
own objects
|
||||||
* Read group member records from the LDAP server and extract their username
|
* Read group member records from the LDAP server and extract their username
|
||||||
|
|
|
@ -17,6 +17,9 @@ ldap:
|
||||||
# connection. Defaults to "no".
|
# connection. Defaults to "no".
|
||||||
tls: yes
|
tls: yes
|
||||||
|
|
||||||
|
# Skip server certificate check. Defaults to false.
|
||||||
|
tls_skip_verify: false
|
||||||
|
|
||||||
# CA certificate chain. Can be omitted if the systems' trusted CAs must be
|
# CA certificate chain. Can be omitted if the systems' trusted CAs must be
|
||||||
# used, or if no TLS is being used.
|
# used, or if no TLS is being used.
|
||||||
cachain: /path/to/ca/chain.pem
|
cachain: /path/to/ca/chain.pem
|
||||||
|
|
62
main.go
62
main.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -26,6 +27,8 @@ type (
|
||||||
Host string
|
Host string
|
||||||
Port uint16
|
Port uint16
|
||||||
Tls string
|
Tls string
|
||||||
|
TlsNoVerify bool `yaml:"tls_skip_verify"`
|
||||||
|
TlsAllowCnOnly bool `yaml:"tls_allow_cn_only"`
|
||||||
CaChain string
|
CaChain string
|
||||||
BindUser string `yaml:"bind_user"`
|
BindUser string `yaml:"bind_user"`
|
||||||
BindPassword string `yaml:"bind_password"`
|
BindPassword string `yaml:"bind_password"`
|
||||||
|
@ -231,30 +234,49 @@ func getGroupMembers(group string, conn *ldap.Conn, fields []string) (members []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Establish a connection to the LDAP server
|
||||||
|
func getLdapConnection(cfg LdapConfig) (conn *ldap.Conn) {
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
InsecureSkipVerify: cfg.TlsNoVerify,
|
||||||
|
}
|
||||||
|
if cfg.Tls != "no" && cfg.CaChain != "" {
|
||||||
|
data, err := ioutil.ReadFile(cfg.CaChain)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to read CA certificate chain from %s", cfg.CaChain)
|
||||||
|
}
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
if !pool.AppendCertsFromPEM(data) {
|
||||||
|
log.Fatalf("could not add CA certificates from %s", cfg.CaChain)
|
||||||
|
}
|
||||||
|
tlsConfig.RootCAs = pool
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
dest := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
||||||
|
if cfg.Tls == "yes" {
|
||||||
|
conn, err = ldap.DialTLS("tcp", dest, tlsConfig)
|
||||||
|
} else {
|
||||||
|
conn, err = ldap.Dial("tcp", dest)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to connect to LDAP server %s: %v", cfg.Host, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Tls == "starttls" {
|
||||||
|
err = conn.StartTLS(tlsConfig)
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
log.Fatalf("LDAP server %s, StartTLS failed: %v", cfg.Host, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Read the list of group members from the LDAP server for all groups in the mapping section.
|
// Read the list of group members from the LDAP server for all groups in the mapping section.
|
||||||
func readLdapGroups(configuration Configuration) (groups GroupMembers) {
|
func readLdapGroups(configuration Configuration) (groups GroupMembers) {
|
||||||
var scheme string
|
conn := getLdapConnection(configuration.Ldap)
|
||||||
if configuration.Ldap.Tls == "yes" {
|
|
||||||
scheme = "ldaps"
|
|
||||||
} else {
|
|
||||||
scheme = "ldap"
|
|
||||||
}
|
|
||||||
url := fmt.Sprintf("%s://%s:%d", scheme, configuration.Ldap.Host, configuration.Ldap.Port)
|
|
||||||
|
|
||||||
conn, err := ldap.DialURL(url)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to connect to LDAP server %s: %v", configuration.Ldap.Host, err)
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
if configuration.Ldap.Tls == "starttls" {
|
|
||||||
tlsConfig := tls.Config{}
|
|
||||||
// FIXME missing support for CA chain
|
|
||||||
if err := conn.StartTLS(&tlsConfig); err != nil {
|
|
||||||
log.Fatalf("LDAP server %s, StartTLS failed: %v", configuration.Ldap.Host, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.Ldap.BindUser != "" {
|
if configuration.Ldap.BindUser != "" {
|
||||||
err := conn.Bind(configuration.Ldap.BindUser, configuration.Ldap.BindPassword)
|
err := conn.Bind(configuration.Ldap.BindUser, configuration.Ldap.BindPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue