Un seul point de terminaison VPN via Squid : une exception CONNECT étroite
Laissez une source approuvée atteindre une passerelle VPN sur le port 1194 via Squid, conservez les garde-fous globaux de ports et prouvez que rien d’autre ne s’est ouvert.
Squid répond à une requête CONNECT avec la première ligne http_access qui correspond, et cette ligne peut être un refus. Ce seul fait explique pourquoi une exception pour un point de terminaison VPN échoue généralement au premier essai, car la requête n’atteint jamais l’autorisation que quelqu’un a ajoutée en bas. Une correction étroite conserve les garde-fous de ports existants et leur apprend une source, une destination et un port revus. Tout le reste sur le proxy se comporte exactement comme avant.
Comment Squid décide d’une requête CONNECT
Une requête CONNECT nomme un hôte et un port, et Squid parcourt les lignes http_access dans l’ordre jusqu’à ce que l’une d’elles corresponde. Un refus correspondant met fin immédiatement à l’évaluation et le client reçoit un 403 du proxy. C’est pourquoi la position d’une règle compte plus que sa formulation. Déplacer la même ligne d’un cran vers le haut peut changer complètement le résultat.
Les garde-fous classiques refusent tout ce qui sort de Safe_ports et refusent CONNECT hors de SSL_ports. Ces noms sont des ACL définies dans votre propre configuration, leur contenu vous appartient donc et non au protocole. Une distribution peut autoriser une large plage de ports comme Safe_ports tout en restreignant CONNECT séparément. Lisez les valeurs réelles avant de supposer qu’un port est bloqué par conception.
Confirmez que c’est bien le proxy qui refuse la requête. Un 403 généré par Squid ne ressemble en rien à une alerte TLS du serveur VPN, et fusionner les deux en un seul problème coûte la première heure. Vérifiez la ligne du journal d’accès de la requête, car elle consigne à la fois l’action et la règle qui l’a produite.
Construisez une correspondance combinée plutôt que trois ACL isolées
Construisez l’exception à partir de trois faits : une plage de sources approuvée, une adresse de destination approuvée et le seul port sur lequel le point de terminaison écoute. Deux ACL isolées et une correspondance combinée produisent une politique très différente, car c’est la combinaison qui est évaluée. Nommez l’ACL combinée d’après ce qu’elle autorise, et non d’après la méthode qu’elle porte.
La forme ci-dessous utilise des plages de documentation qu’il faut remplacer par des valeurs revues. Squid ne réserve aucun de ces noms, ils sont donc à vous de choisir et à vous de garder cohérents. Cette recette est limitée à Squid 6 et 7, dont la configuration documentée prend en charge le groupe all-of. La référence actuelle marque ces directives comme indisponibles dans Squid 8, traitez donc ceci comme une recette liée à une version et non comme un chemin de migration, et vérifiez la directive dans la référence de votre propre version avant de l’appliquer.
acl pvpn_src src 192.0.2.128/25
acl pvpn_dst dst 198.51.100.77/32
acl pvpn_port port 1194
acl pvpn_ok all-of CONNECT pvpn_port pvpn_dst pvpn_srcLe groupe all-of ne correspond que si chaque membre correspond, ce qui signifie que source, destination et port sont vérifiés sur une seule ligne. Le groupe n’accorde rien par lui-même, et une requête qui ne correspond qu’à deux des trois faits ne peut pas le satisfaire. Cette propriété garde l’exception étroite lorsqu’une seconde passerelle est ajoutée plus tard. Soit la nouvelle destination est ajoutée délibérément, soit la requête retombe sur les garde-fous d’origine.
Pliez les garde-fous de ports sans les supprimer
À leurs positions actuelles, les deux lignes de garde-fou classiques ressemblent à ceci. Elles se situent généralement après l’authentification et avant les lignes de politique qui autorisent tout.
http_access deny !Safe_ports
http_access deny CONNECT !SSL_portsAjoutez la correspondance combinée niée à chacune, afin qu’une exception correspondante survive à un garde-fou qui la refuserait sinon. Seules les lignes de garde-fou changent, et seulement d’un terme supplémentaire chacune.
http_access deny CONNECT !SSL_ports !pvpn_ok
http_access deny !Safe_ports !pvpn_okLes termes d’une ligne d’accès sont combinés, la ligne ne refuse donc plus que les requêtes qui échouent à la fois au contrôle d’origine et à l’exception. Une requête vers le point de terminaison approuvé passe, et toute autre requête conserve l’ancien comportement de port. C’est plus étroit que d’ajouter le port à une liste SSL_ports globale, ce qui autoriserait ce port vers n’importe quelle destination. Si le port figure déjà dans cette liste, cette ACL ne resserre rien et l’autorisation plus ancienne et plus large s’applique toujours aux autres destinations, alors lisez la liste réelle avant d’affirmer que l’exception a ouvert le port. Elle est aussi réversible, car deux lignes reviennent à leur forme précédente. La référence de contrôle d’accès documente l’ordre et les garde-fous classiques dont dépend ce changement.
Où l’exception ne doit pas être placée
La tentation est de placer une autorisation au-dessus des garde-fous et d’en finir. Ce placement saute aussi les protections d’authentification et de destination locale qui se trouvent généralement près du haut d’une configuration fonctionnelle. Le résultat n’est pas une exception étroite, c’est un trou avec un commentaire au-dessus. Gardez toute nouvelle autorisation à la même étape revue que le reste de la politique client.
Vérifiez ce dont la requête a encore besoin après les garde-fous de ports. Un compte authentifié, une adresse client autorisée et une politique de destination s’appliquent toujours, et l’exception n’en change aucun. Si votre proxy laisse déjà le compte approuvé atteindre des destinations arbitraires, le garde-fou de port n’a jamais été le véritable contrôle.
Demandez-vous si le point de terminaison est TCP. Une exception CONNECT transporte des flux TCP, et un profil OpenVPN qui utilise UDP ne deviendra pas joignable par son intermédiaire. Ne passez le profil en TCP que si le serveur écoute ainsi et que l’exploitant accepte la différence de comportement.
Vérifiez la frontière avec l’analyseur et une vraie requête
Analysez la configuration avant de recharger, et gardez une seconde session ouverte pendant ce temps. Une erreur de syntaxe au rechargement peut laisser le proxy sur l’ancienne configuration ou refuser la nouvelle purement et simplement. L’analyseur signale la ligne rejetée, ce qui est plus que ce que l’erreur côté client vous dira.
Rechargez ensuite et envoyez une vraie requête CONNECT via le proxy depuis une source approuvée. L’exécution de l’analyseur vient d’abord, car un rechargement avec une faute de frappe ne vous apprend rien sur la politique.
squid -k parse
squid -k reconfigure
curl -v -p -x http://proxy.lab.internal:3128 https://vpn.lab.internal:1194/ --max-time 5Testez trois cas : une source et un compte approuvés, une source non approuvée, et une destination différente sur le même port. Le troisième cas est celui qui prouve que l’exception est étroite, car il exerce le port sans la correspondance de destination. Lisez le journal d’accès pour les trois au lieu de faire confiance au message du client. Un CONNECT réussi établit un flux TCP et rien de plus, la poignée de main VPN reste donc un test séparé.