تصور کنید یک عامل (Agent) را در شبکه داخلی یک شرکت مستقر کردهاید و ناگهان ارتباطش قطع میشود؛ نه لاگی از timeout میبینید و نه خطای اتصال، فقط سکوتی مطلق. طبق راهنمای فنی منتشر شده در dev.to در ۲۹ جولای ۲۰۲۶، این وضعیت بهندرت یک باگ کدنویسی است و بیشتر زمانی رخ میدهد که یک عدم تطابق در معماری شبکه وجود دارد؛ جایی که عامل تصور میکند در یک اینترنت مسطح و آزاد است، اما شرکت فیلترینگ سختگیرانهٔ خروجی (Egress Filtering) را اعمال کرده است. در این حالت، عامل نمیتواند به همتایان خود دسترسی پیدا کند، نمیتواند ابزارها را از فروشگاه (Tool Store) فراخوانی کند و حتی نمیتواند به سرور مرکزی (Phone Home) گزارش ارسال کند.
بسیاری از شبکههای سازمانی پشت یک NAT (ترجمهٔt نشانی شبکه) قرار دارند و از پروکسیهای شفاف HTTP/HTTPS استفاده میکنند که ترافیک را شنود و رهگیری میکنند. ترافیک خروجی معمولاً از یک درگاه NAT عبور میکند (که ممکن است از نوع Carrier-Grade باشد) و قوانین فایروال هر چیزی بهجز پورتها و پروتکلهای خاص را مسدود میکند. بازرسی عمیق بستهها (Deep Packet Inspection) اغلب هر ترافیکی را که روی پورت ۴۴۳ نباشد یا دارای TLS معتبر نباشد، حذف میکند. از آنجا که بسیاری از چارچوبهای عاملمحور (Agentic) فرض میکنند اتصال دوطرفه و شنودکنندههای باز (Open Listeners) دارند، در محیطهای سازمانی که هیچ آدرس قابل مسیری ( Routable Address) وجود ندارد، سریعاً شکست میخورند.
راه اندازی یک عامل مدرن در این شبکهها، درست مثل راندن یک ماشین مسابقهای در جادهای است که فقط برای دوچرخهها طراحی شده؛ هرچقدر موتور ماشین قدرتمند باشد، زیرساخت اجازه حرکت نمیدهد. برای حل این مشکل، توسعهدهندگان باید بهصورت سیستماتیک و گامبهگام محدودیتهای شبکه را نقشهبرداری کنند، بدون اینکه نیاز باشد برای تغییر قوانین فایروال به تیم IT درخواست دهند.
گام اول: تایید پروتکل و DNS
شناسایی مانع اصلی با تست دسترسی UDP آغاز میشود. بسیاری از فایروالهای سازمانی تمام ترافیک UDP خروجی را حذف میکنند و فقط TCP روی پورتهای ۸۰، ۴۴۳ و گاهی ۲۲ را میپذیرند. این اتفاق اکثر پروتکلهای همتا-به-همتا (P2P) را که برای NAT hole-punching به UDP نیاز دارند، از کار میاندازد.
- تست دسترسی UDP: شما میتوانید این مورد را با یک دستور ساده bash بررسی کنید:
timeout 5 bash -c 'echo test > /dev/udp/8.8.8.8/53' && echo "UDP egress OK". اگر این دستور متوقف شد یا شکست خورد، به این معناست که UDP کاملاً مسدود است. در این حالت، روشهای مستقیم hole-punching مبتنی بر STUN و تونلهای UDP ساده حذف میشوند و شما به یک Relay یا جایگزین TCP نیاز خواهید داشت.
سپس باید رزولوشن DNS را بررسی کنید. DNSهای سازمانی اغلب فقط رکوردهای داخلی را رزولو میکنند، کوئریهای خارجی را مسدود میکنند یا کاربر را به یک پورتال اسیری (Captive Portal) هدایت میکنند. اگر یک عامل نتواند آدرس همتایان خود را رزولو کند، هرگز نمیتواند متصل شود. برای تست یک رزولور عمومی، از دستور dig +short pilotprotocol.network @8.8.8.8 استفاده کنید و نتیجه را با رزولور سیستم با دستور dig +short pilotprotocol.network مقایسه نمایید. اگر رزولور عمومی جواب داد اما رزولور سیستم نه، شما با DNS intercept یا DNS با افق تقسیمشده (Split-horizon DNS) روبرو هستید. در این شرایط، عامل باید از یک رزولور عمومی یا DoH (DNS over HTTPS) برای دور زدن DNS داخلی استفاده کند.
گام دوم: نقشهبرداری پورت و شناسایی پروکسی
شناسایی پروکسیهای شفاف (Transparent Proxies) حیاتی است زیرا آنها ترافیک TCP/80 و TCP/443 را میربایند. در این حالت، اتصال TLS عامل بهجای سرور مقصد، در خودِ پروکسی terminated (پایان) مییابد. این اتفاق باعث شکست Certificate Pinning، هدرهای WebSocket upgrade و هر پروتکلی میشود که انتظار TCP خام (Raw TCP) را دارد.
- تشخیص پروکسی: یک درخواست
curl -v https://api.github.com 2>&1 | grep -i "proxy\|x-forwarded-for\|via"به یک API شناختهشده میتواند هدرهایViaیاX-Forwarded-Forرا فاش کند. اگر این هدرها ظاهر شوند، عامل شما پشت یک پروکسی شفاف است. در این صورت، عامل باید یا گواهینامه CA پروکسی را به عنوان مورد اعتماد بپذیرد و یا از پروتکلهایی استفاده کند که پروکسی آنها را شنود نمیکند.
برای حذف حدس و گمان، تست پورتهای خروجی را اجرا کنید. یک حلقه تکرار برای تست پورتهای زیر معمولاً فاش میکند که تنها TCP/443 باز است:
- ۸۰، ۴۴۳، ۸۰۸۰، ۸۴۴۳
- ۵۳، ۱۲۳، ۳۴۷۸
- ۴۴۳۳، ۵۱۸۲۰
دستور تست: for port in 80 443 8080 8443 53 123 3478 4433 51820; do timeout 3 bash -c "echo >/dev/tcp/pilotprotocol.network/$port" 2>/dev/null && echo "TCP/$port open" || echo "TCP/$port blocked" done. در این محیطهای سختگیرانه، هر پروتکلی که عامل استفاده میکند باید روی TLS تونل شود.
گام سوم: تحلیل NAT و راهکارهای جایگزین
اگر UDP باز است، یک تست STUN نوع رفتار NAT را برای بررسی امکان hole-punching تعیین میکند. با استفاده از کلاینتی مانند stun-client stun.l.google.com 19302 نتایج معمولاً در چهار دسته قرار میگیرند:
- اینترنت باز (Open Internet): هیچ مشکلی در NAT یا فایروال وجود ندارد و مشکل شبکه سازمانی مطرح نیست.
- Full-cone NAT: قابلیت Hole-punching کار میکند. همتاها میتوانند پس از ارسال اولین بسته خروجی توسط عامل، به او دسترسی یابند.
- Symmetric NAT: قابلیت Hole-punching شکست میخورد. هر مقصد یک پورت منبع متفاوت دریافت میکند. در اینجا استفاده از یک Relay یا تونل مبتنی بر TCP الزامی است.
- مسدود (Blocked): ترافیک UDP به هیچکجا نرسید و هیچ امکانی برای hole-punching وجود ندارد.
وقتی فقط TCP/443 در دسترس است — که رایجترین سناریوی سازمانی است — سه گزینه معماری وجود دارد. اول، استفاده از یک Relay Server روی VPS با IP عمومی که ترافیک را از طریق یک اتصال TCP طولانی-مدت فوروارد میکند (مثلاً با دستور ssh -R 8080:localhost:3000 user@your-relay-server -N). با این حال، هر بایت ترافیک از طریق Relay عبور میکند که باعث ایجاد گلوگاه و یک نقطه شکست واحد (SPOF) میشود.
دوم، شبکههای Overlay مانند Pilot Protocol که STUN و Relay fallback را بهصورت شفاف مدیریت میکنند. عامل یک Daemon کوچک اجرا میکند که اتصالات خروجی را به شبکه برقرار کرده، رمزنگاری را مذاکره میکند و تونل را زنده نگه میدارد. همتاها از طریق یک آدرس مجازی به آن میرسند. این لایه overlay در صورت شکست hole-punching مستقیم، بهطور خودکار Relay fallback را مدیریت میکند، به این معنا که عامل هرگز نیازی به باز کردن پورت ورودی ندارد.
سوم، استفاده از WebSocket روی TLS سادهترین راهکار است اگر هر دو سر اتصال تحت کنترل باشند. از آنجا که WebSocketها روی TCP/443 به عنوان ترافیک استاندارد HTTPS عمل میکنند (مثلاً: const ws = new WebSocket("wss://your-relay.example.com/agent");)، آنها از اکثر فیلترهای سختگیرانه عبور میکنند.
گام چهارم: بررسیهای نهایی اتصال
دسترسی به Relay را از محیط واقعی عامل (نه لپتاپ شخصی) با دستور curl -sI https://your-relay.example.com/health | head -1 بررسی کنید. این دستور باید یک کد ۲۰۰ یا ۲۰۴ برگرداند. این موضوع حیاتی است زیرا شبکههای سازمانی اغلب DNS را سفید (Whitelist) میکنند اما IPهای تصادفی را مسدود میکنند.
علاوه بر این، احراز هویت پروکسی را چک کنید. برخی پروکسیها نیاز به Credentials دارند و در صورت نبود آنها، درخواستها بیصدا شکست میخورند یا پورتال اسیری را برمیگردانند. متغیرهای محیطی زیر را تنظیم کنید:
- `export HTTP_PROXY="http://user:[email protected]:8080"
- `export HTTPS_PROXY="http://user:[email protected]:8080"
در نهایت، mTLS و Certificate Pinning را مدیریت کنید. اگر عامل از TLS متقابل استفاده میکند، شنود گواهینامه توسط پروکسی، دستدادن (handshake) را میشکند. راهکارها عبارتند از:
- نصب گواهینامه CA سازمان در Trust Store عامل.
- استفاده از پروتکلی که روی TCP/443 خام بدون شنود TLS اجرا شود (تونلهای لایه ۳/۴).
- پین کردن گواهینامه Relay در حالی که CA پروکسی به عنوان جایگزین (Fallback) گنجانده شده باشد.
تغییر این رویکرد، یک شکست معماری بنیادی را به یک تسک سادهی پیکربندی تبدیل میکند. با همراستاسازی لایه شبکه عامل با محیط واقعی — بهجای یک محیط ایدهآل — پایداری در سختگیرترین سازمانها تضمین میشود. قبل از نتیجهگیری اینکه یک عامل نمیتواند اجرا شود، چکلیست کامل را بررسی کنید: وضعیت UDP، رزولوشن DNS، تشخیص پروکسی، نقشهبرداری پورت، نتایج STUN، دسترسی به Relay، احراز هویت پروکسی و گواهینامههای CA.
برای کسانی که این عاملها را مقیاسبندی میکنند، چالش بحرانی بعدی، مدیریت سربار تأخیر (Latency Overhead) است که توسط سرورهای Relay و شبکههای Overlay در حلقههای با فرکانس بالای فراخوانی ابزار (Tool-calling loops) ایجاد میشود.




گفتگو