چگونه یک تونل VPN فعال را از کد روی هر پلتفرمی تشخیص دهیم
آیا تونل وجود دارد، آیا این مقصد از آن عبور میکند، یا طرف دور پاسخ میدهد؟ اینها سه بررسی متفاوت و سه سیگنال متفاوت هستند.
«آیا VPN روشن است؟» در واقع سه پرسش در یک جمله است. اینکه کد شما به کدامیک نیاز دارد نخستین تصمیم است، و همان است که بیشتر پیادهسازیها از آن میگذرند. آیا تونلی روی این دستگاه وجود دارد، آیا ترافیک به این مقصد از آن خارج میشود، یا طرف دور با هویتی که انتظار دارید پاسخ میدهد. ویژگی را انتخاب کنید، سپس سیگنالی را که آن را میسنجد، و در پایان در گزارش بنویسید کدام را واقعاً سنجیدهاید.
سه ویژگی، سه سیگنال
هر کدام در یک خط فشرده شدهاند، سه پرسش سه پاسخ متفاوت دارند. جدول زیر خودِ تصمیم است، نه خلاصهای از آن.
| Property | Signal that answers it | What it still leaves open |
|---|---|---|
| Existence | The platform's own connection state: RAS on Windows, NetworkManager on D-Bus on Linux, scutil on macOS | Tunnels of a type the platform does not manage, which includes most third-party clients |
| Path | A route lookup for the one destination, or a scoped proxy or interface key that names the tunnel | Whether the far end is the peer you trust |
| Identity | An authenticated response from the far end, or a source-address policy applied on the server | Which local interface carried the packets |
سطر آخر را آهسته بخوانید. میزبان خصوصیای که پاسخ میدهد ثابت میکند چیزی پاسخ داده است، نه اینکه پاسخ از تونل آمده باشد، و هیچ چیزی درباره اینکه طرف دیگر کیست نمیگوید. اگر ویژگیای که نیاز دارید مسیر است، مسیر را بسنجید.
وجود: وضعیت خودِ پلتفرم
ویندوز برای پروفایلهای بومی از طریق Remote Access Service API به این پاسخ میدهد. RasEnumConnections فهرست میکند چه چیزی وصل است، RasGetConnectStatus وضعیت یک ورودی را گزارش میدهد، و RasGetLinkStatistics سرعت، شمارندههای بایت و عمر اتصال را میافزاید. محدودیتها خودِ نکتهاند: OpenVPN، WireGuard و کلاینتهای فروشندگان هرگز اتصال RAS ثبت نمیکنند، بنابراین تونل سالمی از آن نوع فهرستی خالی نشان میدهد و کد سادهلوح آن را قطعشده گزارش میکند.
میزکارهای لینوکس همان ویژگی را از طریق NetworkManager روی D-Bus عرضه میکنند، جایی که PropertiesChanged روی شیء اتصال VPN بررسی را به یک رویداد تبدیل میکند و ویژگی State گزارش میدهد چه وقت پیوند به وضعیت متصل میرسد. از یک پوسته، nmcli connection show --active همان اطلاعات را میخواند، و این همان چیزی است که هنگام اشکالزدایی میخواهید. macOS آن فهرست را در چارچوب System Configuration نگه میدارد، با scutil بهعنوان نمای خط فرمانش. هر سه یک اتصال را توصیف میکنند که پلتفرم مدیریت میکند، و هر سه برای تونلی که مدیریت نمیکند ساکت میمانند.
مسیر: بسته واقعاً کجا میرود
تطبیق نام میانبری است که همه اول به آن دست میزنند: رابطها را برشمارید، رشته را با tun، tap، ppp یا ipsec بسنجید و هر تطبیقی را مدرک بگیرید. این یک اکتشافی است، و مجموعه رابطها ممکن است یکسان به نظر برسد، چه چیزی از آن عبور کند و چه نه. بیلدهای قدیمی iOS اینگونه پاسخ میدادند و بعدیها دست کشیدند، چون رابطهای قابل مشاهده دیگر آن دو وضعیت را از هم جدا نمیکردند.
چیزی که جای آن را گرفت واژهنامه پروکسی سیستم است. تا وقتی VPN متصل است، فراخوان تنظیمات پروکسی کلیدهایی محدود به رابطهای مرتبط با تونل برمیگرداند، و وقتی چیزی متصل نیست واژهنامه خالی برمیگردد. این ادعایی ضعیفتر از آنچه به نظر میرسد است، چون باور سیستم به وجود تونل را ثبت میکند نه اینکه کدام مقصد از آن استفاده میکند.
اندروید نسخه خودش از این تله را دارد: پخش vpn.connectivity در برخی بیلدها به گیرندههای اعلامشده در مانیفست میرسد و در برخی دیگر به گیرندههای ثبتشده در زمان اجرا. آن را بهترین تلاش بدانید و یک کاوشگر مستقیم پشت آن نگه دارید.
وقتی مقصد مهم است، از جدول مسیریابی بپرسید نه از فهرست آداپتورها. اکتشافیهای دروازه پیشفرض روی ماشینهای چندشبکهای و روی تونلهایی که دروازه خودشان را نصب میکنند میشکنند.
هویت: طرف دور را بکاوید
حلقهای که هر چند ثانیه یک پژواک ICMP به طرف دور میفرستد ارزانترین بررسی از این نوع است، و در جهتی سودمند شکست میخورد. آن را به نشانی بگیرید که فقط داخل شبکه خصوصی وجود دارد، چون نشانی عمومی از هر پیوند بالارونده فعالی پاسخ میدهد و هیچ چیز را ثابت نمیکند. جایی که ICMP فیلتر میشود، یک اتصال کوتاه TCP به درگاه سرویس همان کار را میکند.
بررسی سمت سرور دقیقاً یک سیگنال در دسترس دارد: نشانی مبدأ روی اتصال. نگهداری فهرست بازهها کار نگهداری است، و نمیتواند تونل را از هر شبکه دیگری که تصادفاً همان بلوک را به کار میبرد جدا کند.
سیاست درشت میتواند با این کنار بیاید. هویت نمیتواند، پس کلاینت را احراز هویت کنید نه اینکه به جایی که بستههایش به نظر میرسد از آن میآید اعتماد کنید.
دسته را ثبت کنید، نه حکم را
دستههای شکست را در گزارش جدا نگه دارید: هیچ رابطی نیست، رابط هست اما مقصد دسترسیناپذیر است، مقصد دسترسیپذیر است اما احراز هویت رد شده است. اینها سه مالک متفاوتاند، و هر یک پژوهش متفاوتی میگشاید.
فروکاستن آنها به یک «VPN قطع است» گزارش را به تیمی میفرستد که نمیتواند درستش کند. دسته خروجی سودمند است؛ حکم همان چیزی است که آن را نادرست میکند.