Wie man ein gemeinsames ProxyScrape-Proxy-Gateway unter Linux mit Privoxy und HAProxy erstellt
Verwandeln Sie einen ProxyScrape SOCKS5-Endpunkt in eine einzige HTTP-Proxy-Adresse, die Ihr gesamtes Team nutzen kann, mit Round-Robin-Rotation über mehrere Upstreams, Gesundheitsprüfungen und Zugriffskontrolle im privaten Netzwerk.
Überblick
Eine Proxy-Einrichtung pro Maschine skaliert nicht. Wenn mehrere Personen, ein paar CI-Runner und einige Container denselben Proxy-Pool benötigen, werden die Anmeldeinformationen in jeden Launcher und jedes Skript kopiert, und niemand kann sagen, welcher Datenverkehr welchen Upstream verwendet hat.
Dieses Tutorial baut das Gegenteil auf: einen Linux-Host, der Ihre ProxyScrape-Anmeldeinformationen einmalig speichert und eine einzige HTTP-Proxy-Adresse für Ihr privates Netzwerk bereitstellt.
Client apps -> HAProxy (TCP :3128) -> Privoxy instances (127.0.0.1:8118-8120) -> ProxyScrape SOCKS5 -> Internet
Der Leitfaden verwendet ProxyScrape SOCKS5-Upstreams, weil das lokale Frontend einen Benutzernamen und ein Passwort an den Upstream weitergeben muss, und Privoxy Anmeldeinformationen für SOCKS5-Upstreams unterstützt, aber nicht für HTTP-Upstreams. Wenn Sie speziell durch einen authentifizierten HTTP-Upstream ketten müssen, verwenden Sie stattdessen ein Chaining-Tool, das die Authentifizierung des HTTP-Parents unterstützt.
| Ebene | Software | Funktion |
|---|---|---|
| Client-Edge | HAProxy (TCP-Modus) | Gibt Clients einen Host und Port, verteilt neue Verbindungen auf lokale Proxy-Instanzen, entfernt Instanzen, die nicht mehr antworten |
| Lokaler Proxy | Privoxy | Akzeptiert HTTP-Proxy-Anfragen und leitet jede an einen einzelnen ProxyScrape SOCKS5-Endpunkt weiter |
| Upstream | ProxyScrape SOCKS5 | Löst die Ziel-URL auf und ruft sie unter Verwendung einer Proxy-IP aus dem Pool ab |
Eine praktische Konsequenz dieses Designs: Die Rotation erfolgt pro neuer Verbindung, nicht pro Anfrage. Ein Client, der eine Keep-Alive-Verbindung wiederverwendet, bleibt bei derselben Upstream-Instanz, bis er sich erneut verbindet.
Voraussetzungen
- Ein Linux-Host (Debian/Ubuntu- oder RHEL/Fedora-Familie) mit einer stabilen Adresse in einem privaten Netzwerk, VPN oder Tailnet. Setzen Sie den Gateway-Port nicht dem öffentlichen Internet aus.
- ProxyScrape SOCKS5-Endpunktdetails aus Ihrem Dashboard: Host, Port, Benutzername und Passwort.
- sudo-Zugriff und die Berechtigung, einen Port (3128 in den folgenden Beispielen) im privaten Netzwerk zu öffnen.
- Grundlegende Vertrautheit mit systemd-Units und dem Bearbeiten von Konfigurationsdateien.
Schritte
Schritt 1: Überprüfen Sie den ProxyScrape SOCKS5-Endpunkt, bevor Sie etwas aufbauen
Legen Sie Ihre Anmeldeinformationen in Shell-Variablen ab, damit die späteren Tests konsistent bleiben:
export PS_HOST="socks5-host-from-your-dashboard"
export PS_PORT="1080"
export PS_USER="your-username"
export PS_PASS="your-password"
Stellen Sie eine Anfrage direkt über den Endpunkt:
curl --silent --show-error \
--proxy "socks5h://${PS_USER}:${PS_PASS}@${PS_HOST}:${PS_PORT}" \
https://api.ipify.org
printf '\n'
Das socks5h://-Schema veranlasst curl, DNS-Anfragen über den Proxy zu senden, was für ein Gateway wünschenswert ist. Führen Sie den Befehl zwei- oder dreimal aus und notieren Sie die zurückgegebenen Adressen. Wenn der erste Befehl fehlschlägt, korrigieren Sie die Anmeldeinformationen oder den Host und Port, bevor Sie fortfahren, da jede Ebene nach dieser davon abhängt.
Schritt 2: Installieren Sie Privoxy und HAProxy
Debian und Ubuntu:
sudo apt update
sudo apt install --yes privoxy haproxy
RHEL, Fedora und kompatible Systeme:
sudo dnf install --yes privoxy haproxy
Bestätigen Sie, dass die Binärdateien vorhanden sind, und notieren Sie ihre Pfade, da die systemd-Unit unten direkt auf die Privoxy-Binärdatei verweist:
command -v privoxy
command -v haproxy
Schritt 3: Erstellen Sie eine Privoxy-Instanz pro Upstream
Privoxy liest eine einzelne flache Konfigurationsdatei, was es einfach macht, mehrere unabhängige Instanzen auszuführen, eine pro Upstream-Endpunkt. Beginnen Sie mit einem Verzeichnis für sie:
sudo mkdir -p /etc/privoxy/instances
Erstellen Sie /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 .
Ersetzen Sie USERNAME, PASSWORD, HOST und PORT durch Ihre ProxyScrape SOCKS5-Werte.
toggle 0deaktiviert die Inhaltsfilterung von Privoxy. Ein Gateway sollte den Datenverkehr unverändert weiterleiten, nicht umschreiben oder blockieren.listen-address 127.0.0.1:8118hält die Instanz privat auf dem Host. HAProxy wird die einzige exponierte Oberfläche sein.forward-socks5tsendet Anfragen an den SOCKS5-Upstream und löst auch DNS remote auf, sodass Hostnamen nicht aus Ihrem eigenen Netzwerk aufgelöst werden.- Das führende
/entspricht jeder URL und das nachfolgende.ist Teil der SOCKS-Weiterleitungsregelform, die in der Privoxy-Dokumentation für Tor und ähnliche Setups verwendet wird.
Sichern Sie die Datei, da sie Anmeldeinformationen enthält:
sudo chown root:privoxy /etc/privoxy/instances/instance-1.conf
sudo chmod 640 /etc/privoxy/instances/instance-1.conf
Wenn das Distributionspaket bereits einen Privoxy-Dienst auf Port 8118 gestartet hat, stoppen Sie ihn zuerst, damit der Port frei ist:
sudo systemctl disable --now privoxy
Testen Sie die Instanz im Vordergrund:
sudo privoxy --no-daemon /etc/privoxy/instances/instance-1.conf
Senden Sie in einem zweiten Terminal eine Anfrage durch sie:
curl --silent --proxy http://127.0.0.1:8118 https://api.ipify.org
printf '\n'
Wenn das eine Adresse zurückgibt, ist der schwierigste Teil erledigt. Stoppen Sie den Vordergrundprozess mit Strg+C und wiederholen Sie die Konfigurationsdatei für jeden weiteren ProxyScrape-Endpunkt, den Sie verwenden möchten, und ändern Sie nur den Namen der Protokolldatei und den Listen-Port.
Schritt 4: Führen Sie die Instanzen als systemd-Template-Dienst aus
Erstellen Sie /etc/systemd/system/[email protected]:
[Unit]
Description=Privoxy Proxy-Gateway-Instanz %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
Wenn command -v privoxy einen anderen Pfad ausgegeben hat, passen Sie ExecStart entsprechend an. Aktivieren Sie dann die Instanzen:
sudo systemctl daemon-reload
sudo systemctl enable --now privoxy-gateway@1 privoxy-gateway@2 privoxy-gateway@3
systemctl list-units 'privoxy-gateway@*' --no-pager
Bestätigen Sie, dass jede Instanz auf ihrem eigenen Loopback-Port lauscht:
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
Jede Zeile sollte eine Adresse zurückgeben, und sie werden nicht unbedingt dieselbe Adresse sein, da jede Instanz mit ihrem eigenen Upstream kommuniziert.
Schritt 5: Setzen Sie HAProxy als TCP-Load-Balancer davor
Das Frontend muss HTTP nicht verstehen. Es muss lediglich TCP-Verbindungen weiterleiten, was den TCP-Modus von HAProxy für einen HTTP-Proxy vor SOCKS5-Upstreams gut geeignet macht.
Sichern Sie die mitgelieferte Konfiguration und ersetzen Sie /etc/haproxy/haproxy.cfg durch die folgende. Ändern Sie 10.8.0.1 in die private Adresse dieses Hosts.
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
Einige Anmerkungen zu den hier getroffenen Entscheidungen:
- Port
3128ist der rotierende Einstiegspunkt. Jede neue TCP-Verbindung wird an die nächste gesunde Privoxy-Instanz gesendet. - Port
3129ist an eine einzelne Instanz gebunden für Aufträge, bei denen jede Anfrage für die Dauer eines Laufs über denselben Upstream verlassen soll. - Das einfache
check-Schlüsselwort führt eine TCP-Verbindungsprüfung durch, sodass eine Instanz, die keine Verbindungen mehr annimmt, automatisch aus der Rotation genommen wird. - Die Statistikseite ist nur an Loopback gebunden. Erreichen Sie sie über einen SSH-Tunnel oder einen internen Jump-Host, anstatt Port 8404 für das Netzwerk zu öffnen.
Validieren und neu laden:
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl restart haproxy
systemctl --no-pager --lines=20 status haproxy
Schritt 6: Beschränken Sie den Zugriff auf Ihr privates Netzwerk
Das Binden von HAProxy an eine private, VPN- oder Tailnet-Adresse bedeutet, dass das Gateway nur aus dem Inneren dieses Netzwerks erreichbar ist. Wenn der Host auch eine öffentliche Schnittstelle hat, fügen Sie eine Firewall-Regel hinzu, damit nichts auf dieser Schnittstelle die Proxy-Ports erreichen kann.
Das folgende nftables-Beispiel ist optional und dient zur Veranschaulichung. Wenden Sie es aus einer zweiten Terminal-Sitzung an, damit ein Fehler Sie nicht aus der Maschine aussperren kann, und passen Sie den Quellbereich an Ihr eigenes Netzwerk an:
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
Dieser Stack authentifiziert keine Clients; die Zugriffskontrolle erfolgt über das Netzwerk, an das das Gateway gebunden ist. Wenn Sie Anmeldeinformationen pro Person benötigen, terminieren Sie den Benutzerzugriff auf einem VPN oder Tailnet vor dem Host.
Schritt 7: Überprüfen Sie die Rotation von Ende zu Ende
Senden Sie eine Reihe separater Anfragen an den rotierenden Port:
for i in $(seq 1 6); do
curl --silent --proxy http://10.8.0.1:3128 https://api.ipify.org
printf '\n'
done
Jeder curl-Aufruf öffnet eine neue Verbindung, sodass Sie eine Streuung von Adressen sehen sollten, anstatt einer einzelnen wiederholten. Öffnen Sie dann die Statistikseite (bei Bedarf über einen Tunnel) und bestätigen Sie, dass jedes Backend als UP markiert ist:
ssh -L 8404:127.0.0.1:8404 user@gateway-host
# Im Browser auf Ihrem Arbeitsplatz: http://127.0.0.1:8404/stats
Richten Sie schließlich einen echten Client auf das Gateway, zum Beispiel eine Shell-Sitzung, die den Proxy für Kommandozeilen-Tools verwendet:
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
Rotierendes versus Sticky-Verhalten
Wählen Sie den Frontend-Port, der zur Aufgabe passt. Beide Optionen sind oben bereits konfiguriert.
- Rotierend (
3128): Neue Verbindungen werden auf alle gesunden Instanzen verteilt. Gute Standardeinstellung für Browser, allgemeines Surfen und Aufträge, die häufig frische Verbindungen öffnen. - Sticky (
3129): Der gesamte Datenverkehr geht an eine Instanz. Gut für Workflows, die für die Dauer einer Sitzung eine konsistente Quelladresse präsentieren müssen. - Isolation pro Gruppe: Erstellen Sie ein zweites Backend mit einer Teilmenge der Instanzen und richten Sie einen neuen Frontend-Port darauf, damit ein Team niemals den gesamten Pool verbraucht.
Fehlerbehebung
| Symptom | Wahrscheinliche Ursache | Lösung |
|---|---|---|
| Privoxy gibt eine 403-Antwort zurück | Die Inhaltsfilterung ist aktiviert und eine Filterregel hat die Anfrage erfasst | Bestätigen Sie, dass toggle 0 in der Instanzkonfiguration vorhanden ist, und starten Sie die Instanz neu |
| Privoxy gibt einen 502- oder Upstream-Verbindungsfehler zurück | Falscher SOCKS5-Host, Port oder falsche Anmeldeinformationen | Führen Sie den direkten curl --proxy "socks5h://..."-Test aus Schritt 1 erneut durch |
Alle Backends werden auf der Statistikseite als DOWN angezeigt |
Privoxy-Instanzen laufen nicht oder lauschen nicht dort, wo HAProxy sie erwartet | Führen Sie systemctl list-units 'privoxy-gateway@*' und `ss -ltnp |
| Jede Anfrage geht von derselben Adresse aus | Der Client verwendet eine Keep-Alive-Verbindung wieder, oder nur eine Instanz ist aktiv | Erzwingen Sie neue Verbindungen pro Anfrage und bestätigen Sie, dass alle Backends UP melden |
| Hostnamen werden aus Ihrem eigenen Netzwerk aufgelöst | Die Instanz verwendet forward-socks5 anstelle von forward-socks5t |
Wechseln Sie zu forward-socks5t, damit DNS über den Proxy aufgelöst wird |
HAProxy startet nicht mit einem /dev/log-Fehler |
Kein Syslog-Socket auf dem Host | Entfernen Sie die Zeile log /dev/log local0 oder installieren und aktivieren Sie einen Syslog-Dienst |
| Große Downloads laufen mitten in der Übertragung in eine Zeitüberschreitung | Die Standard-HAProxy-Zeitüberschreitungen sind für die Arbeitslast zu niedrig | Erhöhen Sie timeout client und timeout server im Abschnitt defaults |
Zusammenfassung
Sie haben jetzt eine einzelne HTTP-Proxy-Adresse, die mehrere ProxyScrape SOCKS5-Endpunkte frontet, mit automatischer Gesundheitsprüfung auf der HAProxy-Seite und Rotation pro Verbindung auf Port 3128. Die Anmeldeinformationen befinden sich in einem Satz von root-eigenen Konfigurationsdateien, anstatt in jedes Tool auf jeder Maschine kopiert zu werden.
Natürliche nächste Schritte: Fügen Sie eine Instanz und eine server-Zeile hinzu, wann immer Sie mehr Upstream-Kapazität benötigen, halten Sie die Privoxy-Konfigurationsdateien aus der Versionskontrolle heraus und rotieren Sie Anmeldeinformationen, indem Sie die Instanzkonfigurationen bearbeiten und die Template-Units nacheinander neu starten, damit das Gateway nie vollständig offline geht.