
Um dos problemas irritantes que surgem ao criar um NAS é que nem todos os softwares podem funcionar com LDAP e alguns não contêm mecanismos de autenticação.
A solução é autenticação de ponta a ponta através de um proxy reverso.
Um exemplo de como fazer isso é discutido em detalhes, por exemplo, neste artigo .
Como este artigo faz parte do ciclo do NAS ,
aqui vou me concentrar em como adaptar essa solução aos serviços em contêineres do Docker.
A solução é baseada no exemplo de implementação de autenticação por meio de um agente externo Nginx LDAP Auth , mas eu uso a versão em contêiner do LinuxServer.io porque é uma imagem pronta que atende a certos padrões.
O único problema foi que os patches do LinuxServer.io quebraram a autenticação HTTP básica, mas após o upload do bugfix , tornou-se possível usá-lo novamente.
Autenticação geral
Conforme mostrado nos artigos, a autenticação é realizada da seguinte maneira:
- O cliente acessa o serviço.
- O proxy reverso será redirecionado se um cookie estiver definido.
- Se não houver cookie, é feita uma solicitação ao serviço de autenticação.
- O serviço de autenticação solicita um nome de usuário e senha, que são verificados acessando o servidor LDAP.
- Se a verificação for bem-sucedida, ela define um cookie e redireciona para o serviço.

Uma opção alternativa pode ser o uso de um módulo compilado para o nginx, mas não considerarei essa opção aqui devido a alguns problemas com esse módulo e sua menor flexibilidade.
Uma imagem modificada para o servidor OpenLDAP está aqui .
Autenticação de contêiner
No NAS, os serviços funcionam em contêineres; portanto, é necessário fazê-lo para que seja possível alternar os modos de autenticação simplesmente configurando as variáveis dentro do contêiner.
Esse mecanismo já está na imagem ngingx-proxy usada e é implementado por meio de modelos que docker-gen processam.
Ele insere metadados no modelo que contém uma descrição dos contêineres do Docker em execução no momento.
Portanto, tudo o que precisa ser feito é refinar o modelo de configuração do proxy reverso para que, se houver uma variável condicional no contêiner, o redirecionamento para o serviço de autenticação de ponta a ponta, que também funciona no contêiner, seja incluído.
Em seguida, faça os ajustes apropriados na configuração da janela de encaixe-composição.
Implementação de autenticação
Modificação do modelo de configuração nginx-proxy
Primeiro de tudo, é adicionado um novo upstream, que permite acessar o serviço de autenticação na configuração:
proxy_cache_path cache/ keys_zone=auth_cache:10m; upstream ldap-backend { server {{ $.Env.LDAP_BACKEND }}:{{ or $.Env.LDAP_LOGIN_PORT "9000" }}; }
Pode-se observar que o serviço de autenticação é executado no host ${LDAP_BACKEND}
e na porta ${LDAP_LOGIN_PORT }
, o padrão é 9000.
Os valores das variáveis serão substituídos por docker-gen, de modo que esta parte da configuração /etc/nginx/conf.d/default.conf
assim em /etc/nginx/conf.d/default.conf
dentro do contêiner:
A adição a seguir define a variável ext_ldap_auth
se a variável LDAP_EXT_AUTH foi montada em um determinado contêiner de serviço.
Além disso, mais algumas variáveis são definidas para configurar a autenticação.
{{/* 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" ) }}
O bloco principal de adições é dado abaixo. É ativado apenas se a variável ext_ldap_auth
estiver ext_ldap_auth
.
Se ldap_use_login_page
definido, o redirecionamento para a página de autenticação será ativado, caso contrário, a janela de autenticação básica HTTP será usada.
O caminho /auth-proxy
é o redirecionamento para o serviço de autenticação.
Os parâmetros serão passados através de cabeçalhos HTTP.
Quais parâmetros e por que são necessários estão descritos em detalhes nos comentários.
Seção LDAP {{ if ($ext_ldap_auth) }}
Por fim, quando a autenticação LDAP para o serviço está ativada, auth_request
adicionado ao seu local:
location / { {{ if ($ext_ldap_auth) }} auth_request /auth-proxy; {{ if ($ldap_use_login_page) }}
A seguir, é apresentada uma lista completa do modelo.
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 }}
Modificação de configuração de composição do Docker
No docker-compose.yml
foram adicionados:
- Novo serviço "ldap-auth", responsável pela autorização.
- Um bloco de variáveis que configuram interações com o servidor LDAP.
O que está escrito nas variáveis, nginx passará o serviço de autenticação através de cabeçalhos HTTP.
O objetivo dos parâmetros é claro nos nomes das variáveis, portanto, não vou me debruçar sobre eles.
Veja a configuração completa abaixo.
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"
Uso por serviço
A autenticação de ponta a ponta está desativada por padrão.
Para habilitá-lo, basta definir as variáveis no ambiente do contêiner desejado:
LDAP_EXT_AUTH=true
- ative a autenticação.LDAP_EXT_ADD_GROUPS=(memberOf=cn=users_cloud,ou=groups,dc=nas,dc=nas)
- um filtro opcional, uma lista de grupos dos quais o usuário deve ser membro para ser autenticado. Isso fornece suporte de autorização.
environment: - LDAP_EXT_AUTH=true - LDAP_EXT_ADD_GROUPS=(memberOf=cn=users_cloud,ou=groups,dc=nas,dc=nas)
Conclusão
Em geral, a solução trabalha há muito tempo e fornece não apenas autenticação, mas também autorização.
Isso permite que você use quaisquer serviços em contêineres no NAS, independentemente de eles suportarem autenticação por LDAP.
Embora haja alguns problemas:
- HTML ,
ldap_use_login_page
. . — . - . LDAP , , docker-gen .
- , . , , , . .
NAS .