Présentation

Certaines applications nécessitent une couche de sécurisation complémentaire externe à défaut de pouvoir assurer elles-même leur propre sécurité. La mise en place d'un proxy inverse permet de réduire le niveau d'exposition de ces applications en mandatant un intermédiaire pour traiter les requêtes entrantes et leurs réponses. Toutefois, cela pourrait être considéré comme insuffisant contre certaines attaques si aucun contrôle supplémentaire n'est assuré sur les requêtes entrantes puisque finalement, n'importe qui pourrait atteindre l'application et potentiellement accéder à ses failles de sécurité. Pour répondre à cette problématique, diverses stratégies de contrôle peuvent être implémentées au niveau du proxy inverse telles que le contrôle des plages horaires, des adresses IP ou des personnes autorisées. Ces stratégies présentent l'avantage de stopper certaines requêtes non souhaitables avant même qu'elles n'atteignent le serveur applicatif. Néanmoins, dans le cas où l'on souhaiterait ajouter une authentification des utilisateurs gérée directement par le proxy inverse, cela pose la question de la répétition de l'authentification car il n'est pas certain que tous les utilisateurs accepteront volontiers de taper 2 mots de passe successifs, un au niveau du proxy inverse et un autre au niveau de l'application elle-même. Par ailleurs, sur quelle base d'authentification pourrions-nous nous baser et l'authentification multifacteur serait-elle possible ?

Dans cet article, nous montrons comment configurer un reverse proxy Apache HTTPd en environnement de test pour protéger une application ancienne assurant l'authentification de ses propres utilisateurs. Cette population d'utilisateurs utilise également des applications Office 365 et est donc souvent déjà connectée à un annuaire Entra ID (ex: AzureAD). La solution testée s'appuiera donc sur le module Apache mod_auth_openidc installé sur le proxy inverse en tant que Service Provider connecté au Fournisseur d'Identité Entra ID via le protocole SSO OpenId Connect. L'avantage de cette solution, est qu'elle sera transparente pour les utilisateurs presque tout le temps puisqu'ils seront déjà authentifiés sur Entra ID. Si ce n'est pas le cas, alors le deuxième avantage est qu'ils devront s'authentifier et qu'un deuxième facteur d'authentification géré par Azure pourra leur être demandé, renforçant ainsi la sécurisation de l'application à protéger.

Installation du Proxy inverse

  1. Installation d'une VM Rocky Linux 9.2 dans une DMZ

  2. Configuration de l'adressage IP et du nom de la machine avec nmtui : 
    # nmtui
    # reboot
  3. Configurer SELinux pour permettre à Apache HTTPd de se comporter comme un proxy inverse en initiant et en relayant des connexions réseau :
    # setsebool -P httpd_can_network_connect 1
    # setsebool -P httpd_can_network_relay 1
  4. Vérification de la zone active Firewalld et autorisation des accès TCP80/TCP443 vers le proxy :
    # firewall-cmd --get-active-zones
    # firewall-cmd --zone=public --add-port=80/tcp --permanent
    # firewall-cmd --zone=public --add-port=443/tcp --permanent
    # firewall-cmd --reload
    # firewall-cmd --zone=public --list-ports 
  5. Installation d'Apache HTTPd et du module SSL :
    # dnf update
    # dnf install httpd mod_ssl
    # systemctl enable httpd
  6. Ajouter dans le DNS externe un CNAME correspondant au FQDN du virtualhost de l'application ex : 
    protected.my-domain.com
  7. Générer les certificats SSL/TLS pour le virtualhost, par exemple avec Let's Encrypt.
    Utiliser un certificat autosigné (par exemple pour tester) n'est pas l'idéal car Entra ID pourrait peut-être refuser de rediriger le client vers l'application une fois authentifié. Dans nos tests, cela semble s'être produit une seule fois avant de se mettre à fonctionner ...

  8. Créer le fichier /etc/httpd/conf.d/protected.my-domain.com.conf avec le contenu suivant :
    <VirtualHost *:80>
       ServerName protected.my-domain.com
       Redirect / https://protected.my-domain.com
    </VirtualHost>
    <VirtualHost *:443>
       ServerName protected.my-domain.com

    SSLEngine on SSLCertificateFile /etc/letsencrypt/live/my-domain.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/my-domain/privkey.pem

       <Location />
          ProxyPass "http://protected.internal.lan/"
          ProxyPassReverse "http://protected.internal.lan/"
       </Location>
    </VirtualHost>
  9. Tester la connexion publique à l'application via le proxy inverse

Configurer l'application dans Entra ID

Enregistrer une nouvelle application

  1. Se connecter au portail Azure

  2. Cliquer sur Entra ID (AzureAD a changé de nom et s'appelle Entra ID) :
    cap1

  3. Cliquer sur < Inscriptions d'applications > dans le volet de gauche puis sur < Nouvelle inscription > :
    cap2

  4. Donner un nom à l'application et renseigner l'URL de l'application (1), sélectionner un type de compte pris en charge (2) et définir un point de terminaison vers lequel Azure redirigera le client (3).

    Attention : ce point de terminaison ne doit pas renvoyer vers l'application sous peine d'une possible erreur "Bad Request" relative à la taille du Header. Il s'agit seulement d'une URL fictive que le module mod_auth_openidc devra identifier comme une redirection d'Entra ID. On peut donc choisir une URL arbitraire (ici /redirect) tant que celle-ci est spécifiée dans la configuration OIDCRedirectURI de mod_auth_openidc :

    cap3

Générer un secret client

  1. Dans la section Certificats & secrets de l'application, cliquer sur Nouveau secret client et saisir un nom et une durée de validité. Ce secret est partagé entre Entra ID et mod_auth_openidc dans son paramètre OIDCClientSecret. Il permet au Service Provider (mod_auth_openidc) de recevoir des token d'accès. Quand il expire, il faut regénérer un secret sur Entra ID et mettre à jour le paramètre OIDCClientSecret :
    cap4

  2. Noter la valeur du secret, car on ne pourra plus la voir plus tard.

Configurer les permissions API

Cette étape consiste à déterminer ce que peut faire le Service Provider (mod_auth_openidc) dans Entra ID au moyen d'API. Dans notre cas, nous autoriserons mod_auth_openidc à connecter les utilisateurs, à afficher leur profil de base et email.

Dans la section < API autorisées >, cliquer sur < Microsoft Graph >, puis dans < Autorisations déléguées > cocher email, openid et profile

cap5

Configurer mod_auth_openidc

Dans cette étape, nous installons et configurons le service provider mod_auth_openidc chargé de communiquer avec le fournisseur d'identité Entra ID et de dire à HTTPd si l'authentification est réussie ou non.

  1. Installer le module d'authentification OpenID Connect :
    # dnf install mod_auth_openidc
  2. Si l'on souhaite obtenir plus d'information de débogage, ajouter la ligne suivante en haut du fichier /etc/httpd/conf.d/protected.my-domain.com.conf :
    LogLevel auth_openidc:debug 
  3. Dans la rubrique < Vue d'ensemble > de l'application configurée sur le portail Azure, relever :
    - la valeur de "ID de l'annuaire (locataire)" correspondant au {TenantID}
    - la valeur de "ID d'application (client)" correspondant au {ClientID}

    Récupérer la valeur du secret précédemment noté correspondant au {NewClientSecret}

  4. Dans le VirtualHost, ajouter la configuration du module mod_auth_openidc en se basant sur les valeurs précédemment relevées. Cette configuration peut également être placée hors du VirtualHost ,au niveau global :
    OIDCProviderMetadataURL https://login.microsoftonline.com/{TenantID}/v2.0/.well-known/openid-configuration
    OIDCClientID {ClientID}
    OIDCClientSecret {NewClientSecret}
    OIDCRedirectURI https://protected.my-domain.com/redirect
    OIDCCryptoPassphrase une_passphrase_securisée_choisie
    OIDCScope "openid email profile"
    Note importante : la valeur de OIDCRedirectURI doit correspondre exactement à l'URL de redirection spécifiée lors de l'inscription de l'application

  5. Dans le bloc <Location /> correspondant à l'URL que l'on souhaire protéger, ajouter les directives suivantes avant les directives ProxyPass :
    AuthType openid-connect
    Require valid-user
    Require all denied
  6. Relancer HTTPd :
    # systemctl restart httpd
  7. Tester l'accès public à l'application avec un navigateur. Si on n'est pas déjà authentifié, on sera redirigé vers la procédure d'authentification sur Azure avant d'être autorisé à accéder à l'application.

    Note : dans un de nos tests, nous avons eu un message d'erreur retourné par HTTPd concernant la taille du Header. En effet, lors de la redirection du client de Entra ID vers l'application, un code très long est ajouté à l'URL et sans doute dans le paquet HTTP. Le problème a été résolu en ajoutant à la louche la directive suivante au VirtualHost :
    LimitRequestFieldSize 131072
Ajouter un commentaire

Joomla templates by a4joomla