خروج جداگانه: استخر VPN روی usb0، ترافیک دروازه روی eth0
کلاینتهای VPN فورواردشده میتوانند از usb0 خارج شوند، در حالی که دروازه مسیر پیشفرض eth0 خود را نگه میدارد. یک جدول انتخابشده کامل بسازید، سپس کاری کنید که شکست ببندد نه اینکه نشت کند.
کلاینتها متصل میشوند و احراز هویت میکنند، سپس ترافیکشان از پیوند بالادستی اشتباه خارج میشود، چون تنها مسیر پیشفرض روی دستگاه به خود دروازه تعلق دارد. جایگزینی آن مسیر پیشفرض بهروزرسانیهای خود دستگاه و دسترسی مدیریت را میشکند، پس انتخاب باید باریکتر از «همه ترافیک» باشد. شکل قابلاجرا یک قاعده سیاست است که بر نشانی مبدأ داخلی استخر کلاینتها کلید میخورد و به جدول مسیریابی دومی اشاره میکند که مالک WAN جایگزین است. از آنجا به بعد، فهرست بازبینی درباره کامل بودن و رفتار در شکست است، نه درباره خود قاعده.
تأیید کنید که نشانی مبدأ تا تصمیم مسیریابی باقی میماند
قاعده سیاستی که با یک محدوده مبدأ مطابقت دارد تنها زمانی فعال میشود که بسته در زمان جستوجو هنوز آن مبدأ را حمل کند. ترافیک فورواردشده کلاینتها چنین میکند، تا زمانی که چیزی در بالادست آن را پیش از مسیریابی بازنویسی نکرده باشد. ترافیکی که خود دروازه تولید میکند چنین نمیکند، و دقیقاً به همین دلیل مسیر پیشفرض خود دروازه میتواند همانجا بماند.
اینجاست که آزمونهای محلی گمراه میکنند. اجرای curl روی دروازه یک جریان محلی با نشانی دروازه است، پس جدول اصلی را برمیدارد و چیزی درباره مسیر کلاینت اثبات نمیکند. از یک کلاینت متصل آزمون کنید، یا ترافیکی با مبدأیی تولید کنید که واقعاً به استخر تعلق دارد.
با نوشتن مقادیر واقعی شروع کنید: پیشوند استخر، رابط تونلی که آن را حمل میکند، نشانی و گام بعدی WAN دوم، و شماره جدولی که قصد استفاده از آن را دارید. پیش از افزودن قواعد جدید، قواعد قدیمی هر تلاش پیشین را پاک کنید، چون قواعد تکراری با اولویتهای مختلف شکستهایی تولید میکنند که تصادفی به نظر میرسند.
یک جدول انتخابشده کامل بسازید
جدول یک مسیر پیشفرض بههمراه یک دوست نیست. به اندازه کافی مسیر لازم دارد تا هر جستوجو درونش حل شود، از جمله مسیر متصل برای زیرشبکه WAN تا گام بعدی قابل دسترسی باشد. برای استخر 10.77.0.0/24 روی tun1، نشانی WAN برابر 203.0.113.20/24 با گام بعدی 203.0.113.1، و جدول 600:
ip -4 route replace 203.0.113.0/24 dev usb0 src 203.0.113.20 table 600
ip -4 route replace 10.77.0.0/24 dev tun1 table 600
ip -4 route replace default via 203.0.113.1 dev usb0 table 600
ip -4 rule add priority 1500 from 10.77.0.0/24 lookup 600
قاعده در اولویتی پایینتر از هر قاعده فراگیر موجود قرار میگیرد، پس کلاینتهای مطابق ابتدا به جدول 600 میرسند و هر چیز دیگر به جدول اصلی میافتد. مرجع ip-rule مدل جستوجوی مرتب و نحو انتخابگر را بهطور کامل توصیف میکند.
سپس به آنچه جدول ندارد فکر کنید. مقصدی که فقط در جدول اصلی مسیر دارد، مثل زیرشبکه مدیریت که از eth0 قابل دسترسی است، در جدول 600 پیدا نمیشود و پس از وجود مسیر پیشفرض در آنجا به جدول اصلی بازنمیگردد. اگر آن مسیرها مهماند، آنها را صریحاً به جدول انتخابشده بیفزایید، که معمولاً پاسخ درست برای جدول خروج VPN است.
ترافیک خود شنونده را بیرون از سیاست نگه دارید
شنونده OpenVPN اتصال بیرونی خودش را دارد که از همان پیوند بالادستی که کلاینت به آن رسیده حمل میشود. آن ترافیک باید مسیر بازگشتی را که با آن آمده حفظ کند، و یک قاعده گسترده که نشانی عمومی سرور یا کل رابط تونل را بپوشاند میتواند آن را به جدول جایگزین بکشد. قاعده را به استخر داخلی محدود کنید و به هیچ چیز دیگر.
فیلتر مسیر معکوس هم به همین دلیل ارزش نگاهی دارد. وقتی پاسخها به کلاینتها از usb0 خارج میشوند در حالی که درخواست از پیوند دیگری رسیده، تنظیم سختگیرانه rp_filter میتواند بستههایی را که سیاست مسیریابی معتبر میداند بیندازد. پیش از نتیجهگیری درباره شکست قاعده، مقادیر مؤثر sysctl را روی هر دو رابط بررسی کنید.
ترتیب نسبت به هر چیز دیگری روی دستگاه هم مهم است. پلهای Docker، یک VPN دوم و هر قاعده از پیش موجود از تصویر یک ارائهدهنده همه اولویت اضافه میکنند، پس کل فهرست قواعد را بخوانید بهجای آنکه فرض کنید اولویت 100 تنهاست.
فوروارد کردن و ترجمه را با مسیر هماهنگ کنید
مسیریابی یک پیوند بالادستی انتخاب میکند؛ اجازه فوروارد کردن نمیدهد. هسته باید فوروارد IPv4 را فعال داشته باشد و دیوار آتش باید جهت کلاینت به WAN و ترافیک بازگشتی را بپذیرد. یک جدول درست با زنجیره FORWARD که جریان را میاندازد همان نشانه مسیر ناموجود را تولید میکند، بنابراین هر دو در یک گذر بررسی میشوند.
اگر WAN دوم یک استخر خصوصی را به سمت شما مسیریابی نکند، مبدأ را روی همان خروج ترجمه کنید. برای رابطی با نشانی پویا، قاعده باریک masquerade محدود به استخر و رابط انتخاب معمول است:
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -o usb0 -j MASQUERADE
اینجا دامنه مهمتر از هدف است. قاعده masquerade که با هر رابط خروجی مطابقت کند، ترافیکی را هم که درست از eth0 خارج میشود بازنویسی میکند، و این خطاهای مسیریابی را پنهان میکند بهجای آنکه برطرفشان کند. ترجمه پس از تصمیم مسیریابی اجرا میشود، پس هرگز نمیتواند بستهای را که به پیوند بالادستی اشتباه فرستاده شده ترمیم کند.
سرباز تونل هم وقتی مسیرها متفاوتاند نیاز به توجه دارد. اگر کلاینتها MSS بزرگ TCP را مذاکره کنند و WAN جایگزین MTU کمتری یا تونلی درون خود داشته باشد، قطعههای بزرگ میمانند در حالی که کوچکها کار میکنند. محدود کردن MSS روی مسیر فوروارد این را به رفتاری قابل پیشبینی تبدیل میکند نه وقفهای گاهبهگاه.
تصمیم بگیرید وقتی usb0 ناپدید میشود چه اتفاقی میافتد
جدول خالی حالت بستهشدن در شکست نیست. اگر مسیر مطابق ناپدید شود، جستوجو به قاعده بعدی ادامه میدهد، به جدول اصلی میرسد و مسیر پیشفرض eth0 را برمیدارد. ترافیکی که قرار بود از WAN دوم خارج شود بیصدا از اولی خارج میشود، که در استقراری با مسیریابی سیاستی معمولاً کمخواستهترین نتیجه است.
جایی که این عقبنشینی پذیرفتنی نیست، یک مسیر پایانی صریح در جدول 600 اضافه کنید، مثل مسیر پیشفرض blackhole، یا استخر را در دیوار آتش بیندازید تا وقتی رابط پایین است. هر یک از این دو تصمیمی است که میتوانید بنویسید؛ سکوت نیست.
پایداری آخرین مورد است. هر که مالک هر دو پیوند است، چه مدیر شبکه، چه اسکریپت ارسالکننده یا چرخه عمر اتصال، باید مسیرها و قاعده را در هر اتصال دوباره بازسازی کند بدون افزودن نسخههای تکراری. با درخواستی از یک کلاینت واقعی و درخواستی جداگانه از دروازه بررسی کنید، خروجی مشاهدهشده را در هر دو تأیید کنید، سپس WAN دوم را بکشید و ببینید کدام یک از دو نتیجهای که طراحی کردهاید واقعاً رخ میدهد. IPv6 جدول، قاعده و ترجمه خودش را میخواهد؛ قاعده IPv4 بالا چیزی درباره آن نمیگوید.