Connectez le tunnel, ouvrez le même signet, et le site autorisé répond exactement comme il le faisait depuis le bureau. C’est l’hypothèse sur laquelle reposent silencieusement la plupart des plans d’accès à distance, et elle ne tient que tant que trois choses distinctes restent vraies en même temps. Aucune n’est une fonction du client VPN, et aucun enregistrement DNS ne peut en fournir une seule. Quand le signet échoue à la maison, le navigateur vous donne une erreur générique, que la cause soit une route manquante, une adresse de sortie non approuvée ou un proxy qui a remplacé la source qu’il rapporte. Traiter ces trois cas comme un seul problème, c’est ainsi qu’une petite correction de politique devient une semaine d’élargissement de listes d’autorisation.

La conception qui survit au contact d’un vrai réseau de bureau est plus étroite que l’hypothèse : une table de décision explicite à trois lignes, un point d’application qui ne peut pas être contourné et un test de refus qui prouve quelque chose. Démonter l’hypothèse vient d’abord, car tout ce qui suit dépend de savoir quelle couche présente mal la source.

Le mythe : se connecter n’est pas router

Un tunnel s’établit et le client installe des routes pour un certain ensemble de préfixes. C’est tout ce que fait la connexion. Qu’une requête HTTPS sans rapport passe par le tunnel, et de quelle adresse publique elle semble venir à son arrivée, sont des décisions prises plus tard par d’autres composants : la table de routage choisit le chemin, et la sortie choisit la source.

C’est pourquoi le bureau et la table de cuisine divergent avec le même ordinateur portable, le même profil de navigateur et le même signet. Au bureau, la requête sort par une adresse publique maintenue que l’exploitant du site a acceptée. Par un tunnel complet, elle peut sortir par la sortie VPN, qui est une autre adresse et, tant que personne ne l’ajoute, non approuvée. Par un tunnel divisé, elle peut ne jamais entrer dans le tunnel. Deux de ces trois chemins seulement ont jamais fait partie de l’accord avec le propriétaire du site, et le troisième n’est pas un défaut à corriger avec une entrée allow supplémentaire.

Trois états de requête, deux sorties approuvées

Écrivez la matrice avant de toucher à un pare-feu, car la table est la conception et la règle n’en est qu’une mise en œuvre. Les adresses ci-dessous sont des plages de documentation ; remplacez-les par vos propres valeurs maintenues et conservez-les là où le propriétaire du site peut les auditer.

Request pathSource the site seesIntended decision
Office, no tunnelOffice public exitAdmit to the application login
Remote, approved full tunnelApproved VPN egressAdmit to the same login
Remote, ordinary connectionNeither approved addressDeny at the network boundary

La ligne du milieu est là où la plupart de ces plans se cassent. Ce qui compte est l’adresse que l’appareil d’application observe, non l’adresse privée que l’ordinateur détient dans le tunnel ni son adresse LAN. Une valeur comme 10.8.0.6 ne signifie rien pour un site public, et 192.168.1.44 non plus. L’adresse du tunnel est un détail d’adressage du tunnel, pas un justificatif que le site peut vérifier.

Si votre VPN ne peut pas fournir une sortie stable et documentée, la matrice n’a pas de ligne du milieu valide et aucune quantité de listes d’autorisation n’en inventera une. Les options honnêtes sont alors un site privé atteint par des routes privées explicites ou une passerelle d’accès consciente de l’identité devant l’application. Les deux ont un contrat différent de celui d’une liste d’autorisation publique, et les deux sont plus faciles à expliquer à un auditeur qu’une liste qui a grossi jusqu’à fonctionner par hasard.

Lisez la source là où la décision est prise

Placez la restriction sur l’appareil qui termine la requête et confirmez qu’aucun chemin d’origine alternatif ne la contourne. Le module d’accès de Nginx évalue les directives allow et deny dans l’ordre, la première correspondance gagne, et les règles héritées d’un bloc englobant s’appliquent toujours à l’intérieur du location. Un allow étroit à côté d’un allow large au même endroit signifie généralement que le large décide. Lisez toute la configuration effective de ce location avant d’en modifier une seule ligne.

server {
    listen 443 ssl;
    server_name intranet.example.com;

    set_real_ip_from 10.20.0.10;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    location /app/ {
        allow 203.0.113.24;    # office public exit
        allow 198.51.100.77;   # approved VPN egress
        deny  all;
        proxy_pass http://app_backend;
    }
}

Derrière un répartiteur de charge ou un proxy inverse, cette règle voit le proxy sauf si vous lui dites le contraire. Restaurez l’adresse de l’appelant uniquement par le mécanisme de proxy de confiance pris en charge, avec une liste explicite d’adresses de proxy. Un en-tête de requête qui prétend une adresse approuvée n’est pas la preuve que l’appelant la possède, et sur une écoute publique un en-tête transmis non validé transforme la liste d’autorisation en décoration.

Vérifiez ensuite l’autre famille d’adresses. Un jeu de règles qui ne couvre qu’IPv4 est une décision incomplète pour un nom d’hôte qui répond aussi en AAAA, et un client disposant d’IPv6 fonctionnel atteindra la même application par un chemin que vous n’avez jamais examiné.

Tunnel divisé : la requête qui n’entre jamais

Un tunnel divisé ne transporte que les préfixes de sa liste. Les sous-réseaux internes du bureau figurent généralement sur cette liste ; un site web public non. Le navigateur résout le nom, compare l’adresse choisie à la table de routage et trouve malgré tout la passerelle locale par défaut devant lui.

La requête arrive donc depuis la connexion domestique de l’utilisateur, est refusée, et le rapport indique que le VPN est cassé alors que le tunnel fait précisément ce pour quoi il a été configuré. Deux corrections sont légitimes : acheminez cette destination par le tunnel et laissez la sortie approuvée la porter, ou acceptez que le site soit atteint directement et donnez aux utilisateurs distants un autre chemin approuvé, comme la passerelle d’accès. Élargir la liste d’autorisation publique du site jusqu’à ce qu’une adresse domestique y figure par hasard n’est ni l’un ni l’autre, et cela supprime la frontière que la conception devait imposer. Les deux premières gardent la matrice honnête ; la troisième en efface silencieusement une ligne.

Prouvez le refus, puis la reprise

Testez avec une requête qui exerce la décision réelle, depuis un client placé sur chaque ligne de la table. Un contrôle d’accessibilité vers une page quelconque qui affiche l’adresse ne prouve rien, car cette destination peut suivre un chemin différent de celui de l’application.

curl -sS -o /dev/null -w 'status=%{http_code}
' https://intranet.example.com/app/login
# repeat with the tunnel up, then with it down
tail -f /var/log/nginx/access.log | grep ' /app/'

Comparez l’enregistrement d’accès à la frontière avec ce que la table avait prédit. Puis coupez le tunnel et faites une nouvelle requête qui devrait être refusée ; une page déjà chargée, ou une connexion déjà ouverte, ne teste absolument rien. Si aucun refus n’apparaît, le point d’application n’est pas là où vous croyez.

Conservez l’authentification de l’application après l’admission réseau, car une sortie de bureau et une sortie VPN représentent chacune beaucoup de personnes et aucune n’identifie un individu. La consigne pour les utilisateurs reste courte : montez le tunnel approuvé, puis réessayez. C’est ce qui garde une seule URL pratique tandis que la règle de source reste une décision et non une devinette.

Articles similaires