Nous vendons des proxys sur Geonode ; il s'agit donc ici de la présentation de notre propre produit. La recommandation qui ne nous coûte rien et qui aide la plupart des gens : si votre adresse source est stable, utilisez une liste blanche d’adresses IP plutôt qu’un nom d’utilisateur et un mot de passe. Cela supprime complètement les identifiants de vos commandes, de vos scripts, de vos variables d’environnement et de la sortie de votre terminal que vous avez copiée — et il n’y a rien à divulguer s’il n’y a rien à envoyer. La plupart des fournisseurs proposent cette option, y compris nous, mais elle est sous-utilisée car la configuration par nom d’utilisateur et mot de passe est la première solution présentée dans le guide d’installation. La suite de cet article aborde ces deux méthodes, et explique pourquoi l’authentification par « SOCKS5 » mérite davantage de prudence qu’on ne le pense généralement.
Les deux méthodes proposées par les fournisseurs
Nom d’utilisateur et mot de passe. Des identifiants vous sont attribués et vous devez les envoyer avec chaque requête. Cette méthode fonctionne depuis n’importe quelle adresse, ce qui en fait la seule option possible lorsque votre adresse change — qu’il s’agisse d’un ordinateur portable, d’une connexion mobile, d’un conteneur avec une adresse dynamique ou d’un ensemble distribué de workers.
Liste blanche d’adresses IP. Vous enregistrez les adresses d’où proviendront vos requêtes, et le proxy accepte tout ce qui provient de ces adresses sans identifiants. Cela ne fonctionne qu’à partir de ces adresses, ce qui est précisément ce qui rend cette méthode sûre.
La plupart des fournisseurs commerciaux prennent en charge les deux méthodes, et beaucoup autorisent leur utilisation simultanée. Le compromis est simple :
| Identifiants | Liste blanche d’adresses IP | |
|---|---|---|
| Fonctionne de n’importe où | Oui | Non |
| Risque de fuite d’informations | Oui | Non |
| Résiste à un changement d’adresse | Oui | Nécessite une mise à jour |
| Adapté aux conteneurs et à l’intégration continue (CI) | Oui | Uniquement avec une adresse de sortie stable |
| Convient à un serveur fixe | Oui | Mieux |
Pour un scraper fonctionnant sur un serveur doté d’une adresse statique, la liste blanche est clairement la meilleure solution. Pour tout ce qui est mobile ou éphémère, les identifiants constituent la seule option viable. Pour les exécuteurs d’automatisation continue (CI), cela dépend entièrement de la capacité de votre plateforme à fournir une adresse de sortie prévisible, ce qui n’est pas le cas de nombreuses plateformes.
Fonctionnement de l'authentification via un proxy HTTP
Le mécanisme repose sur un système de « challenge » et de « réponse », défini dans la RFC 9110.
Vous envoyez une requête. Si le proxy exige une authentification et que vous ne l'avez pas fournie, le proxy répond par un code d'état 407 Proxy Authentication Required
et inclut une requête d'authentification. La spécification est formelle à ce sujet : « Un proxy DOIT envoyer au moins un champ d'en-tête Proxy-Authenticate dans chaque réponse 407 (Proxy Authentication Required) qu'il génère. »
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="proxy.example.com"
Vous renvoyez la requête en incluant vos identifiants dans un en-tête « Proxy-Authorization
», que la RFC décrit comme permettant « au client de s’identifier (ou d’identifier son utilisateur) auprès d’un proxy qui exige une authentification ».
Proxy-Authorization: Basic dXNlcjpwYXNz
Deux propriétés distinguent ce processus de l’authentification Web ordinaire, et toutes deux découlent directement de la spécification.
Le défi est spécifique à chaque saut. « Contrairement à WWW-Authenticate, le champ d’en-tête Proxy-Authenticate ne s’applique qu’au client sortant suivant dans la chaîne de réponse. En effet, seul le client ayant choisi un proxy donné est susceptible de disposer des identifiants nécessaires à l’authentification. »
Les identifiants sont utilisés plutôt que transmis. « Lorsque plusieurs proxys sont utilisés dans une chaîne, le champ d’en-tête Proxy-Authorization est consommé par le premier proxy entrant qui s’attendait à recevoir des identifiants. » Un proxy peut les relayer si les proxys coopèrent de cette manière, mais par défaut, vos identifiants s’arrêtent au premier saut qui les a demandés.
La RFC souligne également une conséquence pour les chaînes au sein d’une même organisation : lorsque plusieurs proxys appartenant au même domaine administratif émettent le même défi, « cela donnera l’impression que l’en-tête Proxy-Authenticate est transféré, car chaque proxy enverra le même ensemble de défis. »
407 contre 401 : la distinction qui compte
Ce qui est le plus utile dans cet article pour quiconque effectue du débogage.
| Statut | Qui envoie la requête | En-tête de réponse | En-tête de requête |
|---|---|---|---|
| 401 Non autorisé | Le serveur cible | WWW-Authenticate | |
Authorization | |||
| 407 Authentification par proxy requise | Le proxy | Proxy-Authenticate | |
Proxy-Authorization | |||
Des codes différents, des en-têtes différents, des identifiants différents, une solution différente.
Un code 407 signifie que vous n’avez jamais atteint la cible. C’est le proxy qui vous a bloqué. Vos identifiants de connexion à la cible n’ont aucune importance, et les modifier ne servira à rien.
Un code 401 signifie que le proxy a fonctionné et que la cible demande des identifiants de connexion.
Ces deux codes peuvent apparaître ensemble dans une même configuration, car deux jeux d’identifiants indépendants peuvent être en jeu. Dans curl :
curl -x http://proxy.example.com:9000 \
--proxy-user proxyuser:proxypass \
-u apiuser:apipass \
https://api.example.com/private
--proxy-user
pour le proxy, -u
pour la cible. Les mélanger entraîne exactement la confusion que cette section vise à éviter.
Pour savoir quel maillon vous a refusé l’accès sans avoir à deviner :
curl -sS -o /dev/null -x "$PROXY" \
-w 'connect=%{http_connect} status=%{response_code}\n' \
https://example.com
connect=407
signifie que le proxy vous a rejeté et que vous n’avez jamais atteint la cible. connect=200 status=401
signifie que le proxy a fonctionné et que la cible demande des identifiants. Deux problèmes différents, deux solutions différentes, une commande pour les distinguer.
L'authentification « SOCKS5 » est différente et moins sûre
Il est important de le savoir, car cette différence constitue un véritable enjeu de sécurité et est rarement mentionnée.
Le protocole SOCKS5 n'utilise pas d'en-têtes HTTP. L'authentification s'effectue lors de l'établissement de la connexion, dans le cadre d'une sous-négociation définie par la RFC 1929. Le client envoie une petite structure binaire contenant un octet de version, la longueur du nom d’utilisateur, le nom d’utilisateur, la longueur du mot de passe et le mot de passe, et le serveur répond par un octet d’état où X'00' indique que l’opération a réussi. Si le serveur renvoie un statut d’échec, il « DOIT fermer la connexion ».
La note de sécurité figurant dans cette RFC est brève et doit être lue attentivement :
Étant donné que la requête transporte le mot de passe en clair, cette sous-négociation n’est pas recommandée dans les environnements où le « sniffing » est possible et réalisable.
En clair, pas en base64, pas haché. L’authentification HTTP Basic est au moins encodée en base64 — facilement réversible, mais pas littéralement lisible dans une capture de paquets. L’authentification par nom d’utilisateur/mot de passe via SOCKS5 transmet le mot de passe sur le réseau sous forme d’octets.
Conséquences pratiques :
Sur un réseau non fiable, privilégiez un proxy HTTP sur TLS, ou une liste blanche. Les identifiants sont davantage exposés avec l’SOCKS5e qu’avec l’authentification HTTP Basic, et cette différence est importante sur les réseaux partagés ou hostiles.
Renouvelez les identifiants SOCKS plus fréquemment que ceux utilisés pour HTTP, car ils sont plus facilement exposés.
Notez que cela ne concerne que l’authentification auprès du proxy. Votre trafic vers un site HTTPS reste protégé par TLS. Ce sont les identifiants eux-mêmes qui transitent sans protection.
Paramètres dans le nom d’utilisateur : une convention propre aux fournisseurs
Une pratique qui sème la confusion chez les débutants et qui ne relève d’aucune norme.
De nombreux fournisseurs intègrent des paramètres de configuration dans la chaîne du nom d’utilisateur :
username-country-de-session-abc123:password
. Il ne s’agit pas d’une fonctionnalité HTTP. La passerelle proxy analyse son propre champ « nom d’utilisateur » et traite les segments supplémentaires comme des instructions : un pays, un identifiant de session, un paramètre de rotation. La syntaxe varie considérablement d’un fournisseur à l’autre.
Il en découle deux choses.
Consultez la documentation de votre fournisseur plutôt que de deviner. Un paramètre mal formé ne génère généralement pas d’erreur. Il produit une requête fonctionnelle mais avec un comportement incorrect — une session qui ne persiste pas, ou une sortie dans un pays que vous n’avez pas demandé. Il s’agit d’un échec silencieux, et c’est le genre d’échec qui perdure le plus longtemps.
Certains fournisseurs utilisent plutôt des ports, en associant une plage de ports à des pays ou à des sessions plutôt que de les encoder dans le nom d’utilisateur. Aucune des deux approches n’est meilleure ; vous devez simplement savoir laquelle vous avez choisie.
Où les identifiants sont-ils exposés ?
Quatre endroits, tous courants, tous évitables.
Lignes de commande. Visibles dans la liste des processus par les autres utilisateurs de la machine, et conservées indéfiniment dans l'historique du shell. Le manuel de curl est très clair à ce sujet : les données sensibles « doivent être récupérées à partir d’un fichier ou d’un équivalent, et ne doivent jamais être utilisées en clair dans une ligne de commande ».
Variables d’environnement. La syntaxe standard de configuration est « http_proxy=http://user:pass@host:9000 », ce qui place le mot de passe dans l’environnement de chaque processus fils, dans le fichier « /proc » sous Linux, ainsi que dans tout dump d’environnement.
Sortie détaillée. curl -v inclut l’en-tête Proxy-Authorization, et les captures d’écran de terminaux peuvent se retrouver là où personne ne le souhaitait. Masquez les informations sensibles avant de partager.
Contrôle de version. Les identifiants codés en dur dans un script et validés restent dans l’historique du dépôt même après leur suppression.
Mesures d’atténuation, par ordre d’efficacité : utilisez une liste blanche d’adresses IP et n’enregistrez aucun identifiant ; placez les identifiants dans un fichier à accès restreint tel que ~/.netrc avec chmod 600 ; lisez-les à partir d’un gestionnaire de secrets au moment de l’exécution ; et, au minimum, évitez qu’ils n’apparaissent dans l’historique du shell avec read -rs.
Un détail d’encodage qui prête vraiment à confusion : si votre mot de passe contient @, : ou /, il doit être encodé en pourcentage avant d’être intégré à une URL de proxy, sinon l’analyseur le divisera au mauvais endroit et vous obtiendrez un code d’erreur 407 alors que vos identifiants sont corrects.
Configuration dans les outils courants
curl :
curl -x http://proxy.example.com:9000 --proxy-user user:pass https://example.com
wget — notez qu’il ne dispose pas d’option « --proxy
» ; le proxy est donc défini soit par l’environnement, soit via .wgetrc
:
wget --proxy-user=user --proxy-password=pass https://example.com
Mieux encore, dans ~/.wgetrc
avec chmod 600
:
http_proxy = http://proxy.example.com:9000/
proxy_user = user
proxy_password = pass
Python requests :
proxies = {"http": "http://user:pass@proxy.example.com:9000",
"https": "http://user:pass@proxy.example.com:9000"}
requests.get("https://example.com", proxies=proxies)
Playwright :
const context = await browser.newContext({
proxy: { server: 'http://proxy.example.com:9000', username: 'u', password: 'p' },
});
Notez que Playwright utilise des champs distincts pour les identifiants plutôt que de les inclure dans l’URL, ce qui évite complètement le problème d’encodage en pourcentage.
Variables d’environnement, prises en charge par de nombreux outils :
export http_proxy=http://user:pass@proxy.example.com:9000
export https_proxy=http://user:pass@proxy.example.com:9000
export no_proxy=localhost,127.0.0.1,.internal
Utilisez des minuscules. L’HTTP_PROXY
en majuscules présente un risque documenté dans les environnements CGI, où les en-têtes de requête deviennent des variables d’environnement en majuscules et où un client qui les prend en compte peut être manipulé par un en-tête « Proxy:
» fourni par un attaquant.
Dépannage
Erreur 407 avec des identifiants que vous estimez corrects. Vérifiez si le mot de passe contient des caractères spéciaux nécessitant un encodage en pourcentage. Vérifiez également si vous figurez sur une liste blanche d'adresses IP dont la validité a expiré. Vérifiez que l'outil envoie bien les identifiants — curl -v ... 2>&1 | grep -i proxy-auth vous le permet de le vérifier.
Erreur 407 apparaissant de manière intermittente. Il s’agit généralement d’une configuration distribuée dans laquelle certains nœuds de travail ont une adresse de sortie différente de celle figurant sur votre liste blanche, ou d’une passerelle à rotation où seuls certains points de terminaison nécessitent une authentification.
Cela fonctionne avec curl, mais échoue dans votre application. Il se peut que la bibliothèque ne prenne pas en charge l’authentification par proxy pour HTTPS, ou qu’elle n’applique tout simplement pas le proxy. Vérifiez si vos requêtes passent bien par celui-ci — un service qui renvoie votre adresse est le test le plus rapide.
Cela fonctionne pour HTTP, mais échoue pour HTTPS. Pour le HTTPS, le client envoie d’abord une requête « CONNECT », et certaines bibliothèques gèrent l’authentification via le proxy pour ce tunnel différemment, voire pas du tout.
L’authentification réussit, mais les requêtes échouent toujours. Dans ce cas, il ne s’agissait pas d’un problème d’authentification. Une erreur 403 après une requête « CONNECT » réussie provient de la cible, et non du proxy.
Gestion des identifiants au sein d'une équipe ou d'un parc
Dès qu'il y a plus d'une personne ou d'une machine impliquée, la gestion des identifiants n'est plus une simple question de commodité, mais devient un enjeu opérationnel.
Délivrez des identifiants distincts par personne et par service lorsque votre fournisseur le permet. Un compte unique partagé signifie que vous ne pouvez pas déterminer quelle tâche a provoqué un pic d’utilisation, que vous ne pouvez pas révoquer l’accès d’un collègue qui quitte l’entreprise sans perturber tout le monde, et que vous ne pouvez pas identifier l’origine d’une fuite. Il vaut la peine de se renseigner sur les sous-comptes, même s’ils coûtent un peu plus cher.
Ne placez pas les identifiants dans les images ni dans le code source. Un mot de passe intégré à une image de conteneur est présent dans chaque couche et chaque copie de celle-ci dans le registre, même après l’avoir supprimé lors d’une version ultérieure. Injectez-le au moment de l’exécution via le mécanisme de secrets de l’orchestrateur, ou récupérez-le auprès d’un gestionnaire de secrets au démarrage.
Privilégiez une liste blanche pour tout ce qui dispose d’une sortie stable. Un serveur fixe, une passerelle NAT avec une adresse statique ou un cluster Kubernetes derrière une adresse IP de sortie connue peuvent tous utiliser une liste blanche et ne contenir absolument aucun identifiant. C’est une solution nettement préférable à n’importe quelle gestion, aussi prudente soit-elle, des identifiants.
Prévoyez la rotation avant d’en avoir besoin. Lisez les identifiants à partir d’un seul emplacement — une variable d’environnement renseignée par un gestionnaire de secrets, ou un fichier de configuration aux permissions restreintes — afin que leur rotation se résume à une seule modification plutôt qu’à une recherche dans l’ensemble du code. Le moment où vous devez réellement procéder à la rotation est précisément celui où vous avez le moins envie de faire des recherches avec grep.
Méfiez-vous des échecs dus à des commits accidentels. Un identifiant validé puis supprimé reste dans l’historique du dépôt, et un dépôt public signifie qu’il est compromis, quelle que soit la rapidité avec laquelle le commit a été annulé. L’analyse du dépôt est une assurance peu coûteuse, et la rotation immédiate est le seul véritable remède.
Et mesurez l’utilisation par identifiant. Si votre fournisseur rend compte du trafic par sous-compte, un changement soudain est le premier signe qui vous indiquera qu’un identifiant a été partagé, divulgué ou est utilisé par une tâche que vous aviez oubliée. C’est également le moyen le moins coûteux de détecter le type d’erreur le plus onéreux : une boucle incontrôlée facturant de la bande passante que vous n’aviez pas l’intention d’acheter.
Questions fréquentes
Qu'est-ce qu'une erreur 407 ? L'erreur «
407 Proxy Authentication Required » signifie que le proxy demande des identifiants et n'en a pas reçu de valides. Elle provient du proxy et non du site web, et la norme RFC 9110 exige que le proxy inclue un en-tête « Proxy-Authenticate » précisant le schéma qu'il attend. Vos identifiants de destination n'ont aucune incidence sur cette erreur.
Quelle est la différence entre les codes d’erreur 401 et 407 ?
Le code 401 provient du serveur cible et utilise les en-têtes WWW-Authenticate et Authorization. Le code 407 provient du proxy et utilise les en-têtes Proxy-Authenticate et Proxy-Authorization. Un code 407 signifie que vous n’avez jamais atteint la cible.
La liste blanche d’adresses IP est-elle préférable à un identifiant et un mot de passe ?
Si votre adresse source est stable, oui. Il n’y a pas d’identifiants à divulguer, rien n’apparaît dans l’historique de votre shell et rien ne risque d’être enregistré par inadvertance dans un dépôt. Cette méthode échoue lorsque votre adresse change, c’est pourquoi les identifiants restent nécessaires pour les ordinateurs portables, les connexions mobiles et la plupart des environnements d’intégration continue (CI).
Les identifiants du proxy sont-ils chiffrés ?
L’authentification proxy HTTP Basic les encode en base64, ce qui est réversible mais pas lisible en clair. L’authentification par nom d’utilisateur/mot de passe SOCKS5 les envoie en texte clair — la RFC 1929 le précise explicitement et le déconseille « lorsque l’interception est possible et réalisable ». Le chiffrement ne l’est pas non plus ; c’est le transport qui vous protège.
Pourquoi mon mot de passe de proxy contenant un caractère spécial est-il refusé ?
Parce que @, : et / ont une signification dans une URL. http://user:p@ss@host:9000 est interprété d’une manière que vous n’aviez pas prévue. Encodez-les en pourcentage, ou utilisez un client qui traite le nom d’utilisateur et le mot de passe comme des champs distincts plutôt que de les intégrer dans l’URL.
Que signifie le texte supplémentaire dans mon nom d’utilisateur de proxy ?
Il s’agit d’une convention propre au fournisseur permettant d’intégrer des options d’encodage — un pays, un identifiant de session, un paramètre de rotation — dans le champ du nom d’utilisateur. Cela ne fait partie d’aucune norme, la syntaxe varie selon le fournisseur, et une erreur entraîne généralement une requête fonctionnelle mais avec un comportement incorrect, plutôt qu’une erreur.
Puis-je utiliser à la fois des identifiants et une liste blanche ?
Avec de nombreux fournisseurs, oui, et c’est une solution judicieuse : la liste blanche couvre vos serveurs fixes sans qu’aucun identifiant ne soit nécessaire, tandis que les identifiants couvrent les machines de développement et tout ce dont l’adresse change.
Ai-je besoin d’identifiants distincts pour le proxy et le site web ?
Si les deux nécessitent une authentification, oui — il s’agit de mécanismes totalement distincts avec des en-têtes séparés. Dans curl, cela correspond à --proxy-user pour le proxy et -u pour la cible ; les confondre génère un code 407 alors que vous vous attendiez à un 401, ou l’inverse.
Conclusion
L’authentification par proxy constitue une couche distincte de l’authentification sur un site web, et le protocole a été conçu pour que cela soit évident. Codes d’état différents, en-têtes différents, identifiants différents. Dès lors que l’on interprète le code 407 comme « le proxy m’a bloqué » et le code 401 comme « la cible demande des identifiants », toute une catégorie d’erreurs prêtant à confusion se résout d’elle-même.
Le mécanisme en lui-même est simple : une requête de vérification dans Proxy-Authenticate, une réponse dans Proxy-Authorization, traitée par le premier nœud qui a émis la requête. La subtilité à retenir concerne SOCKS5, où la spécification indique clairement que les identifiants transitent en clair — une raison de privilégier un proxy HTTP ou une liste blanche sur tout réseau que vous ne contrôlez pas.
Et voici une recommandation qui ne coûte rien à un fournisseur : si vos requêtes proviennent d’une adresse stable, utilisez une liste blanche d’adresses IP. Chaque fuite décrite ici — historique du shell, listes de processus, vidages d’environnement, code source validé, sortie de terminal copiée-collée — repose sur l’existence d’un identifiant susceptible d’être divulgué. Supprimez l’identifiant et vous éliminez cette catégorie de risques.
