Skip to content
Advanced / 4 min read

چگونه یک دروازه پروکسی اشتراکی ProxyScrape روی لینوکس با Privoxy و HAProxy بسازیم

یک نقطه پایانی SOCKS5 ProxyScrape را به یک آدرس پروکسی HTTP تبدیل کنید که کل تیم شما بتواند از آن استفاده کند، با چرخش چرخشی در چندین بالادست، بررسی سلامت، و کنترل دسترسی شبکه خصوصی.

لینوکس SOCKS5 HTTP(S) سایر

مرور کلی

تنظیمات پروکسی به ازای هر ماشین مقیاس‌پذیر نیست. وقتی چندین نفر، چند اجراکننده CI، و چند کانتینر همگی به همان استخر پروکسی نیاز دارند، اعتبارنامه‌ها در هر لانچر و اسکریپت کپی می‌شوند، و هیچ‌کس نمی‌تواند بگوید کدام ترافیک از کدام بالادست استفاده کرده است.

این آموزش نقطه مقابل را می‌سازد: یک میزبان لینوکس که اعتبارنامه‌های ProxyScrape شما را یک بار نگه می‌دارد و یک آدرس پروکسی HTTP واحد را به شبکه خصوصی شما ارائه می‌دهد.

Client apps -> HAProxy (TCP :3128) -> Privoxy instances (127.0.0.1:8118-8120) -> ProxyScrape SOCKS5 -> Internet

این راهنما از بالادست‌های SOCKS5 ProxyScrape استفاده می‌کند زیرا front end محلی باید نام کاربری و رمز عبور را به بالادست ارسال کند، و Privoxy از اعتبارنامه برای بالادست‌های SOCKS5 پشتیبانی می‌کند اما برای بالادست‌های HTTP نه. اگر به طور خاص نیاز دارید از طریق یک بالادست HTTP احراز هویت شده زنجیره کنید، به جای آن از یک ابزار زنجیره‌سازی استفاده کنید که از احراز هویت والد HTTP پشتیبانی می‌کند.

لایه نرم‌افزار کارکرد
لبه کلاینت HAProxy (حالت TCP) به کلاینت‌ها یک میزبان و پورت می‌دهد، اتصالات جدید را بین نمونه‌های پروکسی محلی پخش می‌کند، نمونه‌هایی که پاسخ‌دهی را متوقف می‌کنند حذف می‌کند
پروکسی محلی Privoxy درخواست‌های پروکسی HTTP را می‌پذیرد و هر کدام را به یک نقطه پایانی SOCKS5 ProxyScrape هدایت می‌کند
بالادست ProxyScrape SOCKS5 URL هدف را با استفاده از یک IP پروکسی از استخر حل و واکشی می‌کند

یک پیامد عملی این طراحی: چرخش به ازای هر اتصال جدید رخ می‌دهد، نه به ازای هر درخواست. کلاینتی که یک اتصال keep-alive را دوباره استفاده می‌کند تا زمانی که دوباره متصل شود روی همان نمونه بالادست باقی می‌ماند.

پیش‌نیازها

  • یک میزبان لینوکس (خانواده Debian/Ubuntu یا RHEL/Fedora) با یک آدرس پایدار در یک شبکه خصوصی، VPN، یا tailnet. پورت دروازه را در معرض اینترنت عمومی قرار ندهید.
  • جزئیات نقطه پایانی SOCKS5 ProxyScrape از داشبورد خود: میزبان، پورت، نام کاربری، و رمز عبور.
  • دسترسی sudo، و مجوز باز کردن یک پورت (3128 در مثال‌های زیر) روی شبکه خصوصی.
  • آشنایی پایه با unitهای systemd و ویرایش فایل‌های پیکربندی.

مراحل

مرحله ۱: قبل از ساخت هر چیزی، نقطه پایانی SOCKS5 ProxyScrape را تأیید کنید

اعتبارنامه‌های خود را در متغیرهای shell قرار دهید تا تست‌های بعدی ثابت بمانند:

export PS_HOST="socks5-host-from-your-dashboard"
export PS_PORT="1080"
export PS_USER="your-username"
export PS_PASS="your-password"

یک درخواست مستقیماً از طریق نقطه پایانی انجام دهید:

curl --silent --show-error \
  --proxy "socks5h://${PS_USER}:${PS_PASS}@${PS_HOST}:${PS_PORT}" \
  https://api.ipify.org
printf '\n'

طرح socks5h:// باعث می‌شود curl جستجوهای DNS را از طریق پروکسی ارسال کند، که همان چیزی است که برای یک دروازه می‌خواهید. دستور را دو یا سه بار اجرا کنید و آدرس‌هایی که برمی‌گردند را یادداشت کنید. اگر دستور اول شکست خورد، قبل از ادامه اعتبارنامه‌ها یا میزبان و پورت را اصلاح کنید، زیرا هر لایه بعد از این یکی به آن وابسته است.

مرحله ۲: نصب Privoxy و HAProxy

Debian و Ubuntu:

sudo apt update
sudo apt install --yes privoxy haproxy

RHEL، Fedora، و سیستم‌های سازگار:

sudo dnf install --yes privoxy haproxy

تأیید کنید که باینری‌ها موجود هستند و مسیرهای آن‌ها را ثبت کنید، زیرا unit systemd زیر مستقیماً به باینری Privoxy ارجاع می‌دهد:

command -v privoxy
command -v haproxy

مرحله ۳: به ازای هر بالادست یک نمونه Privoxy ایجاد کنید

Privoxy یک فایل پیکربندی مسطح واحد می‌خواند، که اجرای چندین نمونه مستقل، یکی به ازای هر نقطه پایانی بالادست، را آسان می‌کند. با یک دایرکتوری برای آن‌ها شروع کنید:

sudo mkdir -p /etc/privoxy/instances

ایجاد /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 .

USERNAME، PASSWORD، HOST، و PORT را با مقادیر SOCKS5 ProxyScrape خود جایگزین کنید.

  • toggle 0 فیلتر محتوای Privoxy را غیرفعال می‌کند. یک دروازه باید ترافیک را دست‌نخورده هدایت کند، نه اینکه آن را بازنویسی یا مسدود کند.
  • listen-address 127.0.0.1:8118 نمونه را خصوصی برای میزبان نگه می‌دارد. HAProxy تنها سطح در معرض قرار گرفته خواهد بود.
  • forward-socks5t درخواست‌ها را به بالادست SOCKS5 ارسال می‌کند و همچنین DNS را از راه دور حل می‌کند، بنابراین نام‌های میزبان از شبکه خودتان حل نمی‌شوند.
  • / ابتدایی با هر URL مطابقت دارد و . انتهایی بخشی از فرم قاعده هدایت SOCKS است که در مستندات Privoxy برای Tor و تنظیمات مشابه استفاده می‌شود.

فایل را قفل کنید، زیرا حاوی اعتبارنامه است:

sudo chown root:privoxy /etc/privoxy/instances/instance-1.conf
sudo chmod 640 /etc/privoxy/instances/instance-1.conf

اگر بسته توزیع قبلاً یک سرویس Privoxy روی پورت 8118 راه‌اندازی کرده است، ابتدا آن را متوقف کنید تا پورت آزاد شود:

sudo systemctl disable --now privoxy

نمونه را در پیش‌زمینه تست کنید:

sudo privoxy --no-daemon /etc/privoxy/instances/instance-1.conf

در یک ترمینال دوم، یک درخواست از طریق آن ارسال کنید:

curl --silent --proxy http://127.0.0.1:8118 https://api.ipify.org
printf '\n'

اگر آن یک آدرس برگرداند، سخت‌ترین بخش انجام شده است. فرآیند پیش‌زمینه را با Ctrl+C متوقف کنید و فایل پیکربندی را برای هر نقطه پایانی ProxyScrape اضافی که می‌خواهید استفاده کنید تکرار کنید، فقط نام فایل لاگ و پورت شنود را تغییر دهید.

مرحله ۴: نمونه‌ها را به عنوان یک سرویس قالب systemd اجرا کنید

ایجاد /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

اگر command -v privoxy مسیر متفاوتی را چاپ کرد، ExecStart را برای مطابقت تنظیم کنید. سپس نمونه‌ها را فعال کنید:

sudo systemctl daemon-reload
sudo systemctl enable --now privoxy-gateway@1 privoxy-gateway@2 privoxy-gateway@3
systemctl list-units 'privoxy-gateway@*' --no-pager

تأیید کنید که هر نمونه روی پورت loopback خودش در حال شنود است:

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

هر خط باید یک آدرس برگرداند، و لزوماً آدرس یکسانی نخواهند بود، زیرا هر نمونه با بالادست خودش صحبت می‌کند.

مرحله ۵: HAProxy را به عنوان یک متعادل‌کننده بار TCP در جلو قرار دهید

front end نیازی به درک HTTP ندارد. فقط باید اتصالات TCP را رله کند، که حالت TCP HAProxy را برای یک پروکسی HTTP در مقابل بالادست‌های SOCKS5 مناسب می‌کند.

از پیکربندی بسته پشتیبان بگیرید و /etc/haproxy/haproxy.cfg را با موارد زیر جایگزین کنید. 10.8.0.1 را به آدرس خصوصی این میزبان تغییر دهید.

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

چند نکته درباره انتخاب‌های اینجا:

  • پورت 3128 نقطه ورود چرخشی است. هر اتصال TCP جدید به نمونه Privoxy سالم بعدی فرستاده می‌شود.
  • پورت 3129 برای کارهایی که می‌خواهید هر درخواست در طول یک اجرا از همان بالادست خارج شود، به یک نمونه واحد پین شده است.
  • کلمه کلیدی ساده check یک بررسی اتصال TCP انجام می‌دهد، بنابراین نمونه‌ای که پذیرش اتصالات را متوقف کند به طور خودکار از چرخش خارج می‌شود.
  • صفحه آمار فقط به loopback متصل است. از طریق یک تونل SSH یا یک میزبان پرش داخلی به آن دسترسی پیدا کنید، نه با باز کردن پورت 8404 به شبکه.

اعتبارسنجی و بارگذاری مجدد:

sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl restart haproxy
systemctl --no-pager --lines=20 status haproxy

مرحله ۶: دسترسی را به شبکه خصوصی خود محدود کنید

اتصال HAProxy به یک آدرس خصوصی، VPN، یا tailnet به این معنی است که دروازه فقط از داخل آن شبکه قابل دسترسی است. اگر میزبان یک رابط عمومی نیز دارد، یک قانون فایروال اضافه کنید تا هیچ چیزی روی آن رابط نتواند به پورت‌های پروکسی دسترسی پیدا کند.

مثال nftables زیر اختیاری است و برای نشان دادن ارائه شده است. آن را از یک جلسه ترمینال دوم اعمال کنید تا یک اشتباه نتواند شما را از دستگاه قفل کند، و محدوده مبدأ را با شبکه خودتان تطبیق دهید:

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

این پشته کلاینت‌ها را احراز هویت نمی‌کند؛ کنترل دسترسی از شبکه‌ای که دروازه به آن متصل است می‌آید. اگر به اعتبارنامه به ازای هر شخص نیاز دارید، دسترسی کاربر را روی یک VPN یا tailnet در جلوی میزبان پایان دهید.

مرحله ۷: چرخش را به صورت سرتاسری تأیید کنید

یک سری درخواست‌های جداگانه به پورت چرخشی ارسال کنید:

for i in $(seq 1 6); do
  curl --silent --proxy http://10.8.0.1:3128 https://api.ipify.org
  printf '\n'
done

هر فراخوانی curl یک اتصال جدید باز می‌کند، بنابراین باید گسترده‌ای از آدرس‌ها را ببینید نه یک آدرس تکرار شده. سپس صفحه آمار را باز کنید (در صورت نیاز از طریق یک تونل) و تأیید کنید که هر backend با 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

در نهایت، یک کلاینت واقعی را به دروازه اشاره دهید، برای مثال یک جلسه shell که از پروکسی برای ابزارهای خط فرمان استفاده می‌کند:

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

رفتار چرخشی در مقابل چسبنده

پورت front-end را انتخاب کنید که با کار مطابقت دارد. هر دو گزینه قبلاً در بالا پیکربندی شده‌اند.

  • چرخشی (3128): اتصالات جدید بین همه نمونه‌های سالم توزیع می‌شوند. پیش‌فرض خوب برای مرورگرها، مرور عمومی، و کارهایی که اغلب اتصالات تازه باز می‌کنند.
  • چسبنده (3129): همه ترافیک به یک نمونه می‌رود. مناسب برای جریان‌های کاری که باید در طول یک جلسه یک آدرس مبدأ ثابت ارائه دهند.
  • جداسازی به ازای هر گروه: یک backend دوم با زیرمجموعه‌ای از نمونه‌ها ایجاد کنید و یک پورت front-end جدید به آن اشاره دهید، تا یک تیم هرگز کل استخر را مصرف نکند.

عیب‌یابی

نشانه علت احتمالی رفع
Privoxy پاسخ 403 برمی‌گرداند فیلتر محتوا فعال است و یک قاعده فیلتر با درخواست مطابقت کرده است تأیید کنید که toggle 0 در پیکربندی نمونه وجود دارد و آن نمونه را راه‌اندازی مجدد کنید
Privoxy پاسخ 502 یا خطای اتصال بالادست برمی‌گرداند میزبان، پورت، یا اعتبارنامه SOCKS5 اشتباه است تست مستقیم curl --proxy "socks5h://..." از مرحله ۱ را دوباره اجرا کنید
همه backendها در صفحه آمار به عنوان DOWN نشان داده می‌شوند نمونه‌های Privoxy در حال اجرا نیستند یا در جایی که HAProxy انتظار دارد شنود نمی‌کنند systemctl list-units 'privoxy-gateway@*' و `ss -ltnp
هر درخواست از همان آدرس خارج می‌شود کلاینت از یک اتصال keep-alive دوباره استفاده می‌کند، یا فقط یک نمونه بالاست اتصالات جدید به ازای هر درخواست را اجبار کنید، و تأیید کنید که همه backendها UP گزارش می‌دهند
نام‌های میزبان از شبکه خودتان حل می‌شوند نمونه از forward-socks5 به جای forward-socks5t استفاده می‌کند به forward-socks5t تغییر دهید تا DNS از طریق پروکسی حل شود
HAProxy با خطای /dev/log شروع نمی‌شود سوکت syslog روی میزبان وجود ندارد خط log /dev/log local0 را حذف کنید، یا یک سرویس syslog نصب و فعال کنید
دانلودهای بزرگ در میانه انتقال timeout می‌شوند timeoutهای پیش‌فرض HAProxy برای بار کاری خیلی کم هستند timeout client و timeout server را در بخش defaults افزایش دهید

خلاصه

شما اکنون یک آدرس پروکسی HTTP واحد دارید که چندین نقطه پایانی SOCKS5 ProxyScrape را در جلو دارد، با بررسی سلامت خودکار در سمت HAProxy و چرخش به ازای هر اتصال روی پورت 3128. اعتبارنامه‌ها در یک مجموعه از فایل‌های پیکربندی تحت مالکیت root زندگی می‌کنند به جای اینکه در هر ابزار روی هر ماشین کپی شوند.

مراحل بعدی طبیعی: هر زمان که ظرفیت بالادست بیشتری می‌خواهید یک نمونه و یک خط server اضافه کنید، فایل‌های پیکربندی Privoxy را از کنترل نسخه دور نگه دارید، و اعتبارنامه‌ها را با ویرایش پیکربندی نمونه‌ها و راه‌اندازی مجدد unitهای قالب یکی یکی بچرخانید تا دروازه هرگز کاملاً آفلاین نشود.