مفاهیمپیشنمایش
ترنسپورتها
نردبون چطور هر بسته را لایهبهلایه پنهان میکند و ترنسپورتی را برمیگزیند که در شبکهی شما کار کند.
نردبون برای شبکههایی ساخته شده که ترافیک را فیلتر، بازرسی و شناسایی میکنند. هر بسته اول با WireGuard رمزنگاری میشود، بعد پنهانسازی میشود و در آخر با یکی از سه ترنسپورت منتقل میشود. حالتی بدون پنهانسازی وجود ندارد.
لایهها
از درون به بیرون:
| لایه | کار آن |
|---|---|
| WireGuard | رمزنگاری سرتاسری بین دستگاههای شما. خود WireGuard هیچ تغییری نکرده است. |
| هدر نردبون | اطلاعات مسیریابی و رله: نسخه، نوع پیام، حد تعداد گام (hop limit)، کلاس ترافیک و شناسهی رله (relay handle). |
| پنهانسازی | همهی لایههای درونی را پنهان میکند و کلیدهایی مستقل از کلیدهای WireGuard دارد. |
| ترنسپورت | حاصل کار را روی شبکه منتقل میکند. |
لایهی پنهانسازی:
- بایتهای ثابت WireGuard را پنهان میکند؛
- اندازهی ثابت پیامهای handshake در WireGuard (۱۴۸ و ۹۲ بایت) را با padding از بین میبرد؛
- پیش از handshake و در زمان بیکاری، مقدار محدودی ترافیک پوششی میفرستد؛
- فقط به handshakeها تأخیر تصادفی کوچکی اضافه میکند، هرگز به دادهها؛
- نسخهدار است تا اگر نسخهی فعلی روزی شناسایی شد، نسخهی تازه سریع منتشر شود.
سه ترنسپورت
به ترتیب اولویت:
| ترنسپورت | چیست | کاربرد |
|---|---|---|
nb-udp | UDP خام | پیشفرض: سریعترین، با کمترین سربار و بدون head-of-line blocking. |
nb-tls | جریان TLS 1.3 با قاببندی بر اساس طول (length-framed) به درِ ورودی یک رله، روی پورتی مخصوص خودش (هیچوقت ۴۴۳ یا ۸۰) | شبکههایی که UDP را کاملاً میبندند. head-of-line blocking را میپذیرد. |
nb-wss | WebSocket روی TLS | وقتی تنها راه خروج یک پروکسی HTTP یا CDN است. بیشترین سربار را دارد. |
روی nb-tls و nb-wss، اتصالهای خود نردبون هر جا سیستم اجازه بدهد (لینوکس، همان جایی که relayها اجرا میشوند) از کنترل ازدحام BBR استفاده میکنند؛ پس loss تصادفی در یک لینک بد، سرعتشان را خیلی کمتر از TCP معمولی پایین میآورد.
روی nb-udp، مسیری که بستههایش بهطور تصادفی گم میشوند تصحیح خطای پیشرو (FEC) میگیرد: دستگاه گیرنده loss را اندازه میگیرد و فقط به اندازهی لازم parity میخواهد (حداکثر نصف حجم داده) تا بستههای گمشده بازسازی شوند و اتصالهای داخل تونل سرعتشان را حفظ کنند. هیچ بستهای منتظر آن نمیماند؛ فقط بستهی گمشده، بعد از بازسازی، کمی دیرتر میرسد. مسیر تمیز اصلاً parity نمیگیرد.
انتخاب ترنسپورت
لازم نیست خودتان ترنسپورت را انتخاب کنید. هر نود:
- تشخیص میدهد کدام ترنسپورتها در شبکهی فعلی کار میکنند و بهترینشان را به کار میگیرد؛
- با هر تغییر شبکه، مثلاً رفتن از Wi-Fi به اینترنت همراه، دوباره بررسی میکند؛
- سربار ترنسپورت را در امتیاز مسیر حساب میکند؛ از کم به زیاد: UDP، TLS و WSS.
اگر ترنسپورت وسط اتصال عوض شود، MTU تونل تغییر نمیکند؛ پس اندازهی بستههایی که برنامههایتان میبینند ثابت میماند.
ترافیک بین نود و سرور کنترل هم از همین ترنسپورتهای پنهانشده عبور میکند و از ترافیک داده قابل تشخیص نیست.
شبکههایی که اتصالِ شروعشده از خودِ دستگاه را قطع میکنند
بعضی شبکهها اتصالهایی را که از جای دیگر شروع شوند راه میدهند، ولی اتصالی را که خودِ دستگاه شروع کند بعد از چند بسته قطع میکنند؛ بعضی هم اتصالِ شروعشده از داخل را به بعضی آدرسها کلاً میبندند. خیلی از دیتاسنترهای ایران همینطورند. دستگاه روی چنین شبکهای خودش این را میفهمد: nardeboon netcheck آن را زیر Flows it starts نشان میدهد و nardeboon status در یک خط میگوید.
از آن به بعد دستگاه هیچوقت خودش به دستگاهی در جای دیگر اتصال شروع نمیکند؛ از طرف مقابل میخواهد شروعش کند، و جواب میدهد:
- همتاها با آن تماس میگیرند. وقتی به همتایی نیاز دارد، با آدرسی که همتاها از آن میبینندش، از طریق سرور کنترل درخواست میکند و همتا به سراغش میآید.
- رلهها با آن تماس میگیرند. رلههای شما، و در پلنهایی که Global Relay دارند Global Relayها، همانجا که هست به آن سلام میکنند؛ پس حتی وقتی کشورش آدرس یک رله را بسته، میتواند از آن رله رد شود.
- سرور کنترل با آن تماس میگیرد. جلسهی خودش را با سرور کنترل دارد که سرور کنترل به آن وصل میکند؛ پس برای مدیریتشدن به هیچ دستگاه دیگری وابسته نیست.
- وقتی راه دیگری ندارد در میزند. بعد از راهاندازی دوباره، یا وقتی هیچ دستگاه دیگری نمیتواند درخواستش را برساند، یک پیام کوتاه میفرستد که شبکه راهش میدهد و طوری رمز شده که فقط همان دستگاه میتوانسته بفرستدش؛ سرور کنترل از همتاها و رلههایش میخواهد با آن تماس بگیرند، و خودش هم به آن زنگ میزند. دستگاهِ تازه هم همینطور درخواست میکند و در همان تماس با auth key خودش وارد میشود.
دو دستگاه روی چنین شبکههایی در یک کشور، مثل همیشه مستقیم به هم وصل میشوند. دستگاه به آدرسی نیاز دارد که طرف مقابل به آن برسد، که سرورِ دیتاسنتر دارد؛ با دستگاهی پشت NATِ اینترنت خانگی یا موبایل نمیشود تماس گرفت، و برای آنها راهی از طریق CDN در برنامه است.
مقاومت در برابر شناسایی فعال
سامانههای فیلترینگ سرورهای VPN را با وصل شدن به آنها و بررسی واکنششان پیدا میکنند. در نردبون، بایتهای اول هر اتصال باید ثابت کنند که فرستنده یک مقدار محرمانه (secret) را میداند و هر اتصال دیگری بیپاسخ میماند:
- روی UDP، سکوت کامل است.
- روی ترنسپورتهای TLS، بازدیدکنندهای که احراز هویت نشده فقط یک وبسایت معمولی میبیند.
- پیامهای ضبطشده را نمیتوان دوباره فرستاد (replay).
- این مقدار محرمانه داخل خود برنامه نیست. مقدار مربوط به control plane همراه auth key دستگاه میآید، یا وقتی کسی اجازهی ورود دستگاه را بدهد؛ و در ورودی هر relay مقدار مخصوص خودش را دارد که فقط دستگاههایی که اجازهی استفاده از آن relay را دارند، از network map امضاشده میگیرند.
جلوگیری از downgrade
ترنسپورتها و نسخههای پنهانسازیای که هر نود پشتیبانی میکند، در نقشهی شبکهی امضاشده (network map) منتشر میشوند. پس از برقراری تونل، دو طرف داخل همان تونل بررسی میکنند که آنچه استفاده میشود با آنچه اعلام شده یکی باشد. اگر یکی نباشد، اتصال را میبندند و رویدادی در گزارش رویدادها ثبت میشود؛ بنابراین هیچکس در میانهی راه نمیتواند بیسروصدا اتصال را به حالت ضعیفتری بکشاند.
بررسی ترنسپورتها با CLI
دستور nardeboon netcheck در چند ثانیه وضعیت شبکهی فعلی را گزارش میکند: نوع NAT، اینکه دستگاه از بیرون کجا دیده میشود، شبکه با اتصالهایی که خودِ دستگاه شروع میکند چه میکند، IPv6، وضعیت تکتک ترنسپورتها، رلههایی که به آنها میرسد و فاصلهشان، port mapping، و اینکه دستگاه با باتری کار میکند، تا بداند کِی کمتر اندازهگیری کند.
$ nardeboon netcheck
NAT type: unknown
Seen from: 203.0.113.40 (by peers)
Flows it starts: cut after a few packets (the network lets in only what others start)
IPv6: no
Port mapping: -
On battery: no
Transports:
nb-udp ok
nb-tls blocked
nb-wss blocked
Relays:
Frankfurt (Global Relay) reaching, 75 ms
am-vps reaching, 78 ms
tr-vps reaching, 41 msدر این نمونه دستگاه روی شبکهای است که اتصالهایی را که خودش شروع میکند قطع میکند: همتاها و رلههایش با آن تماس میگیرند، پس با این حال از nb-udp به همهشان میرسد، و اتصالهای nb-tls خودش، که باید خودش شروعشان کند، قطع میشوند.
برای آزمایش یک همتا روی ترنسپورتی مشخص، گزینهی --transport را به nardeboon ping بدهید:
$ nardeboon ping --transport nb-tls hetzner
pong from hetzner (100.83.20.5): direct 203.0.113.9:47391, nb-tls, 36 msاگر فعلاً هیچ مسیری به همتا کار نکند، nardeboon ping با کد خروج ۱۰ (unreachable) تمام میشود.