shibboleth: Módulo de Solicitação de Autenticação Shibboleth para NGINX
Instalação
Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:
- RedHat Enterprise Linux 7, 8, 9 e 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 e Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-shibboleth
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-shibboleth
Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:
load_module modules/ngx_http_shibboleth_module.so;
Este documento descreve o nginx-module-shibboleth v2.0.2 lançado em 26 de maio de 2023.
Este módulo permite que o Nginx trabalhe com Shibboleth, através do autorizador FastCGI do Shibboleth. Este módulo requer uma configuração específica para funcionar corretamente, assim como a aplicação autorizadora FastCGI do Shibboleth disponível no sistema. Ele visa ser semelhante a partes do mod_shib do Apache, embora as configurações de autorização e autenticação do Shibboleth sejam configuradas através do shibboleth2.xml em vez de na configuração do servidor web.
Com este módulo configurado em um bloco location, as solicitações de entrada são autorizadas dentro do Nginx com base no resultado de uma subsolicitação ao autorizador FastCGI do Shibboleth. Nesse processo, este módulo pode ser usado para copiar atributos de usuário de uma resposta de autorizador bem-sucedida para a solicitação original do Nginx como cabeçalhos ou parâmetros de ambiente para uso por qualquer aplicação backend. Se a autorização não for bem-sucedida, o status e os cabeçalhos da resposta do autorizador são retornados ao cliente, negando o acesso ou redirecionando o navegador do usuário de acordo (como para uma página WAYF, se configurado assim).
Este módulo funciona na fase de acesso e, portanto, pode ser combinado com outros módulos de acesso (como access, auth_basic) através da diretiva satisfy. Este módulo também pode ser compilado junto com o ngx_http_auth_request_module, embora o uso de ambos os módulos no mesmo bloco location não tenha sido testado e não seja aconselhado.
Leia mais sobre o Comportamento abaixo e consulte Configuração para notas importantes sobre como evitar spoofing se estiver usando cabeçalhos para atributos.
Para mais informações sobre por que este é um módulo dedicado, veja https://forum.nginx.org/read.php?2,238523,238523#msg-238523
Diretrizes
As seguintes diretrizes são adicionadas aos seus arquivos de configuração do Nginx. Os contextos mencionados abaixo mostram onde elas podem ser adicionadas.
shib_request \<uri>|off | Contexto: http, server, location
Padrão: off
Ativa o módulo de solicitação de autenticação Shibboleth e define a URI que será solicitada para autorização. A URI configurada deve referir-se a um bloco de localização do Nginx que aponta para o seu autorizador FastCGI do Shibboleth.
O status HTTP e os cabeçalhos da resposta resultante da subsolicitação para a URI configurada serão retornados ao usuário, de acordo com a especificação do Autorizador FastCGI. A única (potencialmente significativa) ressalva é que, devido à forma como o Nginx opera atualmente em relação às subsolicitações (o que um Autorizador requer efetivamente), o corpo da solicitação não será encaminhado para o autorizador e, da mesma forma, o corpo da resposta do autorizador não será retornado ao cliente.
As URIs configuradas não estão restritas a usar um backend FastCGI para gerar uma resposta, no entanto. Isso pode ser útil durante testes ou de outra forma, pois você pode usar as diretivas internas return e rewrite do Nginx para produzir uma resposta adequada. Além disso, este módulo pode ser usado com qualquer autorizador FastCGI, embora a operação possa ser afetada pela ressalva acima.
[!WARNING] A diretiva
shib_requestnão requer mais a flagshib_authorizer. Esta deve ser removida para que o Nginx inicie. Nenhuma outra alteração é necessária.
shib_request_set \<variable> \<value>
Contexto: http, server, location
Padrão: none
Define a variable para o value especificado após a conclusão da solicitação de autenticação. O value pode conter variáveis da resposta da solicitação de autenticação. Por exemplo, $upstream_http_*, $upstream_status, e qualquer outra variável mencionada na documentação do nginx_http_upstream_module.
Esta diretiva pode ser usada para introduzir atributos do Shibboleth no ambiente da aplicação backend, como $_SERVER para uma aplicação PHP FastCGI e é o método recomendado para fazê-lo. Consulte a documentação de Configuração para um exemplo.
shib_request_use_headers on|off | Contexto: http, server, location
Padrão: off
[!NOTE] Adicionado na v2.0.0.
Copia atributos da resposta do autorizador Shibboleth para a solicitação principal como cabeçalhos, tornando-os disponíveis para servidores e aplicações upstream. Use esta opção apenas se seu upstream/aplicação não suportar parâmetros de servidor via shib_request_set.
Com esta configuração ativada, os cabeçalhos de resposta do Autorizador que começam com Variable-\* são extraídos, removendo a substring Variable- do nome do cabeçalho, e copiados para a solicitação principal antes de serem enviados para o backend. Por exemplo, um cabeçalho de resposta do autorizador como Variable-Commonname: John Smith resultaria em Commonname: John Smith sendo adicionado à solicitação principal, e assim enviado para o backend.
Cuidado com spoofing - você deve garantir que sua aplicação backend esteja protegida contra injeção de cabeçalhos. Consulte o exemplo de Configuração sobre como alcançar isso.
Configuração
Para detalhes completos sobre como configurar o ambiente Nginx/Shibboleth, consulte a documentação em https://github.com/nginx-shib/nginx-http-shibboleth/blob/master/CONFIG.rst.
Um exemplo de bloco server consiste no seguinte:
#Autorizador FastCGI para o módulo de Solicitação de Autenticação
location = /shibauthorizer {
internal;
include fastcgi_params;
fastcgi_pass unix:/opt/shibboleth/shibauthorizer.sock;
}
#Respondedor FastCGI
location /Shibboleth.sso {
include fastcgi_params;
fastcgi_pass unix:/opt/shibboleth/shibresponder.sock;
}
## Usando a diretiva ``shib_request_set``, podemos introduzir atributos como
## variáveis de ambiente para a aplicação backend. Neste exemplo, configuramos
## ``fastcgi_param`` mas isso poderia ser qualquer tipo de backend Nginx que
## suporte parâmetros (usando a opção *_param apropriada)
#
## Os ``shib_fastcgi_params`` são um conjunto opcional de parâmetros padrão,
## disponíveis no diretório ``includes/`` deste repositório.
#
## Escolha este tipo de configuração, a menos que sua aplicação backend
## não suporte parâmetros de servidor ou exija especificamente cabeçalhos.
location /secure-environment-vars {
shib_request /shibauthorizer;
include shib_fastcgi_params;
shib_request_set $shib_commonname $upstream_http_variable_commonname;
shib_request_set $shib_email $upstream_http_variable_email;
fastcgi_param COMMONNAME $shib_commonname;
fastcgi_param EMAIL $shib_email;
fastcgi_pass unix:/path/to/backend.socket;
}
## Uma localização segura. Todas as solicitações de entrada consultam o autorizador FastCGI do Shibboleth.
## Cuidado com problemas de desempenho e spoofing!
#
## Escolha este tipo de configuração para aplicações ``proxy_pass``
## ou backends que não suportam parâmetros de servidor.
location /secure {
shib_request /shibauthorizer;
shib_request_use_headers on;
# Atributos do Shibboleth são introduzidos como cabeçalhos pelo FastCGI
# autorizador, então devemos prevenir spoofing. O
# ``shib_clear_headers`` é um conjunto de diretivas de cabeçalho padrão,
# disponíveis no diretório `includes/` deste repositório.
include shib_clear_headers;
# Adicione *todos* os atributos que sua aplicação usa, incluindo todas
# as variações.
more_clear_input_headers 'displayName' 'mail' 'persistent-id';
# Esta aplicação backend receberá variáveis Shibboleth como cabeçalhos de solicitação
# (do autorizador FastCGI do Shibboleth)
proxy_pass http://localhost:8080;
}
Note que usamos o headers-more-nginx-module para limpar cabeçalhos de entrada potencialmente perigosos e evitar a possibilidade de spoofing. O último exemplo com variáveis de ambiente não é suscetível a spoofing de cabeçalhos, desde que o backend leia dados apenas dos parâmetros de ambiente somente.
Uma configuração padrão está disponível para limpar os cabeçalhos básicos do autorizador Shibboleth, mas você deve garantir que escreva suas próprias diretivas de limpeza para todos os atributos que sua aplicação usa. Tenha em mente que algumas aplicações tentarão ler um atributo do Shibboleth do ambiente e, em seguida, recorrerão aos cabeçalhos, então revise o código da sua aplicação mesmo que você não esteja usando shib_request_use_headers.
Com o uso de shib_request_set, um params padrão está disponível que você pode usar como um include do nginx para garantir que todas as variáveis principais do Shibboleth sejam passadas do autorizador FastCGI para a aplicação. Vários atributos padrão estão incluídos, então remova os que não são necessários pela sua aplicação e adicione atributos de Federação ou IDP que você precisa. Este arquivo de parâmetros padrão pode ser reutilizado para upstreams que não são FastCGI simplesmente mudando as diretivas fastcgi_param para uwsgi_param, scgi_param ou assim por diante.
Armadilhas
- Subsolicitações, como a solicitação de autenticação do Shibboleth, não são processadas através de filtros de cabeçalho. Isso significa que diretivas internas como
add_headernão funcionarão se configuradas como parte de um bloco/shibauthorizer. Se você precisar manipular cabeçalhos de subsolicitação, usemore_set_headersdo móduloheaders-more.
Veja https://forum.nginx.org/read.php?29,257271,257272#msg-257272.
Comportamento
Este módulo segue a especificação do Autorizador FastCGI sempre que possível, mas tem algumas notáveis desvios - com boa razão. O comportamento é assim:
-
Uma subsolicitação do autorizador é composta por todos os aspectos da solicitação original, exceto o corpo da solicitação, já que o Nginx não suporta o buffering de corpos de solicitação. Como o autorizador FastCGI do Shibboleth não considera o corpo da solicitação, isso não é um problema.
-
Se uma subsolicitação do autorizador retornar um status
200, o acesso é permitido.
Se shib_request_use_headers estiver habilitado, e os cabeçalhos de resposta que começam com Variable-\* forem extraídos, removendo a substring Variable- do nome do cabeçalho, e copiados para a solicitação principal. Outros cabeçalhos de resposta do autorizador que não estão prefixados com Variable- e o corpo da resposta são ignorados. A especificação FastCGI exige que pares nome-valor Variable-* sejam incluídos no ambiente FastCGI, mas nós os transformamos em cabeçalhos para que possam ser usados com qualquer backend (como proxy_pass) e não apenas restringir-nos a aplicações FastCGI. Ao passar os dados Variable-* como cabeçalhos, acabamos seguindo o comportamento de ShibUseHeaders On em mod_shib para Apache, que passa esses atributos de usuário como cabeçalhos.
Para passar atributos como variáveis de ambiente (o equivalente a ShibUseEnvironment On em mod_shib), os atributos devem ser extraídos manualmente usando diretivas shib_request_set para cada atributo. Isso não pode (atualmente) ser feito em massa para todos os atributos, já que cada backend pode aceitar parâmetros de maneira diferente (fastcgi_param, uwsgi_param, etc). Pull requests são bem-vindos para automatizar esse comportamento.
- Se a subsolicitação do autorizador retornar qualquer outro status (incluindo redirecionamentos ou erros), o status e os cabeçalhos da resposta do autorizador são retornados ao cliente.
Isso significa que em 401 Unauthorized ou 403 Forbidden, o acesso será negado e cabeçalhos (como WWW-Authenticate) do autorizador serão passados para o cliente. Todas as outras respostas do autorizador (como redirecionamentos 3xx) são passadas de volta ao cliente, incluindo status e cabeçalhos, permitindo redirecionamentos como aqueles para páginas WAYF e o respondedor do Shibboleth (Shibboleth.sso) funcionarem corretamente.
A especificação do Autorizador FastCGI exige que o corpo da resposta seja retornado ao cliente, mas como o Nginx atualmente não suporta o buffering de respostas de subsolicitação (NGX_HTTP_SUBREQUEST_IN_MEMORY), o corpo da resposta do autorizador é efetivamente ignorado. Uma solução alternativa é fazer com que o Nginx sirva uma error_page própria, assim:
location /secure {
shib_request /shibauthorizer;
error_page 403 /shibboleth-forbidden.html;
...
}
Isso serve a página de erro dada se o autorizador do Shibboleth negar acesso ao usuário a esta localização. Sem error_page especificado, o Nginx servirá suas páginas de erro genéricas.
Note que isso não se aplica ao respondedor do Shibboleth (tipicamente hospedado em Shibboleth.sso), pois é um respondedor FastCGI e o Nginx é totalmente compatível com isso, já que nenhuma subsolicitação é usada.
Para mais detalhes, veja https://forum.nginx.org/read.php?2,238444,238453.
Embora este módulo seja voltado especificamente para o autorizador FastCGI do Shibboleth, é provável que funcione com outros autorizadores, levando em consideração os desvios da especificação acima.
Testes
Os testes são executados automaticamente no GitHub Actions (usando esta configuração) sempre que novos commits são feitos no repositório ou quando novas pull requests são abertas. Se algo quebrar, você será informado e os resultados serão relatados no GitHub.
Os testes são escritos usando uma combinação de um simples script Bash para compilação do nosso módulo com diferentes versões e configurações do Nginx e a estrutura de teste Perl Test::Nginx para testes de integração. Consulte o link anterior para informações sobre como estender os testes e também consulte a documentação subjacente do Test::Base sobre aspectos como a função blocks().
Os testes de integração são executados automaticamente pelo CI, mas também podem ser executados manualmente (requer Perl e CPAN instalados):
cd nginx-http-shibboleth
cpanm --notest --local-lib=$HOME/perl5 Test::Nginx
## nginx deve estar presente no PATH e construído com símbolos de depuração
PERL5LIB=$HOME/perl5/lib/perl5 prove
Ajuda & Suporte
Solicitações de suporte para configuração do Shibboleth e configuração do Nginx ou servidor web devem ser direcionadas à lista de discussão da comunidade de usuários do Shibboleth. Veja https://www.shibboleth.net/community/lists/ para detalhes.
Depuração
Devido à natureza complexa da pilha nginx/FastCGI/Shibboleth, depurar problemas de configuração pode ser difícil. Aqui estão alguns pontos-chave:
-
Confirme que o
nginx-http-shibbolethfoi construído e instalado com sucesso dentro do nginx. Você pode verificar executandonginx -Ve inspecionando a saída para--add-module=[path]/nginx-http-shibbolethou--add-dynamic-module=[path]/nginx-http-shibboleth. -
Se estiver usando módulos dinâmicos para o nginx, confirme que você usou a diretiva
load_modulepara carregar este módulo. Seu uso deshib_requeste outras diretivas falhará se você se esquecer de carregar o módulo. -
Se estiver usando uma versão do nginx que é diferente daquelas que nós testamos ou se você estiver usando outros módulos de terceiros, você deve executar a suíte de testes acima para confirmar a compatibilidade. Se algum teste falhar, verifique sua configuração ou considere atualizar sua versão do nginx.
-
Configuração do Shibboleth: verifique seu
shibboleth2.xmle a configuração associada para garantir que seus hosts, caminhos e atributos estejam sendo liberados corretamente. Uma configuração de exemplo pode ajudá-lo a identificar "armadilhas" chave para configurar oshibboleth2.xmlpara funcionar com o autorizador FastCGI. -
Nível de aplicação: dentro do seu código, sempre comece com a saída de depuração mais simples possível (como imprimir o ambiente da solicitação) e trabalhe a partir daí. Se você quiser criar um aplicativo básico e autônomo, dê uma olhada na configuração do Bottle na wiki.
-
Depurando os internos do módulo: se você verificou cuidadosamente todos os itens acima, você também pode depurar o comportamento deste módulo em si. Você precisará ter compilado o nginx com suporte a depuração (via
./auto/configure --with-debug ...) e, ao executar o nginx, é mais fácil se você puder rodar em primeiro plano com o registro de depuração ativado. Adicione o seguinte ao seunginx.conf:daemon off; error_log stderr debug;e execute o nginx. Ao iniciar o nginx, você deve ver linhas contendo [debug] e, à medida que você faz solicitações, o registro no console continuará. Se isso não acontecer, verifique sua configuração e processo de compilação do nginx.
Quando você eventualmente fizer uma solicitação que atinja (ou deva invocar) o bloco de localização
shib_request, você verá linhas como estas na saída:[debug] 1234#0: shib request handler [debug] 1234#0: shib request set variables [debug] 1234#0: shib request authorizer handler [debug] 1234#0: shib request authorizer allows access [debug] 1234#0: shib request authorizer copied header: "AUTH_TYPE: shibboleth" [debug] 1234#0: shib request authorizer copied header: "REMOTE_USER: [email protected]" ...Se você não vir esses tipos de linhas contendo shib request ..., ou se você ver algumas das linhas acima, mas não onde os cabeçalhos/variáveis estão sendo copiados, então verifique novamente sua configuração do nginx. Se você ainda não estiver conseguindo resolver, pode adicionar suas próprias linhas de depuração no código-fonte (siga os exemplos deste módulo) para eventualmente determinar o que está dando errado e quando. Se fizer isso, não se esqueça de recompilar o nginx e/ou
nginx-http-shibbolethsempre que fizer uma alteração.
Se você acredita que encontrou um bug no código do módulo principal, por favor, crie um issue.
Você também pode pesquisar issues existentes, pois é provável que alguém tenha encontrado um problema semelhante antes.