
L'un des problèmes gênants qui se posent lors de la création d'un NAS est que tous les logiciels ne peuvent pas fonctionner avec LDAP, et certains ne contiennent pas de mécanismes d'authentification.
La solution est l'authentification de bout en bout via un proxy inverse.
Un exemple de la façon de procéder est expliqué en détail, par exemple, dans cet article .
Étant donné que cet article fait partie du cycle NAS ,
ici, je vais me concentrer sur la façon d'adapter cette solution aux services dans les conteneurs Docker.
La solution est basée sur l'exemple de l'implémentation de l'authentification via un agent Nginx LDAP Auth externe, mais j'utilise la version conteneurisée de LinuxServer.io car c'est une image prête à l'emploi qui répond à certaines normes.
Le seul problème était que les correctifs LinuxServer.io ont cassé l'authentification HTTP de base, mais après le téléchargement du correctif , il est devenu possible de l'utiliser à nouveau.
Authentification générale
Comme indiqué dans les articles, l'authentification est effectuée comme suit:
- Le client accède au service.
- Le proxy inverse redirigera si un cookie est défini.
- S'il n'y a pas de cookie, une demande est faite auprès du service d'authentification.
- Le service d'authentification demande un nom d'utilisateur et un mot de passe, qu'il vérifie en accédant au serveur LDAP.
- Si la vérification réussit, il place un cookie et redirige vers le service.

Une alternative peut être d'utiliser un module compilé pour nginx, mais je ne considérerai pas cette option ici en raison de certains problèmes avec ce module et de sa moins grande flexibilité.
Une image modifiée pour le serveur OpenLDAP est ici .
Authentification de conteneur
Au sein du NAS, les services fonctionnent dans des conteneurs, il y a donc un désir de permettre de changer de mode d'authentification en définissant simplement les variables à l'intérieur du conteneur.
Un tel mécanisme est déjà présent dans l' image proxy ngingx utilisée et il est implémenté via des modèles qui ancrent les processus de génération .
Il insère des métadonnées dans le modèle qui contient une description des conteneurs Docker en cours d'exécution.
Ainsi, tout ce qui doit être fait est d'affiner le modèle de configuration du proxy inverse afin que s'il y a une variable conditionnelle dans le conteneur, la redirection vers le service d'authentification de bout en bout, qui fonctionne également dans le conteneur, soit incluse.
Ensuite, apportez les ajustements appropriés à la configuration de composition de docker.
Implémentation de l'authentification
Modification du modèle de configuration de nginx-proxy
Tout d'abord, un nouveau amont est ajouté, ce qui vous permet d'accéder au service d'authentification dans la config:
proxy_cache_path cache/ keys_zone=auth_cache:10m; upstream ldap-backend { server {{ $.Env.LDAP_BACKEND }}:{{ or $.Env.LDAP_LOGIN_PORT "9000" }}; }
On peut voir que le service d'authentification s'exécute sur l'hôte ${LDAP_BACKEND}
et le port ${LDAP_LOGIN_PORT }
, par défaut 9000.
Les valeurs des variables seront remplacées par docker-gen afin que cette partie de la configuration ressemble à ceci dans /etc/nginx/conf.d/default.conf
à l'intérieur du conteneur:
L'addition suivante définit la variable ext_ldap_auth
si la variable LDAP_EXT_AUTH a été armée dans un conteneur d'un certain service.
En outre, quelques autres variables sont définies pour configurer l'authentification.
{{/* Nginx LDAP authentication enabled */}} {{ $ext_ldap_auth := parseBool (or (first (groupByKeys $containers "Env.LDAP_EXT_AUTH")) "false") }} {{/* User need to be participated in these groups to use service */}} {{ $ldap_add_groups := or (first (groupByKeys $containers "Env.LDAP_EXT_ADD_GROUPS")) "" }} {{/* Use HTML login page or HTTP Basic authentication */}} {{ $ldap_use_login_page := parseBool (or $.Env.LDAP_USE_LOGIN_PAGE "false" ) }}
Le bloc principal des ajouts est donné ci-dessous. Il n'est activé que si la variable ext_ldap_auth
est ext_ldap_auth
.
Si ldap_use_login_page
défini, la redirection vers la page d'authentification sera activée, sinon la fenêtre d'authentification de base HTTP sera utilisée.
Le chemin d'accès /auth-proxy
est la redirection vers le service d'authentification.
Les paramètres seront transmis via les en-têtes HTTP.
Quels paramètres et pourquoi sont nécessaires, sont décrits en détail dans les commentaires.
Section LDAP {{ if ($ext_ldap_auth) }}
Enfin, lorsque l'authentification LDAP pour le service est activée, auth_request
ajouté à son emplacement:
location / { {{ if ($ext_ldap_auth) }} auth_request /auth-proxy; {{ if ($ldap_use_login_page) }}
Ce qui suit est une liste complète du modèle.
nginx.tmpl {{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }} {{ define "upstream" }} {{ if .Address }} {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} {{ if and .Container.Node.ID .Address.HostPort }} # {{ .Container.Node.Name }}/{{ .Container.Name }} server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }}; {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}} {{ else if .Network }}
Modification de la configuration de Docker-compose
Dans docker-compose.yml
ont été ajoutés:
- Nouveau service "ldap-auth", qui est responsable de l'autorisation.
- Un bloc de variables qui configure les interactions avec le serveur LDAP.
Ce qui est écrit dans les variables, nginx passera le service d'authentification via des en-têtes HTTP.
Le but des paramètres est clair à partir des noms de variables, donc je ne m'attarderai pas sur eux.
Voir la configuration complète ci-dessous.
docker-compose.yml version: '2' networks: internal: docker0: external: name: docker0 services: ldap-auth: image: linuxserver/ldap-auth:latest container_name: ldap-auth networks: - internal - docker0 environment: - TZ=Europe/Moscow expose: - 8888 - 9000 restart: unless-stopped nginx-proxy: depends_on: - ldap-auth networks: - internal - docker0 restart: always image: jwilder/nginx-proxy ports: - "80:80" - "443:443" volumes: - ./certs:/etc/nginx/certs:ro - ./vhost.d:/etc/nginx/vhost.d - ./html:/usr/share/nginx/html - /var/run/docker.sock:/tmp/docker.sock:ro - ./local-config:/etc/nginx/conf.d - ./nginx.tmpl:/app/nginx.tmpl environment: - DEFAULT_HOST=nas.nas - LDAP_BACKEND=ldap-auth #- LDAP_BACKEND_PORT=8888 #- LDAP_LOGIN_PORT=9000 - LDAP_HOST=ldap://172.21.0.1:389 #- LDAP_METHOD=start_tls - LDAP_METHOD=plain - LDAP_UID=uid - LDAP_PASS=LDAP_PASSWORD - LDAP_BASE=ou=users,dc=nas,dc=nas - LDAP_BIND_DN=cn=readonly,dc=nas,dc=nas - LDAP_USER_FILTER=(uid=%(username)s) #- LDAP_USE_LOGIN_PAGE=true labels: - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true" letsencrypt-dns: image: adferrand/letsencrypt-dns restart: always volumes: - ./certs/letsencrypt:/etc/letsencrypt environment: - "LETSENCRYPT_USER_MAIL=MAIL@MAIL.COM" - "LEXICON_PROVIDER=cloudns" - "LEXICON_OPTIONS=--delegated NAS.cloudns.cc" - "LEXICON_PROVIDER_OPTIONS=--auth-id=CLOUDNS_ID --auth-password=CLOUDNS_PASSWORD"
Utilisation par service
L'authentification de bout en bout est désactivée par défaut.
Pour l'activer, il suffit de définir les variables dans l'environnement du conteneur souhaité:
LDAP_EXT_AUTH=true
- LDAP_EXT_AUTH=true
authentification.LDAP_EXT_ADD_GROUPS=(memberOf=cn=users_cloud,ou=groups,dc=nas,dc=nas)
- un filtre facultatif, une liste de groupes dont l'utilisateur doit être membre pour être authentifié. Cela fournit un support d'autorisation.
environment: - LDAP_EXT_AUTH=true - LDAP_EXT_ADD_GROUPS=(memberOf=cn=users_cloud,ou=groups,dc=nas,dc=nas)
Conclusion
En général, la solution fonctionne depuis longtemps et fournit non seulement une authentification, mais également une autorisation.
Cela vous permet d'utiliser tous les services dans des conteneurs du NAS, qu'ils prennent en charge l'authentification via LDAP ou non.
Bien qu'il y ait quelques problèmes:
- HTML ,
ldap_use_login_page
. . — . - . LDAP , , docker-gen .
- , . , , , . .
NAS .