LDAP Authentication for Nginx, Kubernetes ingress controller (Nginx), HAProxy (haproxy-auth-request) or any webserver/reverse proxy with authorization based on the result of a subrequest.
Another LDAP Authentication is an implementation of the ldap-auth-daemon services described in the official blog from Nginx in the following article.
Another LDAP Authentication it's prepared to run inside a Docker container, also you can run the Python script without the Docker container. Supports ldap and ldaps and provide a simple cache.
The easy way to use Another LDAP Authentication is running as a Docker container and set the parameters via environment variables.
Change the environment variables with your setup.
docker run -d \
-e LDAP_ENDPOINT='ldaps://testmyldap.com:636' \
-e LDAP_MANAGER_DN_USERNAME='CN=john-service-user,OU=Administrators,DC=TESTMYLDAP,DC=COM' \
-e LDAP_MANAGER_PASSWORD='MasterpasswordNoHack123' \
-e LDAP_SERVER_DOMAIN='TESTMYLDAP.COM' \
-e LDAP_SEARCH_BASE='DC=TESTMYLDAP,DC=COM' \
-e LDAP_SEARCH_FILTER='(sAMAccountName={username})' \
-p 9000:9000 \
--name another_ldap_auth \
dignajar/another-ldap-auth:latest
Another LDAP Authentication now is running on http://localhost:9000.
Nginx use the module ngx_http_auth_request_module to do the subrequest.
The following example shows how to configure Nginx which is running in the same machine as Another LDAP Authentication. The backend /private/ includes the authentication request to /another_ldap_auth.
location /private/ {
auth_request /another_ldap_auth;
# ...
# Here you private site
}
location = /another_ldap_auth {
internal;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://localhost:9000;
}
Another LDAP Auth deployment manifest, another-deployment.yaml.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: another-ldap-auth
namespace: ingress-nginx
labels:
app: another-ldap-auth
spec:
replicas: 1
selector:
matchLabels:
app: another-ldap-auth
template:
metadata:
labels:
app: another-ldap-auth
spec:
containers:
- image: dignajar/another-ldap-auth:latest
name: another-ldap-auth
ports:
- name: http
containerPort: 9000
env:
- name: LDAP_ENDPOINT
value: "ldaps://testmyldap.com:636"
- name: LDAP_MANAGER_DN_USERNAME
value: "CN=john-service-user,OU=Administrators,DC=TESTMYLDAP,DC=COM"
- name: LDAP_SERVER_DOMAIN
value: "TESTMYLDAP"
- name: LDAP_SEARCH_BASE
value: "DC=TESTMYLDAP,DC=COM"
- name: LDAP_SEARCH_FILTER
value: "(sAMAccountName={username})"
- name: LDAP_MANAGER_PASSWORD
valueFrom:
secretKeyRef:
name: another-ldap-auth
key: LDAP_MANAGER_PASSWORD
Another LDAP Auth secret manifest, another-secret.yaml.
---
apiVersion: v1
kind: Secret
metadata:
name: another-ldap-auth
namespace: ingress-nginx
type: Opaque
data:
LDAP_MANAGER_PASSWORD: <your-password-in-base64>
Another LDAP Auth service manifest, another-service.yaml.
---
kind: Service
apiVersion: v1
metadata:
name: another-ldap-auth
namespace: ingress-nginx
spec:
type: ClusterIP
selector:
app: another-ldap-auth
ports:
- name: another-ldap-auth
port: 80
protocol: TCP
targetPort: 9000
Ingress manifest for the application you want to add authentication. You can remove the un-comment and send headers as variables such as Required groups.
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demo-webserver
namespace: demo
annotations:
nginx.ingress.kubernetes.io/auth-url: http://another-ldap-auth.ingress-nginx.svc.cluster.local
# nginx.ingress.kubernetes.io/auth-snippet: |
# proxy_set_header Ldap-Required-Groups "<SOME GROUP>";
spec:
rules:
- host: demo.local
http:
paths:
- path: /
backend:
serviceName: demo-webserver
servicePort: 80
The parameters can be sent via environment variables or via HTTP headers, also you can combine them.
The parameters LDAP_SEARCH_FILTER and LDAP_AUTH_FILTER supports variable expansion with the username, you can do something like this (sAMAccountName={username}) and {username} is going to be replaced by the username typed in the login form.
LDAP_ENDPOINTLDAP URL with the port number. Ex:ldaps://testmyldap.com:636LDAP_MANAGER_DN_USERNAMEUsername to bind and search in the LDAP tree. Ex:CN=john-service-user,OU=Administrators,DC=TESTMYLDAP,DC=COMLDAP_MANAGER_PASSWORDPassword for the bind user.LDAP_SEARCH_BASEEx:DC=TESTMYLDAP,DC=COMLDAP_SEARCH_FILTERFilter to search, for Microsoft Active Directory usually you can usesAMAccountName. Ex:(sAMAccountName={username})LDAP_SERVER_DOMAIN(Optional), for Microsoft Active Directory usually need the domain name for authenticate the user. Ex:TESTMYLDAP.COMLDAP_REQUIRED_GROUPS(Optional), required groups are case insensitive (DevOpsis the same asDEVOPS), you can send a list separated by commas, try first without required groups. Ex:'DevOps', 'DevOps_QA'LDAP_AUTH_FILTER(Optional) Filter to apply to username before authentication.CACHE_EXPIRATION(Optional, default=5) Expiration time in minutes for the cache. Ex:10
Ldap-EndpointLdap-Manager-Dn-UsernameLdap-Manager-PasswordLdap-Search-BaseLdap-Search-FilterLdap-Server-Domain(Optional)Ldap-Required-Groups(Optional)Ldap-Auth-Filter(Optional)
- Parameters via headers need to be escaped, for example, you can not send parameters such as
$1or$testbecause Nginx is applying variable expansion.
