نشت WebRTC: چرا با وجود VPN روشن، IP شما دیده میشود
WebRTC برای برقراری تماسهای نظیربهنظیر از یک سرور STUN میپرسد نشانی عمومی شما چیست، و این درخواست اغلب از کنار VPN رد میشود. نشت چطور اتفاق میافتد، چرا آزمایش از داخل چین به سرورهای STUN داخلی نیاز دارد، و خاموش کردن WebRTC چه هزینهای دارد.
7 دقیقه مطالعه · انتشار ۱۹ شهریور ۱۴۰۵
از طریق پروکسی وصل میشوید، یک صفحهٔ نمایش IP باز میکنید و نشانیای در توکیو یا لسآنجلس میبینید. خیالتان راحت میشود. در همان لحظه، JavaScript همان صفحه ممکن است IP عمومی واقعی شما در کشور خودتان را در دست داشته باشد. نه به خاطر یک باگ، بلکه از طریق یک قابلیت کاملاً مشروع مرورگر به نام WebRTC.
WebRTC برای چیست
WebRTC پشتهٔ ارتباط بلادرنگ داخلی مرورگر است. جلسات ویدیویی داخل یک تب، تماسهای تلفنی مرورگری، انتقال فایل نظیربهنظیر در برخی سایتهای اشتراک فایل: همهٔ اینها روی شیء RTCPeerConnection اجرا میشود. برای اینکه دو مرورگر مستقیماً با هم صحبت کنند، هر کدام باید بفهمد نشانیاش از بیرون چه شکلی است. این فرایند کشف، ICE یا Interactive Connectivity Establishment نام دارد.
ICE فهرستی از «کاندیداها» جمع میکند که تقریباً سه نوع دارند:
- کاندیداهای host: نشانیهای واسطهای شبکهٔ خود شما، مثل
192.168.1.23. - کاندیداهای srflx (server-reflexive): مرورگر شما یک بستهٔ UDP به سرور STUN میفرستد و سرور نشانی مبدأی را که دیده برمیگرداند. این همان IP خروجی عمومی شماست.
- کاندیداهای relay: ترافیکی که از یک سرور TURN عبور داده میشود. معمولاً به اعتبارنامه نیاز دارد و به موضوع نشت ربطی ندارد.
نکتهٔ مهم: هر کاندیدا عیناً از طریق رویداد onicecandidate و متن SDP در اختیار اسکریپت صفحه قرار میگیرد. صفحه هیچوقت لازم نیست تماسی را کامل کند. یک RTCPeerConnection بسازید، یک data channel اضافه کنید، createOffer را صدا بزنید، و چند صد میلیثانیه بعد فهرست کاندیداها در یک متغیر JavaScript نشسته است. نه درخواست مجوزی، نه نشانگری.
STUN چیست
STUN یک آینه است. یک بستهٔ UDP برایش میفرستید؛ جواب میدهد «میبینم که از 1.2.3.4:51234 میآیی.» پروتکل بسیار کوچک و بدون حالت است و سرورهای عمومی فراوانی دارد. stun.l.google.com:19302 گوگل معروفترین آنهاست؛ Cloudflare و Twilio هم سرورهای خودشان را دارند.
همین سادگی دقیقاً همان چیزی است که STUN را به نقطهٔ ورود نشت تبدیل میکند.
چرا VPN جلویش را نمیگیرد
بستگی دارد کلاینت فیلترشکن شما چطور ترافیک را در دست میگیرد.
بسیاری از کلاینتها در حالت پروکسی سیستمی کار میکنند: یک پورت محلی SOCKS یا HTTP باز میکنند و تنظیم پروکسی سیستمعامل را به آن اشاره میدهند. درخواستهای HTTP مرورگر مطیعانه از آن عبور میکنند. اما WebRTC بستههای خام UDP میفرستد، و UDP خام هرگز به تنظیم پروکسی مراجعه نمیکند. بسته از واسط شبکهٔ پیشفرض شما خارج میشود و سرور STUN همان IP اینترنت خانگی شما را میبیند.
تونلسازی تفکیکی مبتنی بر قاعده هم همین مشکل را دارد. اگر فقط دامنهها یا محدودههای IP خاصی از پروکسی عبور کنند، سرورهای STUN بهندرت در آن فهرست هستند و در نتیجه اتصال مستقیم میگیرند. پیکربندیهای پروکسی فقط-TCP هم بنا به تعریف، UDP را نشت میدهند.
پروکسی «فقط برای مرورگر»، چه از طریق افزونه و چه با تنظیم پروکسی بهازای هر برنامه، مثل حالت پروکسی سیستمی رفتار میکند.
چیزی که واقعاً جلوی نشت را میگیرد حالت TUN یا «سراسری» است: کلاینت یک واسط شبکهٔ مجازی میسازد و جدول مسیریابی را طوری بازنویسی میکند که هر بسته، مستقل از پروتکل، وارد تونل شود. آن وقت STUN همان IP گرهٔ خروجی را میبیند که HTTP میبیند، و آزمایش نشتی گزارش نمیکند.
بنابراین آزمایش WebRTC چیزی بیشتر از «نشت دارد یا ندارد» به شما میگوید. میگوید ابزار شما واقعاً چه مقدار از ترافیکتان را کنترل میکند.
پنهانسازی mDNS: نشانیهای شبکهٔ داخلی تقریباً دیگر نشت نمیکنند
چند سال پیش WebRTC نشانی خصوصی شبکهٔ داخلی شما را در کاندیداهای host لو میداد. یک سایت میتوانست ببیند روی 192.168.x.x هستید یا 10.x.x.x، و حدس معقولی بزند که در خانهاید یا در اداره. Chrome و Firefox حالا اینها را بهطور پیشفرض با نامهای mDNS جایگزین میکنند، بنابراین کاندیدا به شکل a1b2c3d4-….local دیده میشود، نه یک IP.
این مشکل نشانی خصوصی را حل کرد. کاندیدای srflx، یعنی IP عمومی، پنهان نمیشود، چون hole-punching در ICE واقعاً به آن نیاز دارد. در یک مرورگر امروزی، «نشت WebRTC» عملاً یعنی «نشت IP عمومی».
چرا آزمایش از داخل چین به سرورهای STUN داخلی نیاز دارد
بسیاری از سایتهای آزمایش نشت این را اشتباه انجام میدهند.
فرض کنید صفحهٔ آزمایش فقط از سرور STUN گوگل میپرسد و شما داخل چین با اتصال مستقیم هستید، چه به این دلیل که پروکسی خاموش است و چه به این دلیل که UDP از کنار آن مسیریابی میشود. آن بسته به احتمال زیاد دور ریخته میشود یا مهلتش تمام میشود، هیچ کاندیدایی برنمیگردد، و صفحه با خوشحالی میگوید «نشتی شناسایی نشد». چیزی نشت نکرد چون پروب به هیچجا نرسید، و این با «امن بودن» یکی نیست.
در سمت پروکسیشده عکس این اتفاق میافتد: STUN گوگل از طریق تونل در دسترس است، IP گرهٔ خروجی را برمیگرداند، و همهچیز سازگار به نظر میرسد. مسیر مستقیم هرگز اندازهگیری نشده است.
رویکرد Browserscan این است که یک دسته سرور STUN را همزمان بپرسد: سرورهای خارجی مثل گوگل، Cloudflare و Twilio، بهعلاوهٔ سرورهایی که شرکتهای چینی مثل Xiaomi، QQ و bilibili اداره میکنند. یک سرور STUN داخلی همیشه با اتصال مستقیم از داخل چین در دسترس است، پس اگر UDP شما از تونل فرار کند، آن سرور نشانی واقعی اینترنت خانگی شما را گزارش میدهد. بررسی WebRTC ما همین کار را میکند: سرورهای زیادی بهصورت موازی، مقایسهٔ هر نشانی عمومی برگشتی با IPی که در لایهٔ HTTP دیده شده، و هر ناهمخوانی بهعنوان نشت شمرده میشود.
همین موضوع توضیح میدهد چرا کسی میتواند در یک سایت آزمایش «پاک» و در سایت دیگری «در حال نشت» باشد.
چطور از خودتان محافظت کنید
تقریباً به ترتیب هزینه:
بگذارید ابزار همهچیز را در دست بگیرد. کلاینت را به حالت TUN یا سراسری ببرید و kill switch را روشن کنید تا قطع شدن تونل اتصال را قطع کند، نه اینکه به اتصال مستقیم برگردد. این راهحل واقعی است و هیچ قابلیتی از مرورگر را از شما نمیگیرد.
Firefox. در نوار نشانی about:config را بنویسید، media.peerconnection.enabled را جستجو کنید و آن را روی false بگذارید. WebRTC کاملاً خاموش میشود.
Chrome و Edge. کلید داخلی ندارند. افزونهٔ WebRTC Network Limiter خود گوگل را نصب کنید و گزینهٔ «use only the default public interface» یا «disable non-proxied UDP» را انتخاب کنید. uBlock Origin هم تنظیمی با عنوان «Prevent WebRTC from leaking local IP addresses» دارد.
Safari. کلیدی برای کاربر ندارد؛ باید مشکل را در لایهٔ پروکسی حل کنید.
غیرفعال کردن WebRTC هزینههای واقعی دارد. جلسات مرورگری (Google Meet، نسخهٔ وب Tencent Meeting و مانند آن) ممکن است وصل نشوند یا فقط از طریق relay کار کنند؛ تلفنهای تحت وب، انتقال P2P داخل مرورگر و برخی بازیهای وب هم از کار میافتند. اگر هر روز در تماس هستید، «محدود کردن» انتخاب بهتری از «غیرفعال کردن» است.
پرسشهای متداول
آزمایش نشان میدهد IP عمومی WebRTC من با IP HTTP یکی است. امن هستم؟ در این بررسی خاص، بله: UDP از تونل عبور میکند. اما این چیزی دربارهٔ DNS نمیگوید که مشکل جداگانهای است؛ نشت DNS و پورتهای باز را ببینید.
کاندیداهای من فقط نامهای .local دارند و هیچ IPی در آنها نیست. یعنی چه؟
مرورگر پنهانسازی mDNS را اعمال کرده و هیچ کاندیدای srflx دریافت نکرده است: یا همهٔ سرورهای STUN در دسترس نبودهاند یا یک افزونه WebRTC را محدود میکند. آزمایش در این وضعیت نمیتواند نتیجهای بگیرد، و «بدون نتیجه» به معنای «امن» نیست.
این اتفاق روی گوشی هم میافتد؟ مرورگرهای موبایل هم WebRTC دارند. اما کلاینتهای فیلترشکن موبایل بیشتر بهصورت VPN سیستمی (حالت TUN) اجرا میشوند که بنا به طراحی همهٔ ترافیک را میگیرند، بنابراین نشت در عمل کمتر از دسکتاپ است. کلاینتهای فقط-پروکسی روی iOS همچنان میتوانند نشت داشته باشند.