Comment construire une passerelle proxy ProxyScrape partagée sur Linux avec Privoxy et HAProxy
Transformez un point de terminaison SOCKS5 ProxyScrape en une seule adresse proxy HTTP que toute votre équipe peut utiliser, avec rotation en round-robin sur plusieurs amonts, contrôles de santé et contrôle d'accès au réseau privé.
Aperçu
Une configuration proxy par machine ne passe pas à l'échelle. Lorsque plusieurs personnes, quelques runners CI et quelques conteneurs ont tous besoin du même pool de proxys, les identifiants finissent par être copiés dans chaque lanceur et script, et personne ne peut dire quel trafic a utilisé quel amont.
Ce tutoriel construit l'inverse : un seul hôte Linux qui conserve vos identifiants ProxyScrape une fois et expose une seule adresse proxy HTTP à votre réseau privé.
Client apps -> HAProxy (TCP :3128) -> Privoxy instances (127.0.0.1:8118-8120) -> ProxyScrape SOCKS5 -> Internet
Le guide utilise des amonts SOCKS5 ProxyScrape car le frontal local doit transmettre un nom d'utilisateur et un mot de passe en amont, et Privoxy prend en charge les identifiants pour les amonts SOCKS5 mais pas pour les amonts HTTP. Si vous avez spécifiquement besoin de chaîner via un amont HTTP authentifié, utilisez plutôt un outil de chaînage qui prend en charge l'authentification parente HTTP.
| Couche | Logiciel | Ce qu'il fait |
|---|---|---|
| Bord client | HAProxy (mode TCP) | Donne aux clients un seul hôte et port, répartit les nouvelles connexions sur les instances proxy locales, supprime les instances qui cessent de répondre |
| Proxy local | Privoxy | Accepte les requêtes proxy HTTP et transmet chacune à un seul point de terminaison SOCKS5 ProxyScrape |
| Amont | SOCKS5 ProxyScrape | Résout et récupère l'URL cible en utilisant une IP proxy du pool |
Une conséquence pratique de cette conception : la rotation se fait par nouvelle connexion, pas par requête. Un client qui réutilise une connexion keep-alive reste sur la même instance amont jusqu'à ce qu'il se reconnecte.
Prérequis
- Un hôte Linux (Debian/Ubuntu ou famille RHEL/Fedora) avec une adresse stable sur un réseau privé, un VPN ou un tailnet. N'exposez pas le port de la passerelle à l'internet public.
- Les détails du point de terminaison SOCKS5 ProxyScrape depuis votre tableau de bord : hôte, port, nom d'utilisateur et mot de passe.
- Accès sudo, et permission d'ouvrir un port (3128 dans les exemples ci-dessous) sur le réseau privé.
- Connaissance de base des unités systemd et de l'édition des fichiers de configuration.
Étapes
Étape 1 : Vérifier le point de terminaison SOCKS5 ProxyScrape avant de construire quoi que ce soit
Placez vos identifiants dans des variables shell pour que les tests ultérieurs restent cohérents :
export PS_HOST="socks5-host-from-your-dashboard"
export PS_PORT="1080"
export PS_USER="your-username"
export PS_PASS="your-password"
Effectuez une requête directement via le point de terminaison :
curl --silent --show-error \
--proxy "socks5h://${PS_USER}:${PS_PASS}@${PS_HOST}:${PS_PORT}" \
https://api.ipify.org
printf '\n'
Le schéma socks5h:// fait que curl envoie les résolutions DNS via le proxy, ce qui est ce que vous voulez pour une passerelle. Exécutez la commande deux ou trois fois et notez les adresses qui reviennent. Si la première commande échoue, corrigez les identifiants ou l'hôte et le port avant de continuer, car chaque couche après celle-ci en dépend.
Étape 2 : Installer Privoxy et HAProxy
Debian et Ubuntu :
sudo apt update
sudo apt install --yes privoxy haproxy
RHEL, Fedora et systèmes compatibles :
sudo dnf install --yes privoxy haproxy
Confirmez que les binaires sont présents et notez leurs chemins, car l'unité systemd ci-dessous référence directement le binaire Privoxy :
command -v privoxy
command -v haproxy
Étape 3 : Créer une instance Privoxy par amont
Privoxy lit un seul fichier de configuration plat, ce qui facilite l'exécution de plusieurs instances indépendantes, une par point de terminaison amont. Commencez par un répertoire pour elles :
sudo mkdir -p /etc/privoxy/instances
Créez /etc/privoxy/instances/instance-1.conf :
confdir /etc/privoxy
logdir /var/log/privoxy
logfile instance-1.log
toggle 0
listen-address 127.0.0.1:8118
forward-socks5t / USERNAME:PASSWORD@HOST:PORT .
Remplacez USERNAME, PASSWORD, HOST et PORT par vos valeurs SOCKS5 ProxyScrape.
toggle 0désactive le filtrage de contenu de Privoxy. Une passerelle doit transmettre le trafic tel quel, sans le réécrire ni le bloquer.listen-address 127.0.0.1:8118garde l'instance privée à l'hôte. HAProxy sera la seule surface exposée.forward-socks5tenvoie les requêtes à l'amont SOCKS5 et résout également le DNS à distance, de sorte que les noms d'hôtes ne sont pas résolus depuis votre propre réseau.- Le
/initial correspond à toutes les URL et le.final fait partie de la forme de règle de transfert SOCKS utilisée dans la documentation Privoxy pour Tor et les configurations similaires.
Verrouillez le fichier, car il contient des identifiants :
sudo chown root:privoxy /etc/privoxy/instances/instance-1.conf
sudo chmod 640 /etc/privoxy/instances/instance-1.conf
Si le paquet de la distribution a déjà démarré un service Privoxy sur le port 8118, arrêtez-le d'abord pour libérer le port :
sudo systemctl disable --now privoxy
Testez l'instance au premier plan :
sudo privoxy --no-daemon /etc/privoxy/instances/instance-1.conf
Dans un second terminal, envoyez une requête à travers elle :
curl --silent --proxy http://127.0.0.1:8118 https://api.ipify.org
printf '\n'
Si cela renvoie une adresse, la partie la plus difficile est faite. Arrêtez le processus au premier plan avec Ctrl+C et répétez le fichier de configuration pour chaque point de terminaison ProxyScrape supplémentaire que vous souhaitez utiliser, en changeant uniquement le nom du fichier journal et le port d'écoute.
Étape 4 : Exécuter les instances en tant que service modèle systemd
Créez /etc/systemd/system/[email protected] :
[Unit]
Description=Privoxy proxy gateway instance %i
Documentation=man:privoxy(8)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=privoxy
Group=privoxy
ExecStart=/usr/sbin/privoxy --no-daemon /etc/privoxy/instances/instance-%i.conf
Restart=on-failure
RestartSec=3
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Si command -v privoxy a affiché un chemin différent, ajustez ExecStart en conséquence. Activez ensuite les instances :
sudo systemctl daemon-reload
sudo systemctl enable --now privoxy-gateway@1 privoxy-gateway@2 privoxy-gateway@3
systemctl list-units 'privoxy-gateway@*' --no-pager
Confirmez que chaque instance écoute sur son propre port de bouclage :
for port in 8118 8119 8120; do
printf '%s -> ' "$port"
curl --silent --proxy "http://127.0.0.1:${port}" https://api.ipify.org
printf '\n'
done
Chaque ligne doit renvoyer une adresse, et elles ne seront pas nécessairement identiques, car chaque instance communique avec son propre amont.
Étape 5 : Mettre HAProxy en frontal comme équilibreur de charge TCP
Le frontal n'a pas besoin de comprendre HTTP. Il doit seulement relayer les connexions TCP, ce qui fait du mode TCP de HAProxy un bon choix pour un proxy HTTP devant des amonts SOCKS5.
Sauvegardez la configuration fournie et remplacez /etc/haproxy/haproxy.cfg par ce qui suit. Remplacez 10.8.0.1 par l'adresse privée de cet hôte.
global
log /dev/log local0
maxconn 4000
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
defaults
mode tcp
log global
option tcplog
retries 2
timeout connect 10s
timeout client 5m
timeout server 5m
frontend proxy_gateway
bind 10.8.0.1:3128
default_backend privoxy_instances
frontend proxy_gateway_sticky
bind 10.8.0.1:3129
default_backend privoxy_instance_1
backend privoxy_instances
balance roundrobin
server privoxy1 127.0.0.1:8118 check
server privoxy2 127.0.0.1:8119 check
server privoxy3 127.0.0.1:8120 check
backend privoxy_instance_1
server privoxy1 127.0.0.1:8118 check
listen stats
bind 127.0.0.1:8404
mode http
stats enable
stats uri /stats
stats refresh 10s
Quelques notes sur les choix ici :
- Le port
3128est le point d'entrée rotatif. Chaque nouvelle connexion TCP est envoyée à l'instance Privoxy saine suivante. - Le port
3129est épinglé à une seule instance pour les tâches où vous voulez que chaque requête sorte via le même amont pendant toute la durée d'une exécution. - Le mot-clé simple
checkeffectue une vérification de connexion TCP, de sorte qu'une instance qui cesse d'accepter les connexions est automatiquement retirée de la rotation. - La page de statistiques est liée uniquement à la boucle locale. Accédez-y via un tunnel SSH ou un hôte de rebond interne plutôt que d'ouvrir le port 8404 au réseau.
Validez et rechargez :
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl restart haproxy
systemctl --no-pager --lines=20 status haproxy
Étape 6 : Restreindre l'accès à votre réseau privé
Lier HAProxy à une adresse privée, VPN ou tailnet signifie que la passerelle n'est accessible que depuis l'intérieur de ce réseau. Si l'hôte dispose également d'une interface publique, ajoutez une règle de pare-feu afin que rien sur cette interface ne puisse atteindre les ports proxy.
L'exemple nftables suivant est facultatif et présenté à titre d'illustration. Appliquez-le depuis une seconde session de terminal afin qu'une erreur ne puisse pas vous verrouiller hors de la machine, et adaptez la plage source à votre propre réseau :
sudo nft add table inet proxygw
sudo nft add chain inet proxygw input '{ type filter hook input priority 0; }'
sudo nft add rule inet proxygw input tcp dport { 3128, 3129 } ip saddr != 10.8.0.0/24 drop
Cette pile n'authentifie pas les clients ; le contrôle d'accès provient du réseau auquel la passerelle est liée. Si vous avez besoin d'identifiants par personne, terminez l'accès utilisateur sur un VPN ou un tailnet devant l'hôte.
Étape 7 : Vérifier la rotation de bout en bout
Envoyez une série de requêtes distinctes au port rotatif :
for i in $(seq 1 6); do
curl --silent --proxy http://10.8.0.1:3128 https://api.ipify.org
printf '\n'
done
Chaque invocation de curl ouvre une nouvelle connexion, vous devriez donc voir une répartition des adresses plutôt qu'une seule adresse répétée. Ouvrez ensuite la page de statistiques (via un tunnel si nécessaire) et confirmez que chaque backend est marqué UP :
ssh -L 8404:127.0.0.1:8404 user@gateway-host
# in the browser on your workstation: http://127.0.0.1:8404/stats
Enfin, pointez un vrai client vers la passerelle, par exemple une session shell qui utilise le proxy pour les outils en ligne de commande :
export http_proxy="http://10.8.0.1:3128"
export https_proxy="http://10.8.0.1:3128"
curl --silent https://api.ipify.org
printf '\n'
unset http_proxy https_proxy
Comportement rotatif versus collant
Choisissez le port frontal qui correspond à la tâche. Les deux options sont déjà configurées ci-dessus.
- Rotatif (
3128) : les nouvelles connexions sont réparties sur toutes les instances saines. Bon choix par défaut pour les navigateurs, la navigation générale et les tâches qui ouvrent fréquemment de nouvelles connexions. - Collant (
3129) : tout le trafic va vers une seule instance. Bon pour les flux de travail qui doivent présenter une adresse source cohérente pendant toute la durée d'une session. - Isolation par groupe : créez un second backend avec un sous-ensemble des instances et pointez un nouveau port frontal vers celui-ci, afin qu'une équipe ne consomme jamais tout le pool.
Dépannage
| Symptôme | Cause probable | Correctif |
|---|---|---|
| Privoxy renvoie une réponse 403 | Le filtrage de contenu est activé et une règle de filtre correspond à la requête | Confirmez que toggle 0 est présent dans la configuration de l'instance et redémarrez cette instance |
| Privoxy renvoie une 502 ou une erreur de connexion amont | Hôte, port ou identifiants SOCKS5 incorrects | Réexécutez le test direct curl --proxy "socks5h://..." de l'étape 1 |
Tous les backends apparaissent comme DOWN dans la page de statistiques |
Les instances Privoxy ne sont pas en cours d'exécution ou n'écoutent pas là où HAProxy s'attend | Exécutez systemctl list-units 'privoxy-gateway@*' et `ss -ltnp |
| Chaque requête sort avec la même adresse | Le client réutilise une connexion keep-alive, ou une seule instance est active | Forcez de nouvelles connexions par requête, et confirmez que tous les backends signalent UP |
| Les noms d'hôtes sont résolus depuis votre propre réseau | L'instance utilise forward-socks5 au lieu de forward-socks5t |
Passez à forward-socks5t pour que le DNS soit résolu via le proxy |
HAProxy ne démarre pas avec une erreur /dev/log |
Pas de socket syslog sur l'hôte | Supprimez la ligne log /dev/log local0, ou installez et activez un service syslog |
| Les téléchargements volumineux expirent en cours de transfert | Les délais d'attente HAProxy par défaut sont trop courts pour la charge de travail | Augmentez timeout client et timeout server dans la section defaults |
Résumé
Vous disposez maintenant d'une seule adresse proxy HTTP qui est en frontal de plusieurs points de terminaison SOCKS5 ProxyScrape, avec vérification automatique de l'état de santé du côté HAProxy et rotation par connexion sur le port 3128. Les identifiants résident dans un ensemble de fichiers de configuration appartenant à root au lieu d'être copiés dans chaque outil sur chaque machine.
Étapes suivantes naturelles : ajoutez une instance et une ligne server chaque fois que vous voulez plus de capacité amont, gardez les fichiers de configuration Privoxy hors du contrôle de version, et faites tourner les identifiants en modifiant les configurations d'instance et en redémarrant les unités modèle une par une afin que la passerelle ne soit jamais complètement hors ligne.