هیچ‌چیز در سوکت به یاد نمی‌آورد که کدام رابط درخواست را حمل کرده است، بنابراین مسیر پیش‌فرض VPN تمام‌تونل می‌تواند پاسخی را که به WAN تعلق دارد بگیرد. سرویس رابط ورودی را نادیده نمی‌گیرد؛ Linux پاسخ تولیدشده به‌صورت محلی را بر اساس مقصد و خط‌مشی مبدأ مسیریابی می‌کند. یک قاعده مبتنی بر مبدأ می‌تواند به‌جای آن فقط پاسخ‌های سرویس را از طریق جدول کامل WAN بفرستد و خروج معمولی را روی تونل بگذارد. پورت باز می‌ماند در حالی که پاسخ از مسیر نادرست خارج می‌شود، و به همین دلیل نشانه یک‌طرفه به نظر می‌رسد.

تصور نادرست: پاسخ‌ها از رابطی پیروی می‌کنند که از آن آمده‌اند

منطقی به نظر می‌رسد که بسته‌ای که روی eth0 می‌رسد باید از eth0 خارج شود. فیلترهای بسته بدون حالت را می‌توان این‌طور نوشت، و tcpdump در سمت ورودی درخواست را دقیقاً همان‌جایی نشان می‌دهد که انتظار می‌رود. مسیریابی برای ترافیکی که خود میزبان تولید می‌کند این‌طور کار نمی‌کند.

وقتی سرویس اتصال را می‌پذیرد، پاسخش یک بسته تازه تولیدشده به‌صورت محلی است. هسته قواعد مسیریابی را برای مقصد و مبدأ پاسخ بررسی می‌کند، و مسیر پیش‌فرض VPN پاسخی کاملاً معتبر است. هیچ‌چیز در سوکت به یاد نمی‌آورد که کدام رابط درخواست را حمل کرده است.

به همین دلیل نشانه یک‌طرفه به نظر می‌رسد: درخواست‌ها می‌رسند، پاسخ‌ها ناپدید می‌شوند. به همین دلیل افزودن یک قاعده فایروال برای پورت ورودی هم چیزی را تغییر نمی‌دهد. بسته در مسیر ورود مسدود نمی‌شود؛ در مسیر خروج به جای دیگری مسیریابی می‌شود. پاسخ را با جستجوی مشخص‌شده بر پایه مبدأ دنبال کنید و انحراف آشکار می‌شود.

آنچه هسته واقعاً مسیریابی می‌کند: آدرس مبدأ

دسته‌ای که نیاز دارید آدرس محلی است که سرویس برای پاسخ‌ها به کار می‌برد. روی میزبانی با آدرس نمونه eth0 برابر 192.0.2.10/24 و دروازه 192.0.2.1، آن آدرس روی رابط وجود دارد. در یک VM ابری ممکن است آدرس عمومی در بالادست ترجمه شده و در مهمان غایب باشد، پس از آدرسی استفاده کنید که میزبان واقعاً دارد.

پیش از رزرو شماره جدول یا اولویت قاعده، وضعیت فعلی را بررسی کنید. قواعد خط‌مشی موجود می‌توانند قاعده جدید را تحت‌الشعاع قرار دهند، و یک جدول قدیمی با همان شماره ممکن است از قبل مسیرهای نامرتبط داشته باشد:

ip -4 addr show dev eth0
ip -4 rule show
ip -4 route show table all

سپس جدولی را بر پایه مبدأ انتخاب کنید. این قاعده با پاسخ‌هایی مطابقت دارد که از قبل 192.0.2.10 را حمل می‌کنند، یعنی دقیقاً همان ترافیک پایان‌یافته به‌صورت محلی که می‌خواهید استثنا کنید. ترافیک فوروارد‌شده و بسته‌های آدرس‌های محلی دیگر مطابقت ندارند.

یک جدول بازگشت کامل بسازید، نه نیمی از یک مسیر پیش‌فرض

جدولی که فقط یک مسیر پیش‌فرض دارد کافی نیست. هسته هنوز باید دروازه را حل کند، و این حل به پیشوند متصل در همان جدول نیاز دارد. جدولی که آن پیشوند را ندارد حتی وقتی مسیر پیش‌فرضش درست به نظر می‌رسد در حل دروازه شکست می‌خورد. هر دو را اضافه کنید و سپس قاعده مبدأ را به جدول نشانه بگیرید:

ip -4 route add table 100 192.0.2.0/24 dev eth0 src 192.0.2.10
ip -4 route add table 100 default via 192.0.2.1 dev eth0
ip -4 rule add priority 1000 from 192.0.2.10/32 lookup 100

از پیشوند و دروازه واقعی استفاده کنید نه اینکه مثال را کپی کنید. یک رابط ابری که به‌صورت /32 با دروازه روی لینک پیکربندی شده به مسیر متصل متفاوتی نیاز دارد، و جدولی که از پیشوند اشتباه ساخته شده در اولین گام شکست می‌خورد. ویژگی src مبدأ ترجیحی آن مسیر را بیان می‌کند؛ جایگزین قاعده مبدأ نمی‌شود.

ترتیب هم مهم است. قاعده‌ای گسترده با شماره اولویت کمتر اول ارزیابی می‌شود، بنابراین باید پیش از هر قاعده‌ای که این ترافیک را به جدول اصلی برگرداند به قاعده مبدأ رسید. اولویت‌ها را پس از افزودن با ip rule show بررسی کنید، نه فقط هنگام بوت.

با جستجوی مشخص‌شده بر پایه مبدأ تأیید کنید

از هسته بخواهید یک مقصد آزمایشی را از آدرس سرویس مسیریابی کند. پاسخ باید eth0 و دروازه WAN را نام ببرد، نه تونل را:

ip -4 route get 198.51.100.25 from 192.0.2.10

سپس یک اتصال مجاز تازه برقرار کنید و هر دو جهت را تماشا کنید. جستجویی که جدول درست را انتخاب می‌کند در حالی که اتصال زنده هنوز شکست می‌خورد به فیلتر مسیر معکوس یا یک قاعده فایروال اشاره دارد، نه به جدول. پیش از غیرفعال کردن هر چیزی به‌صورت سراسری آن کنترل‌ها را بررسی کنید.

مسیرها و قاعده نهایی را زیر مدیر شبکه‌ای قرار دهید که مالک رابط است. تغییر آدرس، تمدید DHCP و اتصال مجدد VPN همگی وضعیت هسته را بازنویسی می‌کنند، و قاعده‌ای که دستی افزوده شده پس از رویداد بعدی ناپدید می‌شود یا به دروازه‌ای کهنه اشاره می‌کند.

کجا این استثنا متوقف می‌شود

این قاعده ترافیک پایان‌یافته به‌صورت محلی از یک آدرس مبدأ را استثنا می‌کند. پورت‌های منتشرشده توسط Docker، DNAT یا سرویس‌های فوروارد‌شده از طریق میزبان را پوشش نمی‌دهد، زیرا آن بسته‌ها به‌عنوان ترافیک فوروارد مسیریابی می‌شوند و هرگز مبدأ محلی میزبان را به همان شکل حمل نمی‌کنند. چنین طرح‌هایی معمولاً به یک نشانه که در ورودی گذاشته می‌شود و قاعده‌ای که با آن نشانه مطابقت دارد نیاز دارند.

همچنین باعث نمی‌شود آدرس عمومی میزبان روی رابط ظاهر شود. وقتی یک NAT بالادست مالک آن آدرس است، پاسخ باید همچنان از مسیری خارج شود که آن NAT انتظار دارد، و به همین دلیل جدول WAN باید دروازه و پیشوند اصلی را منعکس کند نه یک بازه عمومی حدس‌زده‌شده.

استثنا را با شماره جدول، اولویت قاعده و آدرس مبدأ دقیق مستند نگه دارید. تغییر بعدی در VPN یا رابط می‌تواند بی‌صدا آن را بشکند، و یادداشتی که سه مقدار را نام می‌برد سریع‌تر بررسی می‌شود تا دوباره کشف نشانه از گزارش مشتری.

اگر سرویس پس از موفقیت جستجوی مشخص‌شده بر پایه مبدأ هنوز از مسیر نادرست پاسخ می‌دهد، آدرس مبدأ سوکت زنده را با آنچه در قاعده است مقایسه کنید. سرویسی که به یک آدرس عام مقید شده می‌تواند مبدأی متفاوت از آدرسی که آزموده‌اید انتخاب کند، و همین ناهمخوانی شکاف باقی‌مانده است.

مقالات مرتبط