LDAP Authentication¶
Traefik Enterprise can integrate with LDAP in order to restrict the access to applications.
Authentication in Traefik Enterprise is implemented as a middleware. To avoid having sensitive information such as LDAP credentials specified as labels (or in CRDs) by applications and to allow multiple middlewares to reuse the same authentication method, the reusable portion of the configuration is externalized in Authentication Sources.
Authentication Sources are defined in the static configuration of the cluster and are referenced by authentication middlewares.
Authentication Source¶
Before configuring an LDAP middleware, an LDAP Authentication Source must be defined in the static configuration.
Authentication Source Options¶
url¶
Required, Default=""
The url option should be set to the URL of your LDAP server. It should use either the ldaps or ldap protocol and end with a port, like ldaps://ldap.example.org:636 for example.
authSources:
ldapSource:
ldap:
url: ldaps://ldap.example.org:636[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
url = "ldaps://ldap.example.org:636"startTLS¶
Optional, Default=false
startTLS, if set to true, instructs Traefik Enterprise to issue a StartTLS request when initializing the connection with the LDAP server.
authSources:
ldapSource:
ldap:
startTLS: true[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
startTLS = truecertificateAuthority¶
Optional, Default=""
The certificateAuthority option should contain a PEM-encoded certificate to use to establish a connection with the LDAP server if the connection uses TLS but that the certificate was signed by a custom Certificate Authority.
authSources:
ldapSource:
ldap:
certificateAuthority: |-
-----BEGIN CERTIFICATE-----
MIIB9TCCAWACAQAwgbgxGTAXBgNVBAoMEFF1b1ZhZGlzIExpbWl0ZWQxHDAaBgNV
BAsME0RvY3VtZW50IERlcGFydG1lbnQxOTA3BgNVBAMMMFdoeSBhcmUgeW91IGRl
Y29kaW5nIG1lPyAgVGhpcyBpcyBvbmx5IGEgdGVzdCEhITERMA8GA1UEBwwISGFt
aWx0b24xETAPBgNVBAgMCFBlbWJyb2tlMQswCQYDVQQGEwJCTTEPMA0GCSqGSIb3
DQEJARYAMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ9WRanG/fUvcfKiGl
EL4aRLjGt537mZ28UU9/3eiJeJznNSOuNLnF+hmabAu7H0LT4K7EdqfF+XUZW/2j
RKRYcvOUDGF9A7OjW7UfKk1In3+6QDCi7X34RE161jqoaJjrm/T18TOKcgkkhRzE
apQnIDm0Ea/HVzX/PiSOGuertwIDAQABMAsGCSqGSIb3DQEBBQOBgQBzMJdAV4QP
Awel8LzGx5uMOshezF/KfP67wJ93UW+N7zXY6AwPgoLj4Kjw+WtU684JL8Dtr9FX
ozakE+8p06BpxegR4BR3FMHf6p+0jQxUEAkAyb/mVgm66TyghDGC6/YkiKoZptXQ
98TwDIK/39WEB/V607As+KoYazQG8drorw==
-----END CERTIFICATE-----[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
certificateAuthority = """
-----BEGIN CERTIFICATE-----
MIIB9TCCAWACAQAwgbgxGTAXBgNVBAoMEFF1b1ZhZGlzIExpbWl0ZWQxHDAaBgNV
BAsME0RvY3VtZW50IERlcGFydG1lbnQxOTA3BgNVBAMMMFdoeSBhcmUgeW91IGRl
Y29kaW5nIG1lPyAgVGhpcyBpcyBvbmx5IGEgdGVzdCEhITERMA8GA1UEBwwISGFt
aWx0b24xETAPBgNVBAgMCFBlbWJyb2tlMQswCQYDVQQGEwJCTTEPMA0GCSqGSIb3
DQEJARYAMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ9WRanG/fUvcfKiGl
EL4aRLjGt537mZ28UU9/3eiJeJznNSOuNLnF+hmabAu7H0LT4K7EdqfF+XUZW/2j
RKRYcvOUDGF9A7OjW7UfKk1In3+6QDCi7X34RE161jqoaJjrm/T18TOKcgkkhRzE
apQnIDm0Ea/HVzX/PiSOGuertwIDAQABMAsGCSqGSIb3DQEBBQOBgQBzMJdAV4QP
Awel8LzGx5uMOshezF/KfP67wJ93UW+N7zXY6AwPgoLj4Kjw+WtU684JL8Dtr9FX
ozakE+8p06BpxegR4BR3FMHf6p+0jQxUEAkAyb/mVgm66TyghDGC6/YkiKoZptXQ
98TwDIK/39WEB/V607As+KoYazQG8drorw==
-----END CERTIFICATE-----
"""insecureSkipVerify¶
Optional, Default=false
When TLS is enabled, the connection to the LDAP server is verified to be secure. This option allows Traefik Enterprise to proceed and operate even for server connections otherwise considered insecure.
authSources:
ldapSource:
ldap:
insecureSkipVerify: true[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
insecureSkipVerify = truebindDN¶
Optional, Default=""
The domain name to bind to in order to authenticate to the LDAP server when running on search mode. Leaving this empty with search mode means binds are anonymous, which is rarely expected behavior. It is not used when running in bind mode.
authSources:
ldapSource:
ldap:
bindDN: cn=admin,dc=example,dc=com[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
bindDN = "cn=admin,dc=example,dc=com"bindPassword¶
Optional, Default=""
The password corresponding to the bindDN specified when running in search mode, used in order to authenticate to the LDAP server.
authSources:
ldapSource:
ldap:
bindPassword: mypassword[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
bindPassword = "mypassword"connPool¶
Optional, Default=None
In order to minimize the impact on the performance of requests using an LDAP authentication middleware, Traefik Enterprise keeps a pool of connections to the LDAP server and reuses them instead of opening a new connection for each request.
connPool.size¶
Optional, Default=10
The number of connections managed by the pool can be customized with the size property.
authSources:
ldapSource:
ldap:
connPool:
size: 42[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
[authSources.ldapSource.ldap.connPool]
size = 42connPool.burst¶
Optional, Default=5
burst connections are ephemeral connections that are opened when the pool is already full. Once the number of connection exceeds size + burst, a Too Many Connections error is returned.
authSources:
ldapSource:
ldap:
connPool:
burst: 42[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
[authSources.ldapSource.ldap.connPool]
burst = 42connPool.ttl¶
Optional, Default=60s
Pooled connections are still meant to be short-lived, so they are closed after roughly one minute by default. This behavior can be modified with the ttl property.
authSources:
ldapSource:
ldap:
connPool:
ttl: 42s[authSources]
[authSources.ldapSource]
[authSources.ldapSource.ldap]
[authSources.ldapSource.ldap.connPool]
ttl = 42sLDAP Middleware¶
After declaring an LDAP Authentication Source in the static configuration of the cluster, LDAP middlewares can be added to routers.
The LDAP middleware will look for user credentials in the Authorization header of each request. Credentials must be encoded with the following format: base64(username:password).
Bind Mode vs Search Mode¶
If no filter is specified in its configuration, the middleware runs in the default bind mode, meaning it tries to make a simple bind request to the LDAP server with the credentials provided in the request headers. If the bind succeeds, the middleware forwards the request, otherwise it returns a 401 Unauthorized status code.
If a filter query is specified in the middleware configuration, and the Authentication Source referenced has a bindDN and a bindPassword, then the middleware runs in search mode. In this mode, a search query with the given filter is issued to the LDAP server before trying to bind. If result of this search returns only 1 record, it tries to issue a bind request with this record, otherwise it aborts a 401 Unauthorized status code.
Middleware Options¶
source¶
Required, Default=""
The source option should contain the name of the authentication source used by the middleware.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.source=ldapSource"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
source: ldapSource- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.source=ldapSource""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.source": "ldapSource"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.source=ldapSource"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
source: ldapSource[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
source = "ldapSource"baseDN¶
Required, Default=""
The baseDN option should be set to the base domain name that should be used for bind and search queries.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.baseDN=dc=example,dc=com"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
baseDN: dc=example,dc=com- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.baseDN=dc=example,dc=com""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.baseDN": "dc=example,dc=com"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.baseDN=dc=example,dc=com"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
baseDN: dc=example,dc=com[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
baseDN = "dc=example,dc=com"attribute¶
Required, Default="cn"
The attribute used to bind a user. Bind queries use this pattern: <attr>=<username>,<baseDN>, where the username is extracted from the request header.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.attribute=cn"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
attribute: cn- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.attribute=cn""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.attribute": "cn"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.attribute=cn"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
attribute: cn[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
attribute = "cn"forwardUsername¶
Optional, Default=""
The forwardUsername option can be enabled to forward the username in a specific header, defined using the forwardUsernameHeader option.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsername=true"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
forwardUsername: true- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsername=true""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsername": "true"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsername=true"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
forwardUsername: true[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
forwardUsername = trueforwardUsernameHeader¶
Required, Default="Username"
Name of the header to put the username in when forwarding it. This is not used if the forwardUsername option is set to false.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsernameHeader=userID"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
forwardUsernameHeader: userID- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsernameHeader=userID""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsernameHeader": "userID"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardUsernameHeader=userID"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
forwardUsernameHeader: userID[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
forwardUsernameHeader = "userID"forwardAuthorization¶
Required, Default=false
The forwardAuthorization option determines if the authorization header will be forwarded or stripped from the request after it has been approved by the middleware.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardAuthorization=true"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
forwardAuthorization: true- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardAuthorization=true""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardAuthorization": "true"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.forwardAuthorization=true"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
forwardAuthorization: true[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
forwardAuthorization = truesearchFilter¶
Optional, Default=""
If not empty, the middleware will run in search mode, filtering search results with the given query.
Filter queries can use the %s placeholder that is replaced by the username provided in the Authorization header of the request.
For example: (&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s)).
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.searchFilter=(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
searchFilter: "(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.searchFilter=(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.searchFilter": "(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.searchFilter=(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
searchFilter: "(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
searchFilter = "(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"wwwAuthenticateHeader¶
Optional, Default=false
If the LDAP middleware receives a request with a missing or invalid Authorization header and wwwAuthenticateHeader is enabled, it will set a WWW-Authenticate header in the 401 Unauthorized response. See the WWW-Authenticate header documentation for more information.
Note
The realm directive of the WWW-Authenticate header can be customized with the wwwAuthenticateHeaderRealm option.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeader=true"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
wwwAuthenticateHeader: true- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeader=true""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeader": "true"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeader=true"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
wwwAuthenticateHeader: true[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
wwwAuthenticateHeader = truewwwAuthenticateHeaderRealm¶
Optional, Default=""
The name of the realm to specify in the WWW-Authenticate header. This option is ineffective unless the wwwAuthenticateHeader option is set to true.
labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeaderRealm=myRealm"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap
spec:
plugin:
ldapAuth:
wwwAuthenticateHeaderRealm: "myRealm"- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeaderRealm=myRealm""labels": {
"traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeaderRealm": "myRealm"
}labels:
- "traefik.http.middlewares.test-ldap.plugin.ldapAuth.wwwAuthenticateHeaderRealm=myRealm"http:
middlewares:
test-ldap:
plugin:
ldapAuth:
wwwAuthenticateHeaderRealm: "myRealm"[http.middlewares]
[http.middlewares.test-ldap.plugin.ldapAuth]
wwwAuthenticateHeaderRealm = "myRealm"Advanced Configuration Examples¶
For applications to be secured with LDAP authentication, an ldapAuth middleware must be created and enabled in the router. Here are some examples of the middleware configuration in its simplest form depending on the provider you're using:
labels:
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.source=ldapSource"
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.baseDN=dc=example,dc=org"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap-auth
spec:
plugin:
ldapAuth:
source: ldapSource
baseDN: dc=example,dc=orghttp:
middlewares:
test-inflightreq:
plugin:
ldapAuth:
source: ldapSource
baseDN: dc=example,dc=org[http.middlewares]
[http.middlewares.test-ldap-auth.plugin.ldapAuth]
source = "ldapSource"
baseDN = "dc=example,dc=org"Below is a more advanced configuration example using search, bind and the WWW-Authenticate header:
labels:
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.source=ldapSource"
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.baseDN=dc=example,dc=org"
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.searchFilter=(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.forwardUsername=true"
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.forwardUsernameHeader=Custom-Username-Header-Name"
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.wwwAuthenticateHeader=true"
- "traefik.http.middlewares.test-ldap-auth.plugin.ldapAuth.wwwAuthenticateHeaderRealm=traefikee"apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-ldap-auth
spec:
plugin:
ldapAuth:
source: ldapSource
baseDN: dc=example,dc=org
searchFilter: (&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))
forwardUsername: true
forwardUsernameHeader: Custom-Username-Header-Name
wwwAuthenticateHeader: true
wwwAuthenticateHeaderRealm: traefikeehttp:
middlewares:
test-ldap-auth:
plugin:
ldapAuth:
source: ldapSource
baseDN: dc=example,dc=org
searchFilter: (&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))
forwardUsername: true
forwardUsernameHeader: Custom-Username-Header-Name
wwwAuthenticateHeader: true
wwwAuthenticateHeaderRealm: traefikee[http.middlewares]
[http.middlewares.test-ldap-auth.plugin.ldapAuth]
source = "ldapSource"
baseDN = "dc=example,dc=org"
searchFilter = "(&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s))"
forwardUsername = true
forwardUsernameHeader = "Custom-Username-Header-Name"
wwwAuthenticateHeader = true
wwwAuthenticateHeaderRealm = "traefikee"