WireGuard تودرتو: پرش میانی نمیتواند به پورت خودش پاسخ دهد
وقتی پرش میانی همه چیز را به یک تونل میفرستد، پاسخها به سرویس ورودی آن از مسیر اشتباه خارج میشوند. قاعدهٔ پورت مبدأ روی رابط این را درست میکند.
سه پرش WireGuard به شبکهای میرسند که نشانی عمومی ندارد، و سپس دستگاه میانی پاسخدادن روی پورتی را که باید روی آن گوش میداد متوقف میکند. تونل به سمت جلو همچنان کار میکند، میزبان دور همچنان پاسخ میدهد، و تنها خود سرور میانی است که از بیرون ساکت شده است. این ترکیب دقیقاً به این دلیل گیجکننده است که خودکرده است: پرش میانی از جدول مسیریابی خودش پیروی میکند، و جدول پاسخهای آن را به سمت اشتباه میفرستد.
زنجیرهای که کار میکند تا زمانی که با جعبهٔ میانی حرف بزنید
یک زنجیرهٔ نمونه بگیرید: کارخواه A روی UDP 500 به سرور B میرسد، و B روی UDP 500 به سرور C میرسد. C ترافیک را فقط از نشانی تنها همتای خود میپذیرد، که آن را یک برگ میکند و رفتارش را ساده نگه میدارد. B برگ نیست، و همهٔ چیز جالب این خرابی همانجا رخ میدهد.
این تمایز مهم است چون نقش برگ و میانی در جهتهای مخالف میکشند. یک برگ میتواند همه چیز را بیپیامد به یک تونل بفرستد، چون چیز دیگری به آن وابسته نیست. پرش میانی همزمان نقطهٔ پایانی برای کارخواهها و کارخواهی به سمت دور است، و این دو کار مسیریابی متفاوتی میخواهند.
چرا پاسخ از تونل خارج میشود
روی B، رابط رو به C همراه با مسیر پیشفرض متناظر، AllowedIPs = 0.0.0.0/0 را حمل میکند. بنابراین هر بستهای که B ایجاد میکند به آن تونل میرود، مگر اینکه چیزی مشخصتر اولویت بگیرد.
بستهای از A که به B نشانه رفته میرسد و پذیرفته میشود، چون B مقصد است و تحویل محلی اول اتفاق میافتد. پاسخ یک بستهٔ کاملاً تازه و محلیتولیدشده به نشانی عمومی A است، و آن مقصد با مسیر پیشفرض به داخل تونل مطابقت دارد. C آن را دریافت میکند، مالک آن نشانی نیست و آن را دور میریزد.
نشانه شبیه مشکل دیوار آتش یا ناسازگاری کلید خوانده میشود، و هیچکدام اینجا درست نیست. یک ضبط روی تونل به سمت C نشان میدهد پاسخها در جهت اشتباه میروند. همان یک مشاهده بیش از هر مقدار خواندن پیکربندی وقت صرفهجویی میکند، پس پیش از شروع تغییر کلیدها آن را بنویسید. هر کس ضبط را ندیده باشد گمان میکند خود تونل خراب است.
تعمیر باریک: قواعد سیاستی که با پورت مبدأ مطابقت دارند
پاسخها از سوکت شنوای B با پورت مبدأ 500 خارج میشوند. یک قاعدهٔ سیاستی میتواند با آن مطابقت کند و این بستهها را به جدول معمولی بازگرداند:
ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101
قواعد سیاستی به ترتیب اولویت بررسی میشوند و جدول اصلی روی 32766 قرار دارد، پس قاعدهای روی 100 پیش از آنکه مسیر پیشفرض تونل حرفی بزند پرسیده میشود. برای هر پورتی که باید از بیرون در دسترس بماند یک ورودی اضافه کنید و نه بیشتر، تا ترافیک هدایتشده همان تونلی را که برایش ساخته شده ادامه دهد.
مرز این ترفند را بدانید. انتخابگر sport با بستههای محلیتولیدشده مطابقت دارد، که دقیقاً حالت پاسخ را پوشش میدهد و عمداً ترافیکی را که B فقط برای دیگری هدایت میکند پوشش نمیدهد. سرویسی که پشت B میزبانی میشود هنوز پاسخ خودش را لازم دارد، و وانمود کردن به خلاف آن راهحلی میسازد که برای سرویس اول کار میکند و برای دوم شکست میخورد.
به قاعده یک مالک بدهید
قاعدهای که در خط فرمان تایپ شود دفعهٔ بعد که رابط بازسازی شود ناپدید میشود. در یک پیکربندی WireGuard آن را جایی بگذارید که رابط ساخته و حذف میشود:
PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100
اگر NetworkManager، قلاب یک توزیع یا نقطهٔ ورود یک کانتینر مالک رابط باشد، این جفت به همان مالک تعلق دارد نه به پروندهای که دستی ویرایش شده است. قواعد مؤثر را پس از اتصال دوباره بررسی کنید، نه فقط پس از نخستین شروع، چون نخستین شروع همان حالتی است که همیشه کار میکند.
گزینهها را صادقانه مقایسه کنید
قاعدهٔ پورت مبدأ یکی از چهار راه خروج است و باریکترین آنهاست. این مزیت را دارد که اصلاً به سیاست تونل دست نمیزند، و به همین دلیل معمولاً از تغییرات بعدی جان سالم به در میبرد. تعمیرهای باریک وقتی از کار میافتند هم با صدای بلند شکست میخورند، در حالی که یک استثنای گسترده مدتها پس از ناپدید شدن دلیلش بیصدا به کار ادامه میدهد. وقتی دو سال بعد کس دیگری مالک جعبه باشد، این تفاوت از زیبایی مهمتر است.
| Approach | What it costs | Where it breaks |
|---|---|---|
| Source-port policy rule | One rule per exposed port | Anything B forwards rather than originates |
| Destination exception route | A route pinned to specific client addresses | Clients whose address changes |
| Stop full-tunnelling on B | Loses the catch-all path toward C | Designs that depend on it |
| Split into two tunnels | More interfaces and more policy | Nothing, at the cost of complexity |
پس از انتخاب از هر دو سر بررسی کنید. از A، اتصالی به پورت B آغاز کنید و مدتی آن را مشغول نگه دارید. روی B، هسته را وادار کنید مسیر پاسخ را با چیزی مانند ip route get <address-of-A> sport 500 توجیه کند، و تأیید کنید که رابط WAN را نام میبرد نه تونل را. پس از آن بررسی کنید که چیزی پشت C هنوز از طریق زنجیره پاسخ میدهد، که ثابت میکند استثنا باریک مانده و به میانبر تبدیل نشده است. سرانجام، پورتها را در یادداشتهای طراحی ثبت کنید، وگرنه اپراتور بعدی این را روی سرویس دیگری دوباره کشف میکند.