تونل کامل WireGuard: AllowedIPs 0.0.0.0/0 کافی نیست
0.0.0.0/0 و ::/0 فقط انتخاب میکنند که همتا چه چیزی را حمل کند. مدیر کلاینت، ارسال به دروازه، DNS و سیاست خطا هنوز باید پیکربندی شوند.
قرار دادن 0.0.0.0/0, ::/0 در AllowedIPs یک همتا همان گامی است که همه به یاد میآورند، و تنها تعیین میکند که همتا اجازه دارد چه ترافیکی را حمل کند. این پیشوندها هیچ مسیری نمیسازند، در سمت مقابل چیزی را ارسال نمیکنند و resolver هر برنامه را دقیقاً همانجا که بود رها میکنند. چهار چیز جداگانه باید همزمان برقرار باشد تا یک تونل کامل واقعاً کامل باشد، و بهتر است آنها را به ترتیب زیر بررسی کنید، چون بررسی بعدی نمیتواند بررسی قبلی را نجات دهد. هر بررسی زیر واقعیتی است که میتوانید از یک ماشین بخوانید، نه تنظیمی که امیدوارید اعمال شده باشد.
پیشوند همتا چه چیزی را انتخاب میکند و چه چیزی را نه
AllowedIPs هم انتخابکننده است و هم مجوزدهنده. به سمت محلی میگوید کدام مقصدها را میتوان به این همتا فرستاد، و به سمت گیرنده میگوید این همتا کدام نشانیهای مبدأ را میتواند ارائه کند. تمام کار همین است. هیچچیز در این توصیف مسیری روی میزبان نمیسازد، ارسال در سمت دور را فعال نمیکند و به حل نام دست نمیزند.
به همین دلیل است که یک پیکربندی میتواند کامل به نظر برسد و مثل تونل تقسیمشده رفتار کند. پیشوند میگوید که همتا همه چیز را میپذیرد؛ جدول مسیریابی میزبان تعیین میکند که واقعاً چه چیزی به آنجا میرسد، و دروازه تعیین میکند که آیا چیزی خارج میشود. هیچیک از این سه تصمیم در بخش همتا زندگی نمیکند.
مسیریابی کلاینت، نه فقط فهرست همتاها
مدیرهایی مانند wg-quick جدول مسیریابی میزبان را به جای شما برنامهریزی میکنند، و به همین دلیل دو فایل پیکربندی یکسان بسته به اینکه رابط چگونه بالا آمده باشد رفتار متفاوتی دارند. یک پروفایل کمینه آنقدر کوتاه است که یکجا خوانده شود:
[Interface]
Address = 10.8.0.2/32
DNS = 10.8.0.1
[Peer]
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = vpn.example.net:51820
دو جزئیات کار را انجام میدهند. فیلد Address یک پیشوند میزبان تنهاست، نه زیرشبکهای که کلاینت فکر میکند مالک آن است، و این مدیر است که AllowedIPs پیشفرض را به یک مسیر پیشفرض واقعی تبدیل میکند. همان فایل را با ip link و wg setconf بالا بیاورید و هیچ مسیری ظاهر نمیشود، که شبیه تونل خراب است و در واقع تونلی سالم است که مرحله مسیریابی از آن حذف شده. راهنمای wg-quick مسیریابی و Table رفتاری را که این مدیرها اضافه میکنند مستند میکند.
نتیجه را بخوانید نه فایل را: ip route get 1.1.1.1 باید رابط تونل را نام ببرد، و wg show باید یک handshake تازه با شمارنده انتقال متحرک گزارش کند. handshake بدون مسیر یعنی مدیر هرگز اجرا نشده، و ویرایش دوباره پروفایل آن را درست نمیکند. رابط را همانطور که کاربر بالا میآورد بالا بیاورید، وگرنه آزمون به جای استقرار، shell شما را میسنجد.
نگه داشتن نقطه پایانی بیرون از تونل
یک تونل کامل هر مقصدی را میگیرد، از جمله مقصدی که برای وجود داشتن باید با آن صحبت کند. مدیرها این را با افزودن یک مسیر میزبان برای نقطه پایانی از طریق دروازه اصلی حل میکنند، و به همین دلیل یک پیکربندی درست تقریباً همیشه یک استثنای عمدی دارد. اعمال نیمی از پیکربندی با یک مدیر و نیم دیگر با دست، راه معمول گم شدن این استثناست.
اگر نقطه پایانی نام میزبانی باشد که به چند نشانی یا به خانوادهای که شما حمل نمیکنید حل شود، استثنا بد کهنه میشود و تونل میتواند پس از اتصال دوبارهای که عادی به نظر میرسید شکست بخورد. نقطه پایانی را به نشانی که کنترل میکنید سنجاق کنید، یا تأیید کنید که مدیر آن را دوباره ارزیابی میکند، و پس از هر تغییر شبکه مسیر میزبان را دوباره بخوانید.
همین سازوکار توضیح میدهد که چرا یک تونل کامل و یک دروازه اسیر با هم میجنگند. دروازه انتظار دارد ترافیکی را رهگیری کند که تونل شما اکنون میگیرد، پس در شبکههای هتل و فرودگاه تونل را بعد از ورود به دروازه بالا میآورید، هرگز پیش از آن.
ارسال و مسیر بازگشت روی دروازه
روی دروازه، ارسال را برای خانوادهای که حمل میکنید فعال کنید، هنگام ترجمه زنجیره forward را در هر دو جهت اجازه دهید، و مسیر بازگشت را با یک جستوجوی مخصوص مبدأ تأیید کنید. هیچیک از اینها از یک handshake موفق نتیجه نمیشود، چون handshake فقط ثابت میکند که دو همتا میتوانند UDP مبادله کنند. درباره اینکه بعداً با بسته کپسولزداییشده چه میشود چیزی نمیگوید.
sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding
ip route get 1.1.1.1 from 10.8.0.2
جستوجو روی دروازه اجرا میشود نه روی کلاینت، وگرنه جدول مسیریابی دیگری را میخوانید. اگر رابط اشتباه را نام ببرد، یا گزارش کند که مسیری نیست، آنگاه هیچ تغییری در سمت کلاینت خروجی اینترنت ایجاد نمیکند. وقتی دروازه نشانی کلاینتها را در مسیر خروج ترجمه میکند، پاسخ به همان وضعیت ترجمه بستگی دارد، پس قاعده باید برای هر دو جهت جریان وجود داشته باشد و نه فقط جهت خروجی.
DNS و وضعیت شکست، جداگانه آزمودهشده
خود پروتکل resolver هیچ برنامهای را پیکربندی نمیکند. wg-quick خط DNS را از طریق یکپارچگی resolver توزیع اعمال میکند، کانتینرها و مرورگرهایی که پشته خودشان را دارند ممکن است آن را نادیده بگیرند، و بنابراین یک نام میتواند شکست بخورد در حالی که تونل بستهها را بیعیب حمل میکند. با نام میزبان آزمون کنید نه با نشانی، و به جای فرض اینکه سرور پروفایل پاسخ داده، بنویسید کدام سرور پاسخ داد.
خانوادههای نشانی آزمون جداگانهای با پاسخ جداگانه هستند. مسیر پیشفرض v4 چیزی درباره اینکه اتصال v6 یک برنامه چه میکند نمیگوید، و تونلی که خانواده دوم را بیصدا نشت میدهد بدتر از تونلی است که بلند شکست میخورد. نامی را از طریق هر خانواده بپرسید، رابطی را که هر درخواست استفاده کرده بخوانید، و شمارندههای ترجمه را قبل و بعد بررسی کنید، چون قاعدهای که با هیچ چیز مطابقت ندارد دقیقاً مثل قاعدهای است که غایب است.
در پایان، وضعیتی را که هنگام توقف تونل میخواهید آزمون کنید. یک تونل کامل باید برای ترافیکی که ادعا میکند بسته شکست بخورد: اگر رابط پایین بیاید و برنامهها بیصدا از پیوند فیزیکی ادامه دهند، طراحی یک تونل تقسیمشده با گامهای اضافی است. رفتار شکست مورد نظر را بنویسید، آگاهانه بررسیاش کنید، و با ثبت چهار پاسخ تمام کنید — کدام مدیر رابط را بالا میآورد، کدام مسیر پیشفرض را حمل میکند، چه کسی روی دروازه ارسال و ترجمه میکند، و کدام resolver پاسخ میدهد.