Quelle adresse source NGINX consignera-t-il pour un client VPN ?
Décidez ce que NGINX voit à côté d'OpenVPN sur un même hôte : une adresse interne de tunnel, une adresse publique de sortie ou un pair transmis, selon le chemin emprunté.
Trois adresses client apparaissent dans une installation NGINX et OpenVPN sur le même hôte, une pour chaque chemin qu'une requête peut emprunter. Un navigateur qui joint l'adresse du tunnel, un navigateur qui joint l'adresse publique et un programme qui sort par la voie internet de la passerelle se présentent tous différemment sur la socket d'écoute. Décidez quel chemin vous observez avant d'interpréter la ligne de journal. La décision dépend de la destination utilisée par le client, de l'exception qu'il conserve pour le point de sortie externe du VPN et de l'existence d'une traduction du paquet en route.
Décidez par destination, pas selon l'identité de l'utilisateur
Partez de l'adresse à laquelle la requête a été envoyée, car c'est cette adresse qui choisit le chemin. Une requête vers l'adresse de tunnel de l'hôte arrive sur l'interface du tunnel avec l'adresse interne du client comme source. Une requête vers l'adresse publique de l'hôte arrive généralement sur l'interface tournée vers internet avec l'adresse publique du client, même lorsque le même ordinateur portable a un tunnel établi à cet instant. L'appartenance au pool VPN est donc une propriété du chemin du paquet, non une propriété qui suit l'utilisateur.
| Path the request took | Source the site normally records |
|---|---|
| Client reaches the site at its tunnel address, 10.24.0.1 | Client inner address, 10.24.0.20 |
| Client reaches another internet site through the gateway | Gateway public egress address, 192.0.2.44 |
| Client reaches the gateway's public address through the endpoint exception | Client's own public access address |
C'est cette troisième ligne qu'il faut vérifier en premier lorsqu'un utilisateur du VPN apparaît dans le journal avec une adresse sans rapport avec le tunnel. Elle explique aussi pourquoi deux utilisateurs dotés du même profil peuvent produire des entrées différentes : leurs propres réseaux d'accès diffèrent, et rien dans le tunnel ne le réécrit.
Pourquoi le point de sortie externe crée un second chemin public
Le client doit joindre l'adresse publique de la passerelle pour établir le tunnel, donc une route vers cette adresse doit exister hors du tunnel. Quand un client redirige tout le trafic vers l'intérieur, une implémentation sensée conserve une route d'hôte explicite vers l'adresse publique du serveur afin d'éviter un tunnel qui dépend de lui-même. Cette exception ne trie pas les services, si bien que toute requête vers la même adresse publique la suit, y compris une requête de navigateur vers un site hébergé sur la passerelle.
C'est le mécanisme derrière la plupart des rapports déroutants dans ce domaine, et il relève de l'implémentation du client, non du serveur. Deux clients dotés de profils identiques peuvent donc se comporter différemment. Supprimer l'exception pour »réparer« le journal fait tomber le tunnel avec elle, donc conservez-la et concevez autour.
Lisez la socket, la table et le format de journal ensemble
Trois observations tranchent le chemin que vous observez : où la socket écoute, quelle interface répond à la destination et ce que le format de journal enregistre réellement. Si l'écouteur n'est lié qu'à l'adresse du tunnel, une requête publique ne peut pas l'atteindre du tout, ce qui écarte immédiatement deux lignes. Si la recherche pour le client renvoie le périphérique de tunnel, la requête est arrivée avec une source interne et le journal devrait le montrer.
ss -lntp 'sport = :443'
ip route get 10.24.0.20
ip route get 192.0.2.44Lisez ensuite le format plutôt que la ligne. Un champ alimenté par un en-tête transféré enregistre une déclaration, non un pair de socket, et la déclaration ne compte que si le pair immédiat est un proxy de confiance. Écrire les deux valeurs dans le journal tranche les discussions ultérieures, car le pair immédiat et l'adresse substituée sont des faits différents et un seul des deux vient du réseau.
log_format tunneled '$remote_addr $realip_remote_addr $request $status';
grep -n 'log_format' /etc/nginx/nginx.confChoisissez le point d'entrée voulu et faites concorder le DNS
Si le site doit être accessible uniquement par le tunnel, donnez-lui un nom qui, pour les clients VPN, résout vers l'adresse du tunnel, et appliquez la politique sur la socket d'écoute. Une réponse DNS scindée renvoyant 10.24.0.1 pour le nom interne est une décision de routage déguisée en détail de résolution de noms. Si le site doit aussi être public, gardez deux noms ou deux ports et laissez le journal vous dire lequel a servi la requête.
Les règles d'autorisation suivent la même logique. Autoriser le pool du tunnel n'autorise pas une requête publique et ne remplira pas une adresse interne sur une connexion arrivée par internet. Mélanger les deux points d'entrée sous un seul nom transforme la source consignée en effet secondaire du routage du client plutôt qu'en choix de conception.
Vérifiez le chemin, puis la politique
Confirmez le chemin par une capture sur la passerelle et une requête que vous contrôlez. Une capture sur le périphérique de tunnel et une sur l'interface publique montrent laquelle a porté les octets, et l'ordre des paquets indique si une traduction a eu lieu entre les deux.
tcpdump -ni tun0 port 443 -c 5
tcpdump -ni eth0 port 443 -c 5Vérifiez ensuite l'accès dans les deux sens : l'entrée nommée prévue fonctionne pour le client prévu, et un chemin public non approuvé est refusé plutôt que simplement lent. Un site générique d'écho d'IP prouve quelque chose sur la sortie internet de la passerelle et rien sur ce site du même hôte. Quand une page et un WebSocket divergent, comparez leurs URL, leurs familles d'adresses et leurs réponses DNS avant de toucher à la configuration du serveur.