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

به درخواستی نگاه کنید که برنامه واقعاً می‌فرستد

پیش از دست زدن به پیکربندی، بگذارید برنامه بگوید چه می‌کند. ثبت یک درخواست با پراکسی صریحاً خاموش و یک آزمون ساده پورت دو خط پایه به شما می‌دهند که مراحل بعدی با آن‌ها مقایسه می‌شوند. اگر درخواست با پراکسی خاموش موفق شود، سه لایه از چهار لایه را تمام کرده‌اید.

env | grep -i proxy            # Linux/macOS
netsh winhttp show proxy       # Windows, machine-wide
curl -sv --noproxy '*' https://svc.internal/
nc -vz svc.internal 8080

دو مورد آخر را با همان مقصد اجرا کنید و ببینید کجا از هم جدا می‌شوند. مرورگری که کار می‌کند به‌علاوه curl که کار می‌کند به‌علاوه برنامه‌ای که کار نمی‌کند، مشکل را به چیزی محدود می‌کند که برنامه اضافه می‌کند: یک پراکسی، یک حامل یا یک اندازه پیام.

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

بیشتر پشته‌های HTTP پیکربندی پراکسی را به‌طور پیش‌فرض از سیستم‌عامل می‌خوانند. کلاینت VPN سازمانی غالباً یکی را به‌عنوان بخشی از نمایه دسترسی خود نصب می‌کند، پس درخواست‌ها از پراکسی‌ای خارج می‌شوند که توسعه‌دهنده هرگز در کد به آن اشاره نکرده است. در .NET هندلر پیش‌فرض از تنظیمات IE/WinHTTP می‌کشد؛ Java مقدار -Dhttp.proxyHost را می‌خواند؛ Node تا زمانی که کتابخانه‌ای آن را اضافه نکند پشتیبانی پراکسی درونی ندارد. شکست به‌ندرت یک رد تمیز است، و به همین دلیل مردم شروع به نگاه کردن به سرور می‌کنند.

آزمون یک درخواست هزینه دارد: پراکسی را صریحاً روی یک هندلر خاموش کنید و مقایسه کنید.

var handler = new HttpClientHandler { UseProxy = false };
using var client = new HttpClient(handler);

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

پورتی که انتخاب کردید همان پورتی نیست که سیاست اجازه می‌دهد

میزبان مسیریابی‌شده یک سرویس مجاز نیست. سیاست سازمانی معمولاً پورت‌های وب خروجی را مجاز می‌کند و بقیه را می‌اندازد، پس سرویسی روی 8080 یا 1883 در دسترس نیست در حالی که 443 خوب کار می‌کند. مرورگر اینجا چیزی را ثابت نمی‌کند: طبق تعریف از 443 استفاده می‌کند.

همان سرویس را پشت 443 منتشر کنید و پیش از درخواست استثنا، با نام به آن برسید. اگر استثنا واقعاً لازم است، آن را به یک محدوده مبدأ و یک مقصد محدود کنید و آن را بخشی از تعریف سرویس بدانید، نه راه‌حل شخصی کسی.

TCP خامی که مسیر بازنشانی می‌کند

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

حامل را عوض کنید، دوباره آزمایش کنید و در همان اجرا چیز دیگری را تغییر ندهید. آن آزمون تک‌متغیره به شما می‌گوید بازنشانی از مسیر آمده یا از سرویس.

اتصال‌هایی که فقط با بارهای بزرگ بسته می‌شوند

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

بار را در لایه برنامه تکه‌تکه کنید. آن را از کار MTU جدا نگه دارید: کاهش اندازه بسته تونل وقتی کمک می‌کند که نشست‌های معمولی TCP روی شمار ثابتی بایت گیر کنند، و برای پیامی که واسطه آن را بیش از حد بزرگ می‌داند کاری نمی‌کند.

چگونه چهار مورد را در یک گذر تشخیص دهیم

سه مشاهده بیشتر موارد را روشن می‌کند. آیا شکست فوراً رخ می‌دهد یا فقط با بدنه بزرگ؟ آیا همان درخواست با پراکسی خاموش موفق می‌شود؟ آیا با تغییر پورت یا حامل نتیجه تغییر می‌کند؟ پاسخ‌ها را پیش از تغییر بعدی بنویسید، چون VPN سازمانی به‌علاوه پراکسی موروثی به‌علاوه مقدار پیش‌فرض برنامه هم‌زمان سه علت محتمل به شما می‌دهند.

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

مقالات مرتبط