← بازگشت به وبلاگ

چگونه HTTPS_PROXY را برای Cursor و Claude Code در شبکه شرکتی تنظیم کنیم

راهنمای فنی مرحله به مرحله برای تنظیم متغیرهای محیطی HTTPS_PROXY، HTTP_PROXY و NO_PROXY برای عملکرد صحیح Cursor و Claude Code در شرکت‌هایی با سرور پروکسی شرکتی.

📅۱۷ آبان ۱۴۰۵

اگر شرکت شما ترافیک خروجی را از طریق پروکسی شرکتی مسدود کند، دستیاران هوش مصنوعی مانند Cursor و Claude Code به سادگی دیگر پاسخ نمی‌دهند: تکمیل خودکار متوقف می‌شود، CLI خطای ETIMEDOUT یا مشکل گواهی SSL را نشان می‌دهد. بیایید بررسی کنیم که چگونه متغیرهای محیطی HTTPS_PROXY را به درستی تنظیم کنیم، احراز هویت را پیکربندی کنیم و از خطاهای رایج که باعث می‌شود توسعه‌دهندگان ساعت‌ها را صرف اشکال‌زدایی تنظیمات شبکه به جای کد کنند، جلوگیری کنیم.

چرا دستیاران هوش مصنوعی به پروکسی در شبکه شرکتی نیاز دارند

Cursor و Claude Code مدل‌های محلی نیستند. آن‌ها به طور مداوم به API‌های خارجی مراجعه می‌کنند: Cursor به سرورهای ایندکس کد خود و API مدل‌ها (OpenAI، Anthropic، Google بسته به ارائه‌دهنده انتخابی) متصل می‌شود، در حالی که Claude Code — به طور مستقیم به API Anthropic از طریق HTTPS. در شبکه شرکتی، دسترسی مستقیم به اینترنت معمولاً توسط فایروال مسدود می‌شود، و تمام ترافیک خروجی باید از طریق سرور پروکسی (Squid، Zscaler، Blue Coat، Fortinet FortiProxy یا دروازه داخلی شرکتی) عبور کند. بدون متغیرهای محیطی به درستی تنظیم شده، برنامه به سادگی نمی‌داند که ترافیک باید از طریق پروکسی عبور کند و سعی می‌کند به طور مستقیم به اینترنت متصل شود — که منجر به زمان‌های تایم اوت می‌شود.

یک چالش جداگانه این است که Cursor بر پایه Electron ساخته شده است (در واقع این Chromium + Node.js است)، در حالی که Claude Code — یک برنامه CLI بر پایه Node.js است. هر کدام منطق خاص خود را برای خواندن تنظیمات پروکسی دارند: Electron به طور جزئی تنظیمات سیستم‌عامل را به ارث می‌برد، در حالی که فرآیندهای Node.js متغیرهای محیطی HTTP_PROXY/HTTPS_PROXY را به طور مستقیم یا از طریق کتابخانه‌هایی مانند undici و node-fetch می‌خوانند. این باعث سردرگمی می‌شود: تنظیمات نوشته شده‌اند، اما ابزار آن‌ها را «نمی‌بیند».

متغیرهای HTTP_PROXY، HTTPS_PROXY و NO_PROXY: چگونه کار می‌کند

روش کلاسیک برای تعیین پروکسی برای برنامه‌های کنسولی Node.js، Python و Go — از طریق متغیرهای محیطی است. تفاوت بین HTTP_PROXY و HTTPS_PROXY اصولی است: اولی برای درخواست‌های پروتکل HTTP استفاده می‌شود، دومی برای درخواست‌های HTTPS (و تقریباً تمام ترافیک دستیاران هوش مصنوعی از طریق HTTPS است). بهتر است هر دو را تعیین کنید، حتی اگر ترافیک واقعی فقط HTTPS باشد — برخی کتابخانه‌ها در شروع درخواست‌های HTTP خدماتی انجام می‌دهند.

export HTTP_PROXY="http://proxy.company.local:8080"
export HTTPS_PROXY="http://proxy.company.local:8080"
export NO_PROXY="localhost,127.0.0.1,.company.local"

توجه داشته باشید: حتی برای ترافیک HTTPS، الگوی آدرس پروکسی به عنوان http:// مشخص می‌شود، نه https:// — این آدرس خود پروکسی است، نه منبع هدف. اتصال به پروکسی از طریق HTTP کاملاً طبیعی است، زیرا رمزگذاری تا سرور نهایی به هر حال از طریق مکانیزم تونل‌زنی CONNECT انجام می‌شود.

متغیر NO_PROXY برای استثنا کردن آدرس‌های داخلی شرکت از پروکسی‌سازی لازم است — در غیر این صورت، درخواست‌ها به مخازن git داخلی، Jira یا خدمات محلی توسعه نیز از طریق پروکسی خارجی عبور می‌کنند و یا پیدا نمی‌شوند و یا کند می‌شوند. نکته مهم: برخی کتابخانه‌ها به حروف بزرگ و کوچک متغیرها حساس هستند. برای اطمینان، هر دو نسخه را بنویسید — با حروف بزرگ و کوچک:

export http_proxy="$HTTP_PROXY"
export https_proxy="$HTTPS_PROXY"
export no_proxy="$NO_PROXY"

تنظیم پروکسی برای Cursor

Cursor به طور جزئی از تنظیمات پروکسی سیستم‌عامل استفاده می‌کند (به ویژه در macOS و Windows)، اما برای عملکرد پایدار در شبکه شرکتی بهتر است به وضوح از طریق متغیرهای محیطی و در صورت نیاز، از طریق فایل پیکربندی برنامه تنظیم شود.

در macOS و Linux ساده‌ترین راه افزودن صادرات متغیرها به فایل پروفایل شل است، تا در هر بار اجرای ترمینال که Cursor از آن شروع می‌شود، بارگذاری شوند:

# ~/.zshrc یا ~/.bash_profile
export HTTP_PROXY="http://user:[email protected]:8080"
export HTTPS_PROXY="http://user:[email protected]:8080"
export NO_PROXY="localhost,127.0.0.1,*.company.local"

پس از تغییر فایل پروفایل، source ~/.zshrc را اجرا کنید و Cursor را به طور کامل راه‌اندازی مجدد کنید (فقط پنجره را کوچک نکنید — فرآیند را از طریق Activity Monitor یا مدیر وظایف خاتمه دهید، زیرا برنامه‌های Electron محیط را در زمان شروع کش می‌کنند).

در Windows متغیرها راحت‌تر از طریق تنظیمات محیطی سیستم (کنترل پنل → سیستم → تنظیمات پیشرفته سیستم → متغیرهای محیطی) یا از طریق PowerShell برای ذخیره دائمی تنظیم می‌شوند:

[System.Environment]::SetEnvironmentVariable('HTTPS_PROXY','http://user:[email protected]:8080','User')
[System.Environment]::SetEnvironmentVariable('HTTP_PROXY','http://user:[email protected]:8080','User')
[System.Environment]::SetEnvironmentVariable('NO_PROXY','localhost,127.0.0.1','User')

اگر پس از این Cursor هنوز به API مدل‌ها متصل نمی‌شود، تنظیمات پروکسی را در خود برنامه بررسی کنید: Settings → Network (یا General) — ممکن است یک فیلد جداگانه Proxy URL وجود داشته باشد که متغیرهای سیستم را نادیده می‌گیرد. در برخی از نسخه‌های Cursor همچنین باید به وضوح گزینه «استفاده از تنظیمات پروکسی سیستم» را فعال کنید.

تنظیم پروکسی برای Claude Code

Claude Code یک ابزار CLI بر پایه Node.js است که از طریق npm/npx اجرا می‌شود، بنابراین به طور مستقیم متغیرهای محیطی را از جلسه ترمینالی که در آن فراخوانی شده است، می‌خواند. این کار تنظیم را ساده می‌کند: کافی است متغیرها را قبل از اجرا صادر کنید.

export HTTPS_PROXY="http://user:[email protected]:8080"
export HTTP_PROXY="http://user:[email protected]:8080"
claude

اگر شما Claude Code را به عنوان بخشی از CI-pipeline یا از یک اسکریپت اجرا می‌کنید، متغیرها را به وضوح در دستور اجرا منتقل کنید، تا از وابستگی به محیط جهانی شل جلوگیری کنید:

HTTPS_PROXY="http://proxy.company.local:8080" \
HTTP_PROXY="http://proxy.company.local:8080" \
claude --print "آزمون‌ها را در پروژه بررسی کن"

برای پیکربندی دائمی، بهتر است متغیرها را در فایل .env در ریشه پروژه ثابت کنید و آن را از طریق direnv یا پشتیبانی داخلی dotenv بارگذاری کنید، اگر شل شما از آن پشتیبانی کند. این کار به ویژه زمانی راحت است که پروژه‌های مختلف نیاز به تنظیمات پروکسی متفاوتی دارند (برای مثال، یک پروژه با API داخلی کار می‌کند و دیگری با خدمات خارجی).

احراز هویت در پروکسی شرکتی

بیشتر پروکسی‌های شرکتی به احراز هویت نیاز دارند — Basic Auth، Digest یا NTLM. برای Basic Auth، نام کاربری و رمز عبور را می‌توان به طور مستقیم در URL پروکسی گنجاند، همانطور که در بالا نشان داده شده است: http://user:[email protected]:8080. نکته مهم — اگر در رمز عبور کاراکترهای خاصی وجود داشته باشد (@، #، %), آن‌ها باید URL-encode شوند، در غیر این صورت تجزیه‌کننده رشته پروکسی در مرز نام کاربری و هاست خراب می‌شود.

# اگر رمز عبور P@ssw0rd#2024 باشد، کاراکترهای خاص را کدگذاری کنید:
# @ -> %40، # -> %23
export HTTPS_PROXY="http://user:P%40ssw0rd%[email protected]:8080"

کار با احراز هویت NTLM (که اغلب در کنار Microsoft ISA Server، Forefront TMG یا Fortinet استفاده می‌شود) دشوارتر است — Node.js و بیشتر HTTP-client‌ها به طور پیش‌فرض از NTLM پشتیبانی نمی‌کنند. در این صورت، راه‌حل استاندارد — راه‌اندازی یک پروکسی محلی است که احراز هویت NTLM را بر عهده می‌گیرد و سپس یک پروکسی HTTP «تمیز» را برای برنامه ارائه می‌دهد. برای این کار معمولاً از cntlm یا px (پروکسی NTLM محلی بر پایه Python) استفاده می‌شود. الگو ساده است: Cursor/Claude Code → localhost:3128 (cntlm) → پروکسی NTLM شرکتی → اینترنت.

# مثال پیکربندی cntlm (/etc/cntlm.conf)
Username    your_login
Domain      COMPANY
Password    رمز_عبور_یا_هش_شما
Proxy       proxy.company.local:8080
Listen      3128

# پس از راه‌اندازی cntlm، آدرس محلی را مشخص کنید:
export HTTPS_PROXY="http://127.0.0.1:3128"
export HTTP_PROXY="http://127.0.0.1:3128"

گواهی‌ها و MITM: مشکل SSL در شبکه شرکتی

اگر در شرکت محصولی از نوع Zscaler، Netskope یا هر فیلتر وب دیگری با بازرسی SSL مستقر شده باشد، ترافیک در پروکسی رمزگشایی می‌شود و با گواهی CA ریشه شرکتی امضا می‌شود. Node.js (و بنابراین Claude Code و بخش عمده‌ای از ماژول‌های داخلی Cursor) به طور پیش‌فرض فقط به مجموعه گواهی‌های ریشه داخلی خود اعتماد می‌کند و خطای UNABLE_TO_VERIFY_LEAF_SIGNATURE یا گواهی خود امضا شده در زنجیره گواهی را پرتاب می‌کند.

راه‌حل — صادرات گواهی CA شرکتی (معمولاً می‌توان آن را از بخش IT دریافت کرد یا از مخزن گواهی‌های مرورگر استخراج کرد) و تعیین مسیر آن به Node.js از طریق متغیر NODE_EXTRA_CA_CERTS:

export NODE_EXTRA_CA_CERTS="/etc/ssl/certs/company-root-ca.pem"

به شدت توصیه نمی‌شود که بررسی گواهی‌ها را به طور جهانی از طریق NODE_TLS_REJECT_UNAUTHORIZED=0 غیرفعال کنید — این کار حفاظت در برابر حملات MITM را برای کل فرآیند حذف می‌کند، از جمله اتصالات قانونی. از این پرچم فقط برای تشخیص یک‌باره استفاده کنید و حتماً حفاظت را به حالت اولیه برگردانید.

خطاهای رایج و راه‌حل‌های آن‌ها

خطا علت راه‌حل
ETIMEDOUT / ECONNREFUSED متغیرهای پروکسی در جلسه‌ای که برنامه در آن اجرا شده است، صادر نشده‌اند بررسی کنید echo $HTTPS_PROXY در همان ترمینال، برنامه را به طور کامل راه‌اندازی مجدد کنید
407 نیاز به احراز هویت پروکسی نام کاربری/رمز عبور مشخص نشده یا منقضی شده‌اند اطلاعات کاربری را در رشته پروکسی به‌روزرسانی کنید، کاراکترهای خاص رمز عبور را URL-encode کنید
گواهی خود امضا شده در زنجیره گواهی پروکسی MITM شرکتی گواهی را تغییر می‌دهد مشخص کردن NODE_EXTRA_CA_CERTS با CA ریشه شرکتی
پروکسی در ترمینال کار می‌کند، اما در Cursor نه Cursor از ترمینال نادرست یا از طریق میانبر بدون محیط اجرا شده است Cursor را با دستور از ترمینال با متغیرهای صادر شده اجرا کنید، یا متغیرها را به طور جهانی در سیستم مشخص کنید
احراز هویت NTLM ناموفق بود کلاینت از احراز هویت NTLM پشتیبانی نمی‌کند یک پروکسی میانی cntlm یا px را بین برنامه و پروکسی شرکتی راه‌اندازی کنید

بررسی اتصال از طریق curl

قبل از اینکه بفهمید چرا Cursor یا Claude Code کار نمی‌کند، اطمینان حاصل کنید که خود پروکسی به طور کلی در دسترس است و ترافیک HTTPS را به درستی پروکسی می‌کند. برای این کار از curl استفاده کنید — این ابزار همان متغیرهای محیطی را می‌خواند و به شما اجازه می‌دهد به سرعت مشکل را بدون راه‌اندازی برنامه‌های سنگین شناسایی کنید.

# بررسی دسترسی پروکسی و احراز هویت
curl -v -x "http://user:[email protected]:8080" https://api.anthropic.com

# بررسی با در نظر گرفتن گواهی شرکتی
curl -v --cacert /etc/ssl/certs/company-root-ca.pem \
  -x "http://user:[email protected]:8080" \
  https://api.anthropic.com

اگر curl به طور موفقیت‌آمیز پاسخ دریافت کند (حتی 401 یا 403 — این طبیعی است، به این معنی است که TLS handshake انجام شده است)، اما Claude Code هنوز متصل نمی‌شود — مشکل در شبکه نیست، بلکه در این است که فرآیند متغیرهای محیطی را نمی‌بیند. اگر curl نیز با خطای گواهی یا تایم اوت مواجه شود — مشکل در سطح شبکه یا پروکسی است و ابزارها هیچ نقشی ندارند.

کی پروکسی خارجی به جای پروکسی شرکتی نیاز است

گاهی اوقات وظیفه محدود به دسترسی از شبکه شرکتی به بیرون نیست. توسعه‌دهندگانی که ادغام‌ها را با API‌های وابسته به جغرافیا آزمایش می‌کنند، رفتار سرویس را از کشورهای مختلف بررسی می‌کنند یا سیاست‌های محدودیت نرخ ارائه‌دهندگان مدل‌ها را اشکال‌زدایی می‌کنند، با این مشکل مواجه می‌شوند که پروکسی شرکتی یک IP شرکتی یکسان برای تمام درخواست‌ها ارائه می‌دهد. در چنین سناریوهایی، راحت است که ترافیک آزمایشی را از طریق پروکسی خارجی به طور موازی با محیط کاری اصلی عبور دهید.

برای جلسات آزمایشی پایدار و طولانی‌مدت با حداقل خطر مسدود شدن به دلیل IP، پروکسی‌های مسکونی مناسب هستند — آن‌ها از آدرس‌های IP واقعی ارائه‌دهندگان خانگی استفاده می‌کنند و به عنوان ترافیک کاربر معمولی به نظر می‌رسند، که در بررسی پاسخ‌های API وابسته به جغرافیا مهم است. اگر نیاز به بازتولید رفتار کلاینت موبایل یا آزمایش سناریوهای حساس به نوع شبکه دارید، باید به پروکسی‌های موبایل فکر کنید. و برای آزمایش‌های موازی انبوه درخواست‌ها به API‌های عمومی، جایی که سرعت و هزینه ترافیک مهم است و نه پنهان شدن به عنوان یک کاربر معمولی، معمولاً کافی است از پروکسی‌های مرکز داده استفاده کنید.

مهم است: این پروکسی خارجی به همین ترتیب از طریق متغیرهای HTTPS_PROXY/HTTP_PROXY تنظیم می‌شود، اما برای محیط آزمایشی یا پروفایل ترمینال جداگانه، تا ترافیک اصلی کاری را با ترافیک پروکسی شرکتی مخلوط نکنید. اگر سیاست شرکتی نیاز دارد که تمام ترافیک شرکت فقط از طریق پروکسی داخلی عبور کند، استفاده از پروکسی خارجی باید با IT/Security هماهنگ شود — بسیاری از شرکت‌ها به طور مستقیم دور زدن دروازه شرکتی بدون مجوز را ممنوع می‌کنند.

چک‌لیست تنظیمات

  • هر دو متغیر صادر شده‌اند: HTTP_PROXY و HTTPS_PROXY (در هر دو حالت)
  • در NO_PROXY دامنه‌های داخلی و localhost ذکر شده‌اند
  • کاراکترهای خاص در رمز عبور URL-encode شده‌اند
  • برنامه به طور کامل راه‌اندازی مجدد شده است، نه فقط پنجره کوچک/بزرگ شده است
  • درخواست curl با همان متغیرها که در برنامه است، بررسی شده است
  • اگر بازرسی MITM SSL وجود دارد — NODE_EXTRA_CA_CERTS با CA ریشه شرکتی مشخص شده است
  • اگر پروکسی از NTLM استفاده می‌کند — یک cntlm/px میانی در localhost راه‌اندازی شده است
  • برای سناریوهای آزمایشی، پروکسی خارجی در یک پروفایل محیطی جداگانه قرار داده شده است

نتیجه‌گیری

بیشتر مشکلات با Cursor و Claude Code در پشت پروکسی شرکتی به سه چیز محدود می‌شود: متغیرهای محیطی به فرآیند نمی‌رسند، احراز هویت به درستی تنظیم نشده است، یا گواهی MITM شرکتی به فهرست اعتماد اضافه نشده است. با بررسی این سه مورد به ترتیب — از طریق curl, نه به طور مستقیم از طریق خود برنامه — شما ساعت‌ها را در اشکال‌زدایی صرفه‌جویی کرده و به سرعت علت را شناسایی می‌کنید.

اگر وظیفه از محدوده شبکه شرکتی فراتر می‌رود و نیاز دارید رفتار API را از مناطق مختلف یا با انواع IP‌های مختلف آزمایش کنید، پیشنهاد می‌کنیم از پروکسی‌های مسکونی استفاده کنید — آن‌ها ترافیک پایدارتر و کمتر مشکوک برای خدمات خارجی نسبت به آدرس‌های معمولی مرکز داده ارائه می‌دهند.