Aller au contenu

shibboleth: Module de demande d'authentification Shibboleth pour NGINX

Installation

Vous pouvez installer ce module dans n'importe quelle distribution basée sur RHEL, y compris, mais sans s'y limiter :

  • RedHat Enterprise Linux 7, 8, 9 et 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 et 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

Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :

load_module modules/ngx_http_shibboleth_module.so;

Ce document décrit nginx-module-shibboleth v2.0.2 publié le 26 mai 2023.


image

Ce module permet à Nginx de fonctionner avec Shibboleth, via l'autorisateur FastCGI de Shibboleth. Ce module nécessite une configuration spécifique pour fonctionner correctement, ainsi que l'application d'autorisation FastCGI de Shibboleth disponible sur le système. Il vise à être similaire à certaines parties de Apache's mod_shib, bien que les paramètres d'autorisation et d'authentification de Shibboleth soient configurés via shibboleth2.xml plutôt que dans la configuration du serveur web.

Avec ce module configuré contre un bloc location, les demandes entrantes sont autorisées au sein de Nginx en fonction du résultat d'une sous-requête à l'autorisateur FastCGI de Shibboleth. Dans ce processus, ce module peut être utilisé pour copier les attributs utilisateur d'une réponse d'autorisation réussie dans la demande originale de Nginx en tant qu'en-têtes ou paramètres d'environnement à utiliser par toute application backend. Si l'autorisation échoue, le statut et les en-têtes de réponse de l'autorisateur sont renvoyés au client, refusant l'accès ou redirigeant le navigateur de l'utilisateur en conséquence (comme vers une page WAYF, si configurée ainsi).

Ce module fonctionne à la phase d'accès et peut donc être combiné avec d'autres modules d'accès (comme access, auth_basic) via la directive satisfy. Ce module peut également être compilé aux côtés de ngx_http_auth_request_module, bien que l'utilisation de ces deux modules dans le même bloc location ne soit pas testée et ne soit pas conseillée.

Lisez plus sur le Comportement ci-dessous et consultez la Configuration pour des notes importantes sur l'évitement du spoofing si vous utilisez des en-têtes pour les attributs.

Pour plus d'informations sur pourquoi il s'agit d'un module dédié, voir https://forum.nginx.org/read.php?2,238523,238523#msg-238523

Directives

Les directives suivantes sont ajoutées dans vos fichiers de configuration Nginx. Les contextes mentionnés ci-dessous montrent où elles peuvent être ajoutées.

shib_request \<uri>|off | Contexte : http, server, location
Par défaut : off

Active le module de demande d'authentification Shibboleth et définit l'URI qui sera demandée pour l'autorisation. L'URI configurée doit faire référence à un bloc de localisation Nginx qui pointe vers votre autorisateur FastCGI Shibboleth.

Le statut HTTP et les en-têtes de la réponse résultant de la sous-requête à l'URI configurée seront renvoyés à l'utilisateur, conformément à la spécification de l'autorisateur FastCGI. La seule (potentiellement significative) mise en garde est qu'en raison de la façon dont Nginx fonctionne actuellement en ce qui concerne les sous-requêtes (ce qu'un Autorisateur nécessite effectivement), le corps de la requête ne sera pas transmis à l'autorisateur, et de même, le corps de la réponse de l'autorisateur ne sera pas renvoyé au client.

Les URIs configurées ne sont pas limitées à utiliser un backend FastCGI pour générer une réponse, cependant. Cela peut être utile lors des tests ou autrement, car vous pouvez utiliser les directives intégrées return et rewrite de Nginx pour produire une réponse appropriée. De plus, ce module peut être utilisé avec n'importe quel autorisateur FastCGI, bien que son fonctionnement puisse être affecté par la mise en garde ci-dessus.

[!WARNING] La directive shib_request ne nécessite plus le drapeau shib_authorizer. Cela doit être supprimé pour que Nginx puisse démarrer. Aucun autre changement n'est requis.

shib_request_set \<variable> \<value>
Contexte : http, server, location
Par défaut : none

Définit la variable à la value spécifiée après que la demande d'authentification soit terminée. La value peut contenir des variables de la réponse de la demande d'authentification. Par exemple, $upstream_http_*, $upstream_status, et toutes autres variables mentionnées dans la documentation de nginx_http_upstream_module.

Cette directive peut être utilisée pour introduire des attributs Shibboleth dans l'environnement de l'application backend, comme $_SERVER pour une application PHP FastCGI et est la méthode recommandée pour le faire. Consultez la documentation de Configuration pour un exemple.

shib_request_use_headers on|off | Contexte : http, server, location
Par défaut : off

[!NOTE] Ajouté dans v2.0.0.

Copie les attributs de la réponse de l'autorisateur Shibboleth dans la demande principale en tant qu'en-têtes, les rendant disponibles pour les serveurs et applications en amont. Utilisez cette option uniquement si votre application en amont ne prend pas en charge les paramètres de serveur via shib_request_set.

Avec ce paramètre activé, les en-têtes de réponse de l'autorisateur commençant par Variable-\* sont extraits, en supprimant la sous-chaîne Variable- du nom de l'en-tête, et copiés dans la demande principale avant qu'elle ne soit envoyée au backend. Par exemple, un en-tête de réponse d'autorisateur tel que Variable-Commonname: John Smith donnerait lieu à Commonname: John Smith étant ajouté à la demande principale, et donc envoyé au backend.

Attention au spoofing - vous devez vous assurer que votre application backend est protégée contre l'injection d'en-têtes. Consultez l'exemple de Configuration sur la façon d'y parvenir.

Configuration

Pour des détails complets sur la configuration de l'environnement Nginx/Shibboleth, consultez la documentation à https://github.com/nginx-shib/nginx-http-shibboleth/blob/master/CONFIG.rst.

Un exemple de bloc server se compose de ce qui suit :

#FastCGI authorizer for Auth Request module
location = /shibauthorizer {
    internal;
    include fastcgi_params;
    fastcgi_pass unix:/opt/shibboleth/shibauthorizer.sock;
}

#FastCGI responder
location /Shibboleth.sso {
    include fastcgi_params;
    fastcgi_pass unix:/opt/shibboleth/shibresponder.sock;
}

## En utilisant la directive ``shib_request_set``, nous pouvons introduire des attributs en tant
## que variables d'environnement pour l'application backend. Dans cet exemple, nous
## définissons ``fastcgi_param`` mais cela pourrait être n'importe quel type de backend Nginx qui
## prend en charge les paramètres (en utilisant l'option *_param appropriée)
#
## Les ``shib_fastcgi_params`` sont un ensemble optionnel de paramètres par défaut,
## disponibles dans le répertoire ``includes/`` de ce dépôt.
#
## Choisissez ce type de configuration à moins que votre application backend
## ne prenne pas en charge les paramètres de serveur ou exige spécifiquement des en-têtes.
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;
}

## Une localisation sécurisée. Toutes les demandes entrantes interrogent l'autorisateur FastCGI de Shibboleth.
## Attention aux problèmes de performance et au spoofing !
#
## Choisissez ce type de configuration pour les applications ``proxy_pass``
## ou les backends qui ne prennent pas en charge les paramètres de serveur.
location /secure {
    shib_request /shibauthorizer;
    shib_request_use_headers on;

    # Les attributs de Shibboleth sont introduits en tant qu'en-têtes par le FastCGI
    # autorisateur, nous devons donc prévenir le spoofing. Les
    # ``shib_clear_headers`` sont un ensemble de directives d'en-têtes par défaut,
    # disponibles dans le répertoire `includes/` de ce dépôt.
    include shib_clear_headers;

    # Ajoutez *tous* les attributs que votre application utilise, y compris toutes
    # les variations.
    more_clear_input_headers 'displayName' 'mail' 'persistent-id';

    # Cette application backend recevra des variables Shibboleth en tant qu'en-têtes de requête
    # (provenant de l'autorisateur FastCGI de Shibboleth)
    proxy_pass http://localhost:8080;
}

Notez que nous utilisons le headers-more-nginx-module pour effacer les en-têtes d'entrée potentiellement dangereux et éviter le potentiel de spoofing. L'exemple précédent avec des variables d'environnement n'est pas susceptible au spoofing d'en-têtes, tant que le backend lit les données uniquement à partir des paramètres d'environnement.

Un configuration par défaut est disponible pour effacer les en-têtes de base de l'autorisateur Shibboleth, mais vous devez vous assurer d'écrire vos propres directives de nettoyage pour tous les attributs que votre application utilise. Gardez à l'esprit que certaines applications essaieront de lire un attribut Shibboleth à partir de l'environnement puis reviendront aux en-têtes, donc examinez le code de votre application même si vous ne utilisez pas shib_request_use_headers.

Avec l'utilisation de shib_request_set, un params par défaut est disponible que vous pouvez utiliser en tant qu'include nginx pour vous assurer que toutes les variables Shibboleth principales sont transmises de l'autorisateur FastCGI à l'application. De nombreux attributs par défaut sont inclus, donc retirez ceux qui ne sont pas requis par votre application et ajoutez les attributs de Fédération ou d'IDP dont vous avez besoin. Ce fichier de paramètres par défaut peut être réutilisé pour des upstreams qui ne sont pas FastCGI en changeant simplement les directives fastcgi_param en uwsgi_param, scgi_param ou autre.

Gotchas

  • Les sous-requêtes, telles que la demande d'authentification Shibboleth, ne sont pas traitées via des filtres d'en-têtes. Cela signifie que des directives intégrées comme add_header ne fonctionneront pas si configurées dans un bloc /shibauthorizer. Si vous devez manipuler les en-têtes de sous-requête, utilisez more_set_headers du module headers-more.

Voir https://forum.nginx.org/read.php?29,257271,257272#msg-257272.

Comportement

Ce module suit la spécification de l'autorisateur FastCGI dans la mesure du possible, mais présente quelques déviations notables - pour de bonnes raisons. Le comportement est donc :

  • Une sous-requête d'autorisateur est composée de tous les aspects de la demande originale, à l'exception du corps de la requête car Nginx ne prend pas en charge la mise en mémoire tampon des corps de requête. Comme l'autorisateur FastCGI de Shibboleth ne considère pas le corps de la requête, cela ne pose pas de problème.

  • Si une sous-requête d'autorisateur renvoie un statut 200, l'accès est autorisé.

Si shib_request_use_headers est activé, et que les en-têtes de réponse commençant par Variable-\* sont extraits, en supprimant la sous-chaîne Variable- du nom de l'en-tête, et copiés dans la demande principale. D'autres en-têtes de réponse d'autorisateur non préfixés par Variable- et le corps de la réponse sont ignorés. La spécification FastCGI exige que les paires nom-valeur Variable-* soient incluses dans l'environnement FastCGI, mais nous les faisons passer en tant qu'en-têtes afin qu'elles puissent être utilisées avec n'importe quel backend (tel que proxy_pass) et ne pas nous restreindre uniquement aux applications FastCGI. En passant les données Variable-* en tant qu'en-têtes, nous suivons le comportement de ShibUseHeaders On dans mod_shib pour Apache, qui passe ces attributs utilisateur en tant qu'en-têtes.

Afin de passer des attributs en tant que variables d'environnement (l'équivalent de ShibUseEnvironment On dans mod_shib), les attributs doivent être extraits manuellement à l'aide de directives shib_request_set pour chaque attribut. Cela ne peut pas (actuellement) être fait en masse pour tous les attributs car chaque backend peut accepter des paramètres de manière différente (fastcgi_param, uwsgi_param, etc.). Les demandes de tirage sont les bienvenues pour automatiser ce comportement.

  • Si la sous-requête d'autorisateur renvoie tout autre statut (y compris des redirections ou des erreurs), le statut et les en-têtes de réponse de l'autorisateur sont renvoyés au client.

Cela signifie que sur 401 Unauthorized ou 403 Forbidden, l'accès sera refusé et les en-têtes (tels que WWW-Authenticate) de l'autorisateur seront transmis au client. Toutes les autres réponses d'autorisateur (telles que les redirections 3xx) sont renvoyées au client, y compris le statut et les en-têtes, permettant des redirections telles que celles vers des pages WAYF et le répondant Shibboleth (Shibboleth.sso) de fonctionner correctement.

La spécification de l'Autorisateur FastCGI exige que le corps de la réponse soit renvoyé au client, mais comme Nginx ne prend actuellement pas en charge la mise en mémoire tampon des réponses de sous-requête (NGX_HTTP_SUBREQUEST_IN_MEMORY), le corps de la réponse de l'autorisateur est effectivement ignoré. Une solution de contournement consiste à faire en sorte que Nginx serve une error_page de sa propre, comme ceci :

location /secure {
   shib_request /shibauthorizer;
   error_page 403 /shibboleth-forbidden.html;
   ...
}

Cela sert la page d'erreur donnée si l'autorisateur Shibboleth refuse l'accès à cette localisation. Sans error_page spécifiée, Nginx servira ses pages d'erreur génériques.

Notez que cela ne s'applique pas au répondant Shibboleth (généralement hébergé à Shibboleth.sso) car c'est un répondant FastCGI et Nginx est entièrement compatible avec cela car aucune sous-requête n'est utilisée.

Pour plus de détails, voir https://forum.nginx.org/read.php?2,238444,238453.

Bien que ce module soit spécifiquement conçu pour l'autorisateur FastCGI de Shibboleth, il fonctionnera probablement avec d'autres autorisateurs, en tenant compte des déviations de la spécification ci-dessus.

Tests

Les tests sont automatiquement exécutés sur GitHub Actions (en utilisant cette configuration) chaque fois que de nouveaux commits sont effectués dans le dépôt ou lorsque de nouvelles demandes de tirage sont ouvertes. Si quelque chose échoue, vous serez informé et les résultats seront rapportés sur GitHub.

Les tests sont écrits en utilisant une combinaison d'un simple script Bash pour la compilation de notre module avec différentes versions et configurations de Nginx et le Test::Nginx cadre de test Perl pour les tests d'intégration. Consultez le lien précédent pour des informations sur la façon d'étendre les tests, et référez-vous également à la documentation sous-jacente Test::Base sur des aspects comme la fonction blocks().

Les tests d'intégration sont exécutés automatiquement par CI mais peuvent également être exécutés manuellement (nécessite Perl & CPAN installés) :

cd nginx-http-shibboleth
cpanm --notest --local-lib=$HOME/perl5 Test::Nginx
## nginx doit être présent dans PATH et construit avec des symboles de débogage
PERL5LIB=$HOME/perl5/lib/perl5 prove

Aide & Support

Les demandes de support pour la configuration de Shibboleth et la configuration de Nginx ou du serveur web doivent être dirigées vers la liste de diffusion des utilisateurs de la communauté Shibboleth. Voir https://www.shibboleth.net/community/lists/ pour plus de détails.

Débogage

En raison de la nature complexe de la pile nginx/FastCGI/Shibboleth, déboguer des problèmes de configuration peut être difficile. Voici quelques points clés :

  1. Confirmez que nginx-http-shibboleth est correctement construit et installé dans nginx. Vous pouvez vérifier en exécutant nginx -V et en inspectant la sortie pour --add-module=[path]/nginx-http-shibboleth ou --add-dynamic-module=[path]/nginx-http-shibboleth.

  2. Si vous utilisez des modules dynamiques pour nginx, confirmez que vous avez utilisé la directive load_module pour charger ce module. Votre utilisation de shib_request et d'autres directives échouera si vous avez oublié de charger le module.

  3. Si vous utilisez une version de nginx différente de celles que nous testons avec ou si vous utilisez d'autres modules tiers, vous devez exécuter la suite de tests ci-dessus pour confirmer la compatibilité. Si des tests échouent, vérifiez votre configuration ou envisagez de mettre à jour votre version de nginx.

  4. Configuration de Shibboleth : vérifiez votre shibboleth2.xml et la configuration associée pour vous assurer que vos hôtes, chemins et attributs sont correctement libérés. Une configuration exemple peut vous aider à identifier les "gotchas" clés pour configurer shibboleth2.xml afin de fonctionner avec l'autorisateur FastCGI.

  5. Niveau application : dans votre code, commencez toujours par la sortie de débogage la plus simple possible (comme l'impression de l'environnement de la requête) et progressez à partir de là. Si vous souhaitez créer une application de base et autonome, jetez un œil à la configuration Bottle sur le wiki.

  6. Débogage des internes du module : si vous avez soigneusement vérifié tout ce qui précède, vous pouvez également déboguer le comportement de ce module lui-même. Vous devrez avoir compilé nginx avec le support de débogage (via ./auto/configure --with-debug ...) et lorsque vous exécutez nginx, il est plus facile si vous pouvez exécuter au premier plan avec les journaux de débogage activés. Ajoutez ce qui suit à votre nginx.conf :

    daemon off;
    error_log stderr debug;
    

    et exécutez nginx. Lors du démarrage de nginx, vous devriez voir des lignes contenant [debug] et au fur et à mesure que vous effectuez des requêtes, l'enregistrement dans la console continuera. Si cela ne se produit pas, vérifiez votre configuration nginx et votre processus de compilation.

    Lorsque vous effectuez finalement une requête qui touche (ou devrait invoquer) le bloc de localisation shib_request, vous verrez des lignes comme celles-ci dans la sortie :

    [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]"
    ...
    

    Si vous ne voyez pas ces types de lignes contenant shib request ..., ou si vous voyez certaines des lignes ci-dessus mais pas où les en-têtes/variables sont copiés, alors vérifiez à nouveau votre configuration nginx. Si vous n'avancez toujours pas, vous pouvez ajouter vos propres lignes de débogage dans le code source (suivez les exemples de ce module) pour finalement déterminer ce qui ne va pas et quand. Si vous faites cela, n'oubliez pas de recompiler nginx et/ou nginx-http-shibboleth chaque fois que vous apportez un changement.

Si vous pensez avoir trouvé un bug dans le code du module principal, veuillez créer un problème.

Vous pouvez également rechercher des problèmes existants car il est probable que quelqu'un d'autre ait déjà rencontré un problème similaire.

GitHub

Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-shibboleth.