یک برنامه از طریق WireGuard: اتصال، مسیریابی نیست
متصل کردن یک برنامه به wg0 فقط نشانی مبدأ آن را تعیین میکند. هسته هنوز به جدولی با مسیرهای تونل و قاعدهای نیاز دارد که آن مبدأ را به آنجا بفرستد.
این تنظیم مثل کلیدی برای هر برنامه به نظر میرسد، بنابراین مردم کلاینت را به واسط WireGuard متصل میکنند و انتظار دارند فقط همان کلاینت از تونل استفاده کند. آنچه اتصال واقعاً انجام میدهد انتخاب یک نشانی مبدأ است. سپس هسته مسیری برای مقصد جستوجو میکند، مسیر پیشفرض معمولی را مییابد و بسته را با نشانی تونل پیوستشده از پیوند فیزیکی خارج میکند. تنها مسیری که برای همان نشانی مبدأ انتخاب شده باشد، این قصد را کامل میکند.
این سازوکار دو نیمه دارد: جدول مسیریابی که فقط ترافیک تونل باید از آن استفاده کند، و قاعدهای که مبدأ منطبق را به آنجا میفرستد.
اتصال یک نشانی مبدأ تعیین میکند و نه بیشتر
لینوکس واسط خروج را با جستوجوی مقصد در جدول مسیریابی انتخاب میکند، پس از آنکه قواعد سیاست فرصت یافتند آن جستوجو را تغییر مسیر دهند. قواعد میتوانند بر اساس نشانی مبدأ، نشانه دیوار آتش، واسط ورودی، یک UID یا حتی یک درگاه انتخاب کنند؛ هر کدام راه دیگری برای گفتن این ترافیک بهجای همه ترافیک است. پیکربندی کلاینت VPN جدولی را انتخاب میکند که مسیرهای تونل را نگه میدارد؛ قاعده انتخاب میکند کدام ترافیک مجاز است به آن مراجعه کند. اتصال بهتنهایی هیچکدام را فراهم نمیکند.
به همین دلیل این شکست اینقدر عجیب به نظر میرسد. برنامه قطعاً از نشانی تونل استفاده میکند، تونل قطعاً فعال است و ترافیک قطعاً از واسط اشتباه خارج میشود. هر جمله درست است و با هم سیستمی را توصیف میکنند که در آن هیچ چیز نشانی را به مسیر وصل نکرده بود.
به تونل جدول خودش را بدهید
wg-quick مسیرها را هر جایی که پروفایل بگوید نصب میکند. افزودن Table = 40 زیر [Interface] آنها را به جدول 40 بهجای جدول اصلی منتقل میکند. واسط را بالا بیاورید و تأیید کنید که رسیدهاند: ip -4 route ls table 40 باید مسیرهای تونل را نشان دهد، و ip -4 route get 10.66.127.142 نشان میدهد هسته اکنون یکی از آنها را چگونه حل میکند. با قرار گرفتن مسیرها در جدول خودشان، جدول اصلی برای همه چیز دیگر کار میکند.
همین کار را برای IPv6 انجام دهید، نه با تطبیق یک پیشوند گسترده. ip -6 rule add from fd00::2/128 lookup 40 یک نشانی را ثابت میکند؛ fc00::/8 ممکن است با واسطهای دیگر روی میزبان برخورد کند و قاعدهای بسازد که بیش از حد موردنظر منطبق شود.
قاعده مبدأ را اضافه کنید و شمارندهها را ببینید
سپس دو نیمه را به هم وصل کنید: ip -4 rule add from 10.66.127.142/32 lookup 40، با همان نشانی که به واسط WireGuard پیوست شده است. هر دو قاعده را در PostUp بگذارید تا اتصال دوباره آنها را بازگرداند. با یک درخواست واقعی تأیید کنید نه با یک تنظیم: ip route get 1.1.1.1 from 10.66.127.142 باید دستگاه تونل را نام ببرد، و curl --interface wg0 ifconfig.me باید نشانی تونل را گزارش کند نه نشانی خانه.
وقتی هنوز شکست میخورد، ip -s rule را بخوانید. قاعدهای که وجود دارد اما هرگز منطبق نشده شمارندههای صفر نشان میدهد و همین یک قاعده اشتباه را از نبودن قاعده تشخیص میدهد. همان یک دستور کلی حدس و گمان را درباره اینکه آیا برنامه تنظیم واسط خود را نادیده گرفته است ذخیره میکند.
حالت معکوس: SSH را بیرون از تونل نگه دارید
مشکل مخالف هم به همان اندازه رایج است: wg-quick صاحب مسیر پیشفرض است و نشست SSH به سرور در میانه نشست قطع میشود. قواعدش در شماره اولویت پایینی قرار دارند، بنابراین یک استثنا باید پیش از آنها ارزیابی شود. ip rule add dport 22 ipproto tcp table main priority 123 این کار را در iproute2 تازه انجام میدهد؛ جایی که انتخابگر در دسترس نیست، جریان را در nftables علامت بزنید و بهجای آن نشانه را تطبیق دهید.
مسیر پاسخ را هم بررسی کنید. نشست SSH که برقرار میشود و بعد ساکت میماند معمولاً مسیریابی نامتقارن دارد: یک جهت از تونل بیرون میرود و جهت دیگر از واسط فیزیکی. ip route get برای نشانی سرور میگوید پاسخ از کدام راه میرود.
شماره جدول، قاعده مبدأ و استثنا را در خود پروفایل ثبت کنید. هر سه به یک طراحی تعلق دارند و با هم ویرایش خواهند شد.