Skip to content

Commit

Permalink
Add configuration for TLS connections
Browse files Browse the repository at this point in the history
Signed-off-by: Knut Ahlers <knut@ahlers.me>
  • Loading branch information
Luzifer committed Sep 24, 2018
1 parent 36a055d commit 4d2e8fb
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ providers:
# Replace DN as the username with another attribute
# Optional, defaults to "dn"
username_attribute: "uid"
# Configure TLS parameters for LDAPs connections
# Optional, defaults to null
tls_config:
# Set the hostname for certificate validation
# Optional, defaults to host from the connection URI
validate_hostname: ldap.example.com
# Disable certificate validation, will be ignored when validate_hostname is set
# Optional, defaults to false
allow_insecure: false
```

To use this provider you need to have a LDAP server set up and filled with users. The example (and default) config above assumes each of your users carries an `uid` attribute and groups does contains `member` or `uniqueMember` attributes. Inside the groups full DNs are expected. For the ACL also full DNs are used.
Expand All @@ -196,6 +205,9 @@ To use this provider you need to have a LDAP server set up and filled with users
- `group_search_base` - optional - Like the `user_search_base` this limits the sub-tree where to search for groups, also defaults to `root_dn`
- `group_membership_filter` - optional - The query to issue to list all groups the user is a member of. The DN of each group is used as the group name. If unset the query `(|(member={0})(uniqueMember={0}))` is used (`{0}` is replaced with the users DN, `{1}` is replaced with the content of the `username_attribute`)
- `username_attribute` - optional - The attribute containing the username returned to nginx instead of the dn. If unset the `dn` is used
- `tls_config` - optional - Configures TLS parameters for LDAPs connections
- `validate_hostname` - optional - Set the hostname for certificate validation, when unset the hostname from the `server` URI is used
- `allow_insecure` - optional - Disable certificate validation, will be ignored when validate_hostname is set. Setting this is not recommended for production setups

When using the LDAP provider you need to pay attention when writing your ACL. As DNs are used as names for users and groups you also need to specify those in the ACL:

Expand Down
15 changes: 14 additions & 1 deletion auth_ldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ type authLDAP struct {
UserSearchBase string `yaml:"user_search_base"`
UserSearchFilter string `yaml:"user_search_filter"`
UsernameAttribute string `yaml:"username_attribute"`
TLSConfig *struct {
ValidateHostname string `yaml:"validate_hostname"`
AllowInsecure bool `yaml:"allow_insecure"`
} `yaml:"tls_config"`
}

// AuthenticatorID needs to return an unique string to identify
Expand Down Expand Up @@ -61,6 +65,7 @@ func (a *authLDAP) Configure(yamlSource []byte) error {
a.UserSearchBase = envelope.Providers.LDAP.UserSearchBase
a.UserSearchFilter = envelope.Providers.LDAP.UserSearchFilter
a.UsernameAttribute = envelope.Providers.LDAP.UsernameAttribute
a.TLSConfig = envelope.Providers.LDAP.TLSConfig

// Set defaults
if a.UserSearchFilter == "" {
Expand Down Expand Up @@ -261,9 +266,17 @@ func (a authLDAP) dial() (*ldap.Conn, error) {
l, err = ldap.Dial("tcp", fmt.Sprintf("%s:%s", host, a.portFromScheme(u.Scheme, port)))

case "ldaps":
tlsConfig := &tls.Config{ServerName: host}

if a.TLSConfig != nil && a.TLSConfig.ValidateHostname != "" {
tlsConfig.ServerName = a.TLSConfig.ValidateHostname
} else if a.TLSConfig != nil && a.TLSConfig.AllowInsecure {

This comment has been minimized.

Copy link
@Xaroth

Xaroth Sep 24, 2018

I would personally not make this an else-if, but rather a separate if block. If you have validate_hostname set in the config, allow_insecure would do nothing in this case, which might be confusing.

tlsConfig = &tls.Config{InsecureSkipVerify: true}
}

l, err = ldap.DialTLS(
"tcp", fmt.Sprintf("%s:%s", host, a.portFromScheme(u.Scheme, port)),
&tls.Config{ServerName: host},
tlsConfig,
)

default:
Expand Down
9 changes: 9 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ providers:
# Replace DN as the username with another attribute
# Optional, defaults to "dn"
username_attribute: "uid"
# Configure TLS parameters for LDAPs connections
# Optional, defaults to null
tls_config:
# Set the hostname for certificate validation
# Optional, defaults to host from the connection URI
validate_hostname: ldap.example.com
# Disable certificate validation, will be ignored when validate_hostname is set
# Optional, defaults to false
allow_insecure: false

# Authentication against embedded user database
# Supports: Users, Groups
Expand Down

0 comments on commit 4d2e8fb

Please sign in to comment.