VPN bloqué sur un réseau web uniquement ? Traitez les couches
Le navigateur fonctionne, le tunnel meurt. Lisez les phases de temps de curl, testez le proxy, vérifiez si le 443 est vraiment autorisé, puis capturez ce qui a quitté la machine.
Un réseau de campus ou d’hôtel où le navigateur fonctionne et où chaque tunnel meurt n’est pas un problème, c’en est quatre empilés. Le chemin peut n’autoriser que TCP 443, exiger un proxy authentifié, inspecter la poignée de main, ou simplement interdire l’accès distant par politique. Les traiter dans l’ordre évite d’acheter un nouveau client pour corriger une règle réseau. Le guide ci-dessous prend une dizaine de minutes et se termine par une réponse écrite sur la couche qui vous a refusé.
Prouvez quelle couche refuse la connexion
Ne commencez pas par le client VPN. Commencez par une requête HTTPS simple vers le même hôte et lisez les phases de temps, car la phase qui échoue indique quel équipement est responsable :
curl -sS -o /dev/null -w 'connect=%{time_connect} tls=%{time_appconnect} code=%{http_code}\n' \
--max-time 8 https://vpn.example.net/
Pas de réponse et pas de temps connect signifie que TCP ne s’est jamais terminé, donc un pare-feu, une exigence de proxy ou une mauvaise destination est en jeu. Un temps connect sans temps tls signifie que quelque chose au milieu a accepté la connexion puis bloqué la poignée de main, et c’est exactement l’aspect d’un proxy inspecteur vu du client.
Inspectez maintenant le certificat que vous recevez réellement. C’est le moyen le plus rapide de savoir si vous parlez au serveur ou à une boîte intermédiaire qui a re-signé la session :
openssl s_client -connect vpn.example.net:443 -servername vpn.example.net -brief </dev/null
Lisez la ligne de l’émetteur. Votre propre CA signifie que vous avez atteint le service ; un émetteur d’entreprise ou d’appareil signifie qu’un filtre a terminé la connexion et décide de la suite. Enregistrez les deux sorties avec un horodatage, car le même test une heure plus tard sur le réseau invité peut donner une autre réponse.
Un client conscient du proxy change le premier paquet, pas la politique
Si le réseau exige CONNECT via un proxy authentifié, il faut le dire au client VPN, sinon il tentera d’ouvrir une socket vers une adresse qu’il ne peut pas router. Testez le proxy séparément du client, pour qu’un échec ait une seule explication :
https_proxy=http://proxy.example.edu:3128 curl -v -o /dev/null https://vpn.example.net/
sudo openvpn --config /etc/openvpn/corp.conf --proto tcp-client \
--remote vpn.example.net 443 --verb 4
La première commande prouve que le proxy portera la destination. La seconde demande au client d’utiliser TCP sur 443, le seul transport que la plupart des chemins web uniquement laisseront passer. Si la première réussit et que la seconde échoue encore, le proxy n’est pas l’obstacle.
Certains clients lisent le proxy du système d’exploitation au lieu d’un remplacement, et certains ne lisent ni l’un ni l’autre. Vérifiez la documentation de l’application avant de supposer qu’un réglage global s’applique. Un client qui résout le point de terminaison via un résolveur que le proxy ne sert pas échouera aussi ici, et c’est pourquoi un changement de DNS peut sembler un correctif alors qu’il n’est qu’un détour.
Surveillez aussi le schéma de pilotage. Un réseau filtré peut répondre au nom d’hôte de détection d’un fournisseur avec quelque chose à lui, ce qui change le profil de proxy choisi par le client. Ne construisez pas un processus autour de cette bizarrerie. Elle varie selon le site, change sans préavis et n’est pas quelque chose que vous pouvez supporter pour quiconque.
Le port 443 est joignable, pas autorisé
Envelopper un tunnel dans TLS sur 443 résout la joignabilité et rien d’autre. Un filtre qui vérifie le port le laissera passer ; un filtre qui prend l’empreinte de la poignée de main non, et le hello client chiffré ne cache le nom du serveur que si les deux extrémités le prennent en charge. Lancez le test et découvrez derrière quel type de filtre vous êtes au lieu d’espérer.
Il y a aussi un coût de performance que les gens découvrent plus tard. Un transport fiable dans un transport fiable amplifie la perte, car la pile interne retransmet des segments que la pile externe a déjà retransmis. Sur un lien propre, personne ne le remarque. Sur un réseau sans fil de campus congestionné, le tunnel devient inutilisable exactement quand vous en avez besoin, et le graphique ressemble à une perte de paquets alors que rien n’est abandonné exprès.
UDP est généralement la première victime, et cela vaut la peine d’être confirmé plutôt que déduit. Si WireGuard ou OpenVPN par défaut ne termine jamais une poignée de main alors que TCP 443 fonctionne, le réseau abandonne UDP, et aucune régénération de clés n’y changera rien :
sudo wg show
dig +short vpn.example.net
dig +short vpn.example.net @1.1.1.1
Un horodatage de poignée de main vide à côté d’un pair qui fonctionnait hier est la réponse UDP. Les deux requêtes DNS répondent à une autre question : si le résolveur local et un résolveur public ne sont pas d’accord sur l’adresse du point de terminaison, vous êtes piloté et l’argument du transport est le mauvais.
Vérifiez ce qui a réellement quitté la machine
Les journaux du client décrivent ce que le client croit. Une capture décrit ce que le réseau a vu, et la différence entre les deux est l’endroit où la plupart de ces cas se résolvent :
sudo tcpdump -ni any -c 20 'tcp port 443 and host 203.0.113.10'
sudo ss -tunp | grep -E ':(443|1194|51820)\b'
Si vous voyez des paquets SYN et aucun SYN-ACK, le blocage est en amont et le client est innocent. Si vous voyez une poignée de main terminée vers une adresse qui n’est pas celle du serveur, vous parlez à un proxy ou à un intercepteur. Si vous ne voyez rien du tout, vérifiez que vous avez capturé sur la bonne interface avant de conclure quoi que ce soit.
La liste des sockets attrape un cas plus subtil : un second tunnel qui détient déjà la route par défaut. Deux clients qui se disputent la table de routage produisent des pannes intermittentes qui ressemblent exactement à un réseau bloqué, et la capture montrera du trafic sortant par une interface que vous n’attendiez pas.
Le retour arrière, et la note qui vaut la peine d’être gardée
Annulez les changements dans l’ordre inverse de celui où vous les avez faits. Supprimez les variables de proxy, arrêtez le client que vous avez lancé à la main et retirez tout remplacement de route ou de résolveur que vous avez ajouté :
unset https_proxy http_proxy
sudo systemctl stop openvpn-client@corp
sudo ip route show default
Laisser tourner un client lancé à la main est la façon dont un portable finit avec un réseau cassé à la prochaine visite au bureau. Les variables de proxy laissées dans un profil de shell cassent des outils sans rapport des semaines plus tard, et la personne qui les débogue ne fera pas le lien entre les deux événements.
Écrivez ensuite quatre lignes : le réseau, l’horodatage, la phase qui a échoué et l’émetteur que vous avez vu. Un chemin qui fonctionne sur un campus et échoue sur le suivant est normal, et la personne suivante doit savoir si la différence venait du proxy, du résolveur ou du filtre. Si la réponse est que le réseau interdit l’accès distant, arrêtez-vous là et demandez à l’administrateur la route prise en charge plutôt que de porter un contournement dans une politique que vous n’avez pas lue.