ProxynetProxynet

تنظیمات پروکسی در Linux: ترمینال، apt، Docker و Git

تاریخ انتشار:

18 دقیقه مطالعه

Acar Diveroli
نویسنده: Acar Diveroli
زمینه سیاه با سطرهای محو IP؛ در قابی گوشه‌به‌علاوه: چپ Proxynet، راست ⁨Linux⁩، ضربدری میانشان و برچسب INTEGRATION

روی یک سرور Linux پروکسی را تعریف کرده‌اید، curl کار می‌کند، اما sudo apt update هنوز به نشانی قبلی می‌رود، git clone گیر می‌کند و docker build اصلاً به شبکه نمی‌رسد. این به معنای تنظیم اشتباه شما نیست. در Linux یک «کلید پروکسی» مرکزی وجود ندارد: متغیرهای محیطی پوسته شما یک لایه است، فایل پیکربندی هر ابزار لایه دوم است و سرویس‌هایی که زیر systemd اجرا می‌شوند لایه سوم و کاملاً جداگانه‌اند.

این نوشته آن سه لایه را به ترتیب شرح می‌دهد. نخست تنظیم موقت و ماندگار متغیر محیطی، تفاوت حروف بزرگ و کوچک، قاعده‌های نوشتن no_proxy و اینکه چرا sudo محیط شما را منتقل نمی‌کند. سپس پیکربندی جداگانه apt و git و pip و npm و Docker، اینکه چرا تنظیم محیط گرافیکی روی ترمینال اثر ندارد، گام‌های راستی‌آزمایی و برای هر تنظیم یک خط بازگرداندن.

چرا تنظیم پروکسی در Linux از یک جا انجام نمی‌شود؟

در Windows و macOS سیستم‌عامل یک ثبت پروکسی سیستمی دارد و بیشتر برنامه‌ها آن را می‌خوانند. در Linux چنین ثبتی وجود ندارد. به‌جای آن یک سنت از دهه 1990 هست: برنامه هنگام اجرا به متغیرهای محیطی http_proxy و https_proxy و all_proxy و no_proxy نگاه می‌کند و اگر تعریف شده باشند از آن‌ها استفاده می‌کند. این یک استاندارد نیست، یک عادت رایج است. باید ابزار به ابزار بدانید کدام یک از آن پیروی می‌کند.

جدا کردن سه لایه بیشتر مشکل‌ها را حل می‌کند:

  1. محیط پوسته. متغیرهایی که با export تعریف می‌کنید به فرایندهایی که از همان پوسته اجرا می‌کنید به ارث می‌رسند. با بستن ترمینال تمام می‌شوند.
  2. پیکربندی خود ابزار. apt و git و pip و npm و Docker فایل‌های خودشان را دارند. این فایل‌ها مستقل از متغیرهای محیطی کار می‌کنند و معمولاً آن‌ها را نادیده می‌گیرند.
  3. محیط سرویس. سرویسی که با systemd آغاز می‌شود از پوسته شما زاده نشده است و بنابراین متغیرهای شما را اصلاً نمی‌بیند. از فایل واحد خودش می‌خواند.

برای فهمیدن اینکه چرا یک تنظیم «کار نمی‌کند» باید نخست پرسید آن ابزار به کدام لایه نگاه می‌کند.

نشانی پروکسی در چه قالبی نوشته می‌شود؟

در همه روش‌های زیر نشانی به یک شکل نوشته می‌شود:

text
http://user:pass@pr.proxynet.io:8000

طرح http:// پروتکل اتصالی است که با پروکسی برقرار می‌شود و هنگام رفتن به نشانی‌های HTTPS هم همین می‌ماند. بخش user:pass@ تنها وقتی لازم است که با نام کاربری و رمز احراز هویت می‌کنید؛ اگر از پنل IP سرور خود را مجاز کرده باشید این بخش را کاملاً کنار می‌گذارید. تفاوت دو روش را در احراز هویت پروکسی: نام کاربری و رمز یا لیست سفید IP شرح داده‌ایم.

اگر رمز شما @ یا : یا # یا / دارد، آن‌ها را با کدگذاری درصدی در نشانی بنویسید: %40 برای @ و %23 برای #. یک @ کدنشده نشانی را از جای نادرست می‌شکند و نتیجه معمولاً یک 407 Proxy Authentication Required است. جزئیات کدگذاری و تفاوت کتابخانه‌ها در این زمینه در بخش اطلاعات ورود نوشته استفاده از پروکسی در Node.js با Axios و node-fetch آمده است.

تنظیم موقت با متغیرهای محیطی

سریع‌ترین راه تعریف متغیرها برای همان نشست است:

bash
export http_proxy="http://user:pass@pr.proxynet.io:8000"
export https_proxy="$http_proxy"
export no_proxy="localhost,127.0.0.1,.company.local"

curl -s https://api.ipify.org; echo

اگر خروجی به‌جای IP شما IP پروکسی را نشان دهد، یعنی تنظیم کار می‌کند. برای برداشتن متغیرها نوشتن unset http_proxy https_proxy no_proxy کافی است.

اینکه این متغیرها چه هستند، کدام ابزارها آن‌ها را می‌خوانند و رابطه‌شان با فایل‌های ابزاری مانند .wgetrc چیست را با جزئیات در استفاده از پروکسی در wget: دستورها و نمونه‌ها توضیح داده‌ایم و اینجا تکرار نمی‌کنیم. برای گزینه‌های سمت cURL و استفاده از SOCKS5 می‌توانید به استفاده از cURL با پروکسی: دستورها و مثال‌ها نگاه کنید.

دو نکته عملی: اگر export ننویسید متغیر تنها در خود پوسته می‌ماند و به برنامه‌هایی که اجرا می‌کنید نمی‌رسد. اگر تنظیم موقت برای یک دستور می‌خواهید، متغیر را پیش از دستور بنویسید تا فقط همان دستور تحت تأثیر باشد:

bash
https_proxy="http://user:pass@pr.proxynet.io:8000" curl -s https://api.ipify.org

http_proxy و HTTP_PROXY: چرا حروف بزرگ مهم است؟

در Linux نام متغیرهای محیطی به بزرگی و کوچکی حروف حساس است: http_proxy و HTTP_PROXY دو متغیر جداگانه‌اند. ابزارها با این دو یکسان رفتار نمی‌کنند.

cURL و هر چیزی که از libcurl استفاده می‌کند، نگارش کوچک و بزرگ متغیرهای پروکسی را می‌پذیرد و به نگارش کوچک اولویت می‌دهد. تنها استثنا http_proxy است: cURL آن را فقط با حروف کوچک می‌خواند. دلیلش امنیت است. وقتی یک اسکریپت CGI اجرا می‌شود، سرور سرایندهای درخواست ورودی را با پیشوند HTTP_ به متغیر محیطی تبدیل می‌کند؛ یعنی سرایند Proxy: که از راه دور فرستاده شود می‌تواند متغیر HTTP_PROXY را پر کند. مشکل‌های امنیتی که این رفتار در گذشته پدید آورده در مستندات cURL شرح داده شده است.

در عمل دو قاعده کار شما را راه می‌اندازد:

  • نگارش کوچک را مبنا بگیرید. http_proxy و https_proxy و no_proxy بنویسید.
  • هر دو را تعریف کنید. برخی ابزارهای Java و Go تنها نگارش بزرگ را می‌جویند. تنظیم هر دو گروه روی یک مقدار کم‌غافلگیرترین راه است.
bash
export http_proxy="http://user:pass@pr.proxynet.io:8000"
export https_proxy="$http_proxy"
export no_proxy="localhost,127.0.0.1"
# also define the uppercase twins
export HTTP_PROXY="$http_proxy" HTTPS_PROXY="$https_proxy" NO_PROXY="$no_proxy"

all_proxy مقدار پیش‌فرض مستقل از پروتکل است؛ اگر متغیر ویژه یک پروتکل وجود داشته باشد، آن جلو می‌افتد. اگر SOCKS5 به کار می‌برید، قالب all_proxy="socks5h://user:pass@pr.proxynet.io:1080" را ترجیح دهید. در طرح socks5h تحلیل نام دامنه در سمت پروکسی انجام می‌شود. تفاوت‌ها را در صفحه پروکسی SOCKS5 و در تفاوت پروکسی SOCKS و HTTP: کدام را انتخاب کنیم؟ می‌یابید.

no_proxy چگونه نوشته می‌شود؟

no_proxy فهرست نشانی‌هایی است که نباید از پروکسی بگذرند و با ویرگول جدا می‌شود. استانداردی ندارد، برای همین بین ابزارها تفاوت‌های کوچکی می‌بینید. در آزمایش‌های ما با ⁦cURL 8.21⁩ رفتار چنین است:

نگارشنتیجه
example.comexample.com و www.example.com بدون پروکسی می‌روند، پورت هر چه باشد
.example.comزیردامنه‌ها و خود دامنه را در بر می‌گیرد
sub.example.comتنها همان زیردامنه؛ example.com بالاتر باز هم از پروکسی می‌گذرد
EXAMPLE.COMبه بزرگی حروف حساس نیست، منطبق می‌شود
example.com:80منطبق نمی‌شود، نوشتن پورت پشتیبانی نمی‌شود
10.0.0.0/8از ⁦cURL 7.86⁩ به بعد نشانه‌گذاری CIDR کار می‌کند
*یک ستاره تنها همه نشانی‌ها را بیرون از پروکسی می‌گذارد

دو دام هست. نخست نوشتن پورت است: no_proxy فهرستی از میزبان‌هاست و اگر server:port بنویسید آن خط با هیچ چیز منطبق نمی‌شود و درخواست بی‌صدا به پروکسی می‌رود. دوم اینکه CIDR همه‌جا کار نمی‌کند؛ پیمانه urllib در Python ورودی 10.0.0.0/8 را در همان فهرست نمی‌شناسد و نشانی 10.1.2.3 را به پروکسی می‌فرستد. اگر می‌خواهید در سمت Python شبکه داخلی را بیرون نگه دارید، نشانی‌ها را تک‌تک یا با نام دامنه بنویسید.

دست‌کم این‌ها را در فهرست بگذارید: localhost و 127.0.0.1 و اگر دارید نام دامنه شبکه داخلی و شبکه کانتینر. وگرنه درخواست به سرور توسعه محلی شما هم از پروکسی می‌چرخد و به مهلت زمانی می‌خورد.

ماندگار کردن تنظیم: ~/.bashrc و /etc/environment

با بستن ترمینال خط‌های export از میان می‌روند. برای ماندگاری دو جا هست و دامنه‌شان فرق دارد.

~/.bashrc برای یک کاربر. همان خط‌های export را به انتهای فایل بیفزایید، سپس با source ~/.bashrc دوباره بخوانید. این فایل در پوسته‌های تعاملی اجرا می‌شود، یعنی وقتی با SSH وارد می‌شوید و دستور می‌نویسید معتبر است. اگر Zsh به کار می‌برید معادلش ~/.zshrc است و خط‌ها بی‌تغییر معتبرند؛ اگر fish به کار می‌برید فایل ~/.config/fish/config.fish می‌شود و نگارش به شکل set -gx http_proxy "…" درمی‌آید.

/etc/environment برای کل سیستم. این فایل را نه پوسته، بلکه پیمانه pam_env از PAM می‌خواند. متغیرها برای هر کاربری که نشست باز می‌کند تعریف می‌شوند. قالبش سخت‌گیرانه است: در هر خط یک KEY=VALUE، و کلیدواژه export همان‌گونه که در مستندات آمده برای سازگاری پذیرفته می‌شود اما نادیده گرفته می‌شود و بسط پوسته انجام نمی‌گیرد. یعنی ارجاعی مانند $http_proxy اینجا کار نمی‌کند و باید مقدار را صریح بنویسید:

ini
# /etc/environment contents, plain and unquoted
http_proxy=http://user:pass@pr.proxynet.io:8000
https_proxy=http://user:pass@pr.proxynet.io:8000
no_proxy=localhost,127.0.0.1

تغییر در نشست‌های تازه معتبر می‌شود؛ برای دیدن آن در نشست SSH باز، بیرون بیایید و دوباره وارد شوید. برای بازگرداندن، پاک کردن خط‌ها و تازه کردن نشست کافی است.

در هر دو فایل رمز به‌صورت متن ساده می‌ماند. اگر روی سرور بیش از یک کاربر هست، به‌جای /etc/environment فایل کاربر را ترجیح دهید، یا از پنل IP سرور را مجاز کنید و به استفاده بدون رمز بروید. برای این سناریو که نشانی خروج ثابت می‌خواهد، بسته‌های پروکسی ISP و پروکسی دیتاسنتر مناسب‌اند.

چرا sudo تنظیم پروکسی شما را نمی‌بیند؟

اگر sudo apt update پروکسی را نادیده می‌گیرد، دلیلش معمولاً این است: sudo به دلیل امنیتی بیشتر متغیرهای محیطی کاربر فراخوان را با یک محیط تمیز جایگزین می‌کند. اینکه می‌خواهید محیط کاربر حفظ شود را با گزینه -E اعلام می‌کنید؛ همان‌طور که در راهنمای sudo آمده، سیاست امنیتی می‌تواند این درخواست را رد کند.

bash
sudo -E apt update

اگر دستور باز هم از پروکسی استفاده نکرد، دو احتمال می‌ماند: یا پیکربندی sudoers اجازه عبور این متغیرها را نمی‌دهد، یا ابزار اصلاً به متغیر محیطی نگاه نمی‌کند و فایل خودش را می‌خواند. برای apt دومی راه‌حل استوارتری است و موضوع بخش بعدی.

تنظیم پروکسی apt

apt متغیرهای محیطی را هم می‌خواند اما جای اصلی‌اش پوشه /etc/apt/apt.conf.d/ است. یک فایل تکه‌ای که آنجا بگذارید هم مشکل sudo را حل می‌کند و هم به‌روزرسانی‌هایی را که با cron اجرا می‌شوند.

text
// /etc/apt/apt.conf.d/95proxy
Acquire::http::Proxy "http://user:pass@pr.proxynet.io:8000";
Acquire::https::Proxy "http://user:pass@pr.proxynet.io:8000";

نقطه‌ویرگول پایان خط اجباری است. برای بیرون گذاشتن یک سرور مشخص از پروکسی، خط ویژه آن میزبان را با کلیدواژه DIRECT می‌نویسید:

text
Acquire::http::Proxy::repo.company.local "DIRECT";

در نام فایل یک نکته هست: بر پایه راهنمای apt.conf، از تکه‌های این پوشه تنها آن‌هایی خوانده می‌شوند که پسوند ندارند یا پسوندشان conf است و در نامشان هم جز حرف و رقم و خط تیره و زیرخط و نقطه چیزی نیست. یعنی 95proxy و 95proxy.conf معتبرند؛ 95proxy.bak نادیده گرفته می‌شود و apt این را با یک اعلان می‌گوید. برای بازگرداندن تنظیم، فایل را پاک کنید یا از پوشه بیرون ببرید، دستور دیگری لازم نیست.

تنظیم پروکسی git

git برای نشانی‌های HTTP و HTTPS از libcurl استفاده می‌کند، پس متغیرهای http_proxy و https_proxy را از پیش می‌خواند. اگر تنظیم ماندگار و صریح می‌خواهید، در پیکربندی خودش بنویسید:

bash
git config --global http.proxy "http://user:pass@pr.proxynet.io:8000"

git config --global --get http.proxy      # verify
git config --global --unset http.proxy    # undo

اگر می‌خواهید تنها برای یک سرور مشخص معتبر باشد، می‌توانید آن را به نشانی مشروط کنید. این کار سبب می‌شود به سرور git داخلی مستقیم و به بیرون با پروکسی بروید:

bash
git config --global http.https://github.com.proxy "http://user:pass@pr.proxynet.io:8000"

جزئیاتی که در آزمایش ما پیدا شد در عمل زیاد دردسر می‌سازد. پیش‌فرض تنظیم http.proxyAuthMethod در git مقدار anyauth است و بر پایه مستندات git-config این حالت فرض می‌کند پروکسی به درخواست بدون هویت با 407 و سرایند Proxy-Authenticate پاسخ می‌دهد. در پروکسی‌هایی که این دور شناسایی را کامل نمی‌کنند، git با خطای Proxy CONNECT aborted می‌ایستد. همان دستور با basic در نخستین تلاش می‌گذرد:

bash
git config --global http.proxyAuthMethod basic

اگر بخواهید تنظیم را برای یک دستور بیازمایید، پرچم -c اصلاً به پیکربندی دست نمی‌زند: git -c http.proxy=... ls-remote <address>. اگر با SSH دریافت می‌کنید هیچ‌کدام از این تنظیم‌ها اثر ندارد؛ برای SSH خط ProxyCommand در ~/.ssh/config لازم است.

تنظیم پروکسی pip

pip سه راه دارد و ترتیب اولویت در مستندات pip نوشته شده است: گزینه‌های خط فرمان بر متغیرهای محیطی و آن‌ها بر فایل پیکربندی برتری دارند.

bash
# 1) one-off
pip install --proxy "http://user:pass@pr.proxynet.io:8000" requests

# 2) environment variable; the PIP_<OPTION> pattern works for every option
export PIP_PROXY="http://user:pass@pr.proxynet.io:8000"

برای تنظیم ماندگار فایل ~/.config/pip/pip.conf را به کار ببرید. /etc/pip.conf برای کل سیستم و $VIRTUAL_ENV/pip.conf تنها برای یک محیط مجازی همین قالب را می‌پذیرند:

ini
[global]
proxy = http://user:pass@pr.proxynet.io:8000

اگر مطمئن نیستید کدام فایل خوانده می‌شود، pip config debug همه مسیرها و مقدارهای معتبر آن لحظه را فهرست می‌کند. برای بازگرداندن pip config unset global.proxy بنویسید یا خط را از فایل پاک کنید.

تنظیم پروکسی npm

npm فایل‌های .npmrc را به ترتیب پروژه، کاربر، سراسری و درون‌ساخت می‌خواند؛ جلویی عقبی را نادیده می‌گیرد. بر پایه مستندات npm متغیرهای محیطی HTTP_PROXY و HTTPS_PROXY هم رعایت می‌شوند و پیش‌فرض گزینه noproxy همان متغیر NO_PROXY است.

bash
npm config set proxy "http://user:pass@pr.proxynet.io:8000"
npm config set https-proxy "http://user:pass@pr.proxynet.io:8000"
npm config set noproxy "localhost,127.0.0.1,registry.company.local"

npm config delete proxy && npm config delete https-proxy   # undo

برای اینکه تنظیم تنها در یک مخزن معتبر باشد، به دستورها --location=project بیفزایید؛ npm آن‌گاه مقدارها را در فایل .npmrc ریشه پروژه می‌نویسد. این فایل را به کنترل نسخه نفرستید، رمز در آن هست.

یک غافلگیری کوچک: دستور npm config get https-proxy مقدار را نشان نمی‌دهد و هشدار «protected» می‌دهد. گزینه‌هایی که اطلاعات ورود دارند برای خواندن بسته‌اند. برای دیدن مقدار، فایل .npmrc را مستقیم باز کنید.

تنظیم پروکسی Docker

در Docker یک تنظیم یگانه وجود ندارد: فرایند پس‌زمینه و کانتینرها تنظیم را از دو جای مستقل می‌خوانند و روی آن یک دام نشانی کلاسیک هم هست. بیشتر سردرگمی از همین‌جا برمی‌خیزد.

1. فرایند پس‌زمینه (دریافت ایمیج). docker pull و docker push را dockerd انجام می‌دهد، نه پوسته شما. بر پایه مستندات Docker تنظیم در کلید proxies از فایل /etc/docker/daemon.json نوشته می‌شود:

json
{
  "proxies": {
    "http-proxy": "http://user:pass@pr.proxynet.io:8000",
    "https-proxy": "http://user:pass@pr.proxynet.io:8000",
    "no-proxy": "localhost,127.0.0.1,.company.local"
  }
}

همین کار با یک فایل تکه‌ای در سمت systemd هم انجام می‌شود. در فایل /etc/systemd/system/docker.service.d/http-proxy.conf این خط‌ها نوشته می‌شوند:

ini
[Service]
Environment="HTTP_PROXY=http://user:pass@pr.proxynet.io:8000"
Environment="HTTPS_PROXY=http://user:pass@pr.proxynet.io:8000"
Environment="NO_PROXY=localhost,127.0.0.1,.company.local"

در هر دو روش تنظیم پس از sudo systemctl daemon-reload و sudo systemctl restart docker معتبر می‌شود. این الگو تنها ویژه Docker نیست: به هر سرویسی که با systemd کار می‌کند پروکسی همین‌طور معرفی می‌شود، چون سرویس از پوسته شما زاده نمی‌شود و فایل ~/.bashrc شما را اصلاً نمی‌خواند.

2. کانتینرها و ساخت‌ها. بیرون رفتن برنامه درون کانتینر موضوع جداگانه‌ای است. همان‌طور که در مستندات خودش شرح داده شده، رابط خط فرمان Docker بلوک proxies.default از فایل ~/.docker/config.json را می‌خواند و مقدارهای آنجا را به‌عنوان متغیر محیطی به کانتینرها و ساخت‌های تازه می‌دهد:

json
{
  "proxies": {
    "default": {
      "httpProxy": "http://user:pass@pr.proxynet.io:8000",
      "httpsProxy": "http://user:pass@pr.proxynet.io:8000",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}

تنظیم‌های این فایل بر فرایند پس‌زمینه اثر ندارد؛ تنها به محیط کانتینر و ساخت می‌رسد و تنها بر تازه‌ساخته‌ها اعمال می‌شود. برای استفاده یک‌باره docker run --env HTTP_PROXY=... و docker build --build-arg HTTP_PROXY=... همان کار را می‌کنند.

3. دام نشانی. اگر پروکسی روی خود ماشین کار می‌کند، درون کانتینر http://127.0.0.1:8000 ننویسید. کانتینر فضای شبکه خودش را دارد و 127.0.0.1 آنجا خود کانتینر است. برای رسیدن به ماشین میزبان، نشانی شبکه میزبان را به کار ببرید.

چرا تنظیم محیط گرافیکی روی ترمینال اثر ندارد؟

در Ubuntu تعریفی که از بخش Settings > Network > Network Proxy انجام می‌دهید در انبار تنظیم‌های خود GNOME نوشته می‌شود و بر برنامه‌هایی اثر می‌گذارد که این مقدارها را می‌خوانند: مرورگر GNOME، مرکز نرم‌افزار و بیشتر برنامه‌های میزکار. پوسته‌ای که در ترمینال باز می‌کنید این انبار را نمی‌خواند، بنابراین curl و git تحت تأثیر نیستند. اگر بخواهید همین تنظیم را از خط فرمان انجام دهید، gsettings set org.gnome.system.proxy mode 'manual' و کلیدهای host و port مربوط به کار می‌روند، اما برای سمت ترمینال باز هم متغیر محیطی لازم است.

نتیجه عملی این است: اگر روی سرور میزکار نیست، این بخش را کاملاً رد کنید. اگر روی میزکار کار می‌کنید باید هر دو تنظیم را انجام دهید. برای معادل‌های آن در سیستم‌عامل‌های دیگر می‌توانید به تنظیم پروکسی در ویندوز و کروم و تنظیم پروکسی در Mac و Safari و تنظیم پروکسی در گوشی اندروید چگونه انجام می‌شود؟ نگاه کنید.

جدول ابزار، فایل و بازگرداندن

ابزارجای تنظیمبازگرداندن
پوسته (موقت)export http_proxy=…unset http_proxy https_proxy no_proxy
پوسته (کاربر)~/.bashrc، ~/.zshrcخط را پاک کنید، با source تازه کنید
کل سیستم/etc/environmentخط را پاک کنید، نشست را تازه کنید
سرویس systemd/etc/systemd/system/<name>.service.d/*.confفایل را پاک کنید، daemon-reload
apt/etc/apt/apt.conf.d/95proxyفایل را از پوشه بیرون ببرید
gitgit config --global http.proxygit config --global --unset http.proxy
pip~/.config/pip/pip.conf، --proxypip config unset global.proxy
npm.npmrc (npm config set proxy)npm config delete proxy
پس‌زمینه Docker/etc/docker/daemon.jsonکلید را پاک کنید، سرویس را دوباره آغاز کنید
کانتینرهای Docker~/.docker/config.jsonبلوک proxies را پاک کنید
میزکار GNOMESettings > Network > Network Proxyحالت را روی «خاموش» بگذارید

چگونه از کار کردن تنظیم مطمئن می‌شوید؟

چهار گام، به ترتیب:

  1. متغیرها را ببینید. خروجی env | grep -i proxy باید مقدارهای مورد انتظار و همزادهای بزرگ آن‌ها را نشان دهد.
  2. نشانی خروج را ببینید. نشانی‌ای که curl -s https://api.ipify.org برمی‌گرداند باید نشانی پروکسی باشد.
  3. اتصال را دنبال کنید. در خروجی curl -v دنبال خط Uses proxy env variable و خط Trying بگردید که به‌جای مقصد به نشانی پروکسی می‌رود. اگر این دو خط نیستند، درخواست اصلاً به پروکسی نمی‌رود.
  4. هر ابزار را جدا بیازمایید. دستورهای sudo apt update و git ls-remote <address> و pip download --no-deps six و npm view express version پیکربندی خودشان را به کار می‌برند و هر کدام باید جداگانه راستی‌آزمایی شوند.

گام‌های مفصل سنجش و تأیید مکان را در آیا پروکسی کار می‌کند؟ چگونه پروکسی را آزمایش کنیم گرد آورده‌ایم.

اشتباه‌های رایج

  • فراموش کردن export. نوشتن http_proxy=... به‌تنهایی متغیر را فقط در پوسته می‌گذارد و به برنامه‌ای که اجرا می‌کنید نمی‌رساند.
  • تعریف کردن تنها http_proxy. درخواست‌هایی که به نشانی‌های HTTPS می‌روند به متغیر https_proxy نگاه می‌کنند؛ اگر نباشد می‌کوشند مستقیم بیرون بروند.
  • آغاز کردن مقدار https_proxy با https://. اگر پروکسی شما TLS را پایان نمی‌دهد، مقدار با http:// آغاز می‌شود.
  • نوشتن رمز بدون کدگذاری. @ درون آن نشانی را می‌شکند و نتیجه 407 می‌شود. دلیل‌های دیگر 407 را در کدهای وضعیت HTTP در وب اسکرپینگ: 403، 407، 429، 503 برشمرده‌ایم.
  • نوشتن پورت در فهرست no_proxy. ورودی server:8080 با هیچ چیز منطبق نمی‌شود.
  • انتظار داشتن از سرویس با تنظیم پوسته. سرویس systemd فایل ~/.bashrc را نمی‌خواند؛ فایل واحد یا فایل تکه‌ای لازم است.
  • فراموش کردن فایل پیکربندی و مقصر دانستن متغیر محیطی. git config --get http.proxy و pip config debug و npm config list یک مقدار قدیمی را آشکار می‌کنند.
  • نوشتن 127.0.0.1 درون کانتینر. کانتینر فضای شبکه خودش را دارد.

تشخیص حالت‌هایی که اتصال اصلاً برقرار نمی‌شود را جداگانه در خطای پروکسی چیست؟ رفع خطای پاسخ ندادن سرور پروکسی بررسی کرده‌ایم.

راهنمای انتخاب

نیازتنظیم پیشنهادی
گذراندن یک دستور از پروکسیمتغیر را پیش از دستور بنویسید
کار کردن در ترمینال در طول نشستخط‌های export
ماندگار روی سرور، یک کاربر~/.bashrc
ماندگار روی سرور، همه کاربران/etc/environment
گذشتن به‌روزرسانی بسته‌ها/etc/apt/apt.conf.d/95proxy
تنها ترافیک git به مخزن‌های بیرونیhttp.<address>.proxy
تنها یک گام در جریان کار CIPIP_PROXY یا npm_config_proxy
ساخت کانتینر~/.docker/config.json یا --build-arg
سرویس پس‌زمینه (dockerd، cron)فایل تکه‌ای systemd
بیرون نگه داشتن شبکه داخلیno_proxy و Acquire::…::DIRECT

پرسش‌های متداول

تنظیم‌ها را انجام دادم اما برخی برنامه‌ها هنوز مستقیم بیرون می‌روند، چرا؟

خواندن متغیرهای محیطی اجبار نیست، عادت است. برخی ابزارهای نوشته‌شده با Go تنها نگارش بزرگ را می‌جویند و برخی برنامه‌های Java پارامتر -Dhttp.proxyHost خودشان را می‌خواهند. در مستندات برنامه سرفصل پروکسی را ببینید؛ اگر تنظیم خودش را دارد، متغیر محیطی از آن جلو نمی‌زند.

آیا می‌توانم بدون نوشتن رمز در فایل از پروکسی استفاده کنم؟

بله. اگر از پنل پروکسی نشانی IP خروج سرور خود را مجاز کنید، نشانی به http://pr.proxynet.io:8000 فرو می‌آید و در هیچ فایلی رمز نمی‌ماند. در سرورهای با IP ثابت این تمیزترین راه است.

آیا می‌توانم هم‌زمان از چند پروکسی استفاده کنم؟

متغیرهای محیطی یک نشانی نگه می‌دارند. تفکیک را بر پایه پروتکل (http_proxy و https_proxy جداگانه) یا بر پایه ابزار (در git http.<address>.proxy و در apt خط ویژه میزبان) انجام می‌دهید. اگر برای هر درخواست نشانی خروج متفاوت لازم دارید، یک بسته پروکسی چرخشی با نشانی یگانه این کار را به‌جای شما انجام می‌دهد.

آیا اتصال‌های SSH من هم از پروکسی می‌گذرند؟

نه. http_proxy و همراهانش بر کارخواه SSH اثر ندارند. برای گذراندن SSH از یک پروکسی خط ProxyCommand در فایل ~/.ssh/config تعریف می‌شود. نشانی‌هایی به شکل git clone git@... هم به همین دلیل تنظیم http.proxy را نادیده می‌گیرند.

چرا کارهای cron من پروکسی را نمی‌بینند؟

cron کارها را از پوسته ورود شما آغاز نمی‌کند و فایل ~/.bashrc شما را نمی‌خواند. متغیرها را یا در آغاز فایل crontab تعریف کنید یا در نخستین خط‌های اسکریپت با export تنظیم کنید.

apt از راه پروکسی کند شد، طبیعی است؟

مخزن‌های بسته از نظر جغرافیایی پراکنده‌اند و پروکسی می‌تواند ترافیک را به کشور دیگری ببرد. استفاده از پروکسی تنها برای منابع بیرونی و بیرون گذاشتن آینه‌های مخزن محلی با خط Acquire::http::Proxy::<host> "DIRECT"; در بیشتر حالت‌ها کافی است.

خلاصه

تنظیم پروکسی در Linux از سه لایه تشکیل می‌شود: محیط پوسته، فایل پیکربندی خود ابزار و واحد سرویس. در ترمینال با export آغاز کنید، برای ماندگاری ~/.bashrc یا /etc/environment را به کار ببرید، سپس apt و git و pip و npm و Docker را جداگانه از فایل‌های خودشان تنظیم کنید. در هر گام با curl -s https://api.ipify.org راستی‌آزمایی کنید و افزودن شبکه داخلی به فهرست no_proxy را از قلم نیندازید. برای کارهای ثابت و پرحجمی که روی سرور اجرا می‌شوند می‌توانید به راهکارهای استخراج داده ما یا مستقیم به صفحه پروکسی HTTPS سر بزنید.

پرسش از ChatGPTپرسش از Claude