چگونه یک دروازه پروکسی اشتراکی ProxyScrape روی لینوکس با Privoxy و HAProxy بسازیم
یک نقطه پایانی SOCKS5 ProxyScrape را به یک آدرس پروکسی HTTP تبدیل کنید که کل تیم شما بتواند از آن استفاده کند، با چرخش چرخشی در چندین بالادست، بررسی سلامت، و کنترل دسترسی شبکه خصوصی.
مرور کلی
تنظیمات پروکسی به ازای هر ماشین مقیاسپذیر نیست. وقتی چندین نفر، چند اجراکننده 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های قالب یکی یکی بچرخانید تا دروازه هرگز کاملاً آفلاین نشود.