پس از تغییر IP سرور، قاعده SNAT هنوز آدرس قدیمی را نام میبرد
تونل میتواند وصل شود در حالی که هر بستهٔ فورواردشده متوقف میماند، چون قاعدهٔ ترجمه هنوز به آدرسی بازنویسی میکند که میزبان دیگر آن را در اختیار ندارد.
سرور به آدرس تازهای منتقل شده، کلاینتها هنوز وصل میشوند، و هیچچیز از آنچه میفرستند به اینترنت نمیرسد. همین شکاف سرنخ است: سوکت شنود و فوروارد پورت از جابهجایی جان سالم به در بردهاند، پس تونل بالا میآید، در حالی که ترجمهٔ مبدأ که روی بستههای فورواردشده اعمال میشود هنوز آدرسی را نام میبرد که میزبان دیگر آن را در اختیار ندارد. پاسخهای آن بستههای بازنویسیشده به ماشینی میرود که دیگر وجود ندارد.
اتصال و فوروارد در جاهای متفاوتی شکست میخورند
برقراری به نقطهٔ پایانی بستگی دارد که کلاینتها از قبل میشناسند: آدرس عمومی، فوروارد پورت جلوی آن، و شنوندهٔ داخل. ترافیک فورواردشده به تصمیم دومی بستگی دارد که پس از ورود بسته به تونل گرفته میشود، وقتی میزبان مبدأ خود را بازنویسی میکند تا پاسخها راه بازگشت را پیدا کنند.
تغییر آدرس فقط تصمیم دوم را میشکند، و به همین دلیل نشانه به شکل «وصل است اما اینترنت ندارد» خوانده میشود. این همچنین توضیح میدهد چرا بررسیهای معمول سمت کلاینت سالم به نظر میرسند: دستدهی کامل میشود، کلاینت آدرس میگیرد، و حتی ping به آدرس تونل سرور هم ممکن است پاسخ بدهد. ساعتها روی کلاینت برای نقصی تلف میشود که در سمت دیگر زندگی میکند، و به همین دلیل جدول قواعد اولین جایی است که باید نگاه کرد.
پیش از ویرایش، قاعده و شمارندههایش را بخوانید
قواعد ترجمه را همراه شمارندهها فهرست کنید و مبدأ پیکربندیشده را با آدرسهایی که میزبان واقعاً دارد مقایسه کنید. قاعدهای که به آدرس مرده بازنویسی شده معمولاً ترافیک را در مسیر ورود نشان میدهد، چون بستهها به آن میرسند و ترجمه میشوند، و در مسیر بازگشت هیچ چیز.
sudo iptables -t nat -L POSTROUTING -n -v --line-numbers
ip -4 addr show
وقتی آنجا هستید سه فیلد را بررسی کنید: مجموعه در تطبیق مبدأ، رابط خروج اگر قاعده یکی را نام میبرد، و استثنایی که مانع بازنویسی ترافیک تونلبهتونل میشود. این استثنا در حین ویرایش بهراحتی گم میشود، و گم شدنش باعث میشود ترافیک همتاها کار کند به نظر برسد در حالی که پاسخهایش مسیر عجیبی میگیرند.
اگر شمارندهها روی صفر ماندهاند، بستهها هرگز به این قاعده نمیرسند و آدرس مشکل فعلی نیست. دنبال قاعدهٔ رقیبی در بالاتر زنجیره بگردید، که وقتی کسی بهجای ویرایش اصل، جایگزینی اضافه میکند رخ میدهد. شمارههای قاعده را با خروجیای که یک دقیقه پیش یادداشت کردید مقایسه کنید. ترتیب بخشی از پیکربندی است، نه جزئیات ظاهری.
مبدأ را جایگزین کنید، یا دیگر مبدأیی نام نبرید
وقتی میزبان آدرس پایداری دارد، قاعده را در جای خودش جایگزین کنید نه اینکه یکی دیگر بیفزایید. جایگزینی بر اساس شمارهٔ قاعده ترتیبی را حفظ میکند که بقیهٔ زنجیره به آن وابسته است.
sudo iptables -t nat -R POSTROUTING 1 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source 10.151.0.40
وقتی آدرس بهصورت پویا تخصیص مییابد، هیچ مبدأیی نام نبرید و بگذارید هسته آدرس فعلی را از رابط خروج انتخاب کند. این گونه بدون ویرایش از جابهجایی بعدی جان سالم به در میبرد، به قیمت پنهان کردن اینکه کدام آدرس استفاده شد.
sudo iptables -t nat -R POSTROUTING 1 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -o eth0 -j MASQUERADE
تأیید کنید که فوروارد IPv4 هنوز از طریق پیکربندی مدیریتشده فعال است، سپس قاعده را با سازوکار خود توزیع ماندگار کنید. تغییری که فقط در هستهٔ در حال اجرا انجام شود با راهاندازی مجدد بعدی برمیگردد، معمولاً در پنجرهٔ نگهداریای که هیچکس آن را به تغییر ربط نمیدهد.
دو راه برای انجام اشتباه جایگزینی
ترجمهٔ مجموعه به آدرس تونل سرور بهجای آدرس LAN آن، پاسخها را مستقیم به تونل برمیگرداند، جایی که به سمت کلاینتی مسیریابی میشوند که هرگز آنها را نخواسته است. اتصال به شکلی متوقف میشود که شبیه حلقهٔ مسیریابی است، چون واقعاً حلقه است.
انباشتن ترجمهٔ دومی روی ترجمهٔ قدیمی اشتباه دیگر است. اولین قاعدهٔ منطبق برنده است، پس ورودی کهنه تا وقتی حذف نشود به پردازش بستهها ادامه میدهد، و شمارندههای قاعدهٔ جدید روی صفر میمانند در حالی که همه جایگزین را سرزنش میکنند. پیش از افزودن هر چیز تازه، نسخهٔ تکراری را حذف کنید. سپس فهرست را یک بار دیگر بخوانید و تأیید کنید که دقیقاً یک ترجمه با مجموعه منطبق است.
اگر تونل IPv6 هم حمل میکند، کل بازبینی را روی پشتهٔ دیگر تکرار کنید. مسیر پیشفرض IPv6 بدون ترجمه و بدون پیشوند مسیریابیشده هم به همین بیصدایی شکست میخورد، و فراموش کردنش آسان است چون همهچیز بالای آن یکسان به نظر میرسد.
سرویسهای ورودی به ترجمهٔ معکوس نیاز دارند
سرویسی روی کلاینت VPN که باید از بیرون در دسترس باشد به ترجمهٔ مقصد نیاز دارد، نه ترجمهٔ مبدأ: پورت عمومی پیش از ورود به آدرس تونل کلاینت بازنویسی میشود. سپس مسیر فوروارد به قاعدهای صریح نیاز دارد که آن ترافیک را مجاز کند.
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.9.8.2:8080
هرگز پورتی را که خود تونل را حمل میکند ترجمه نکنید، چون آن بازنویسی اتصالی را قطع میکند که سرویس را در دسترس نگه میدارد. پورت تونل را کاملاً بیرون از قواعد مقصد نگه دارید. در پایان از دو طرف بررسی کنید: شمارندهها روی قاعدهٔ جدید، یک ضبط کوتاه روی دستگاه تونل، و یک درخواست به آدرسی درون تونل پیش از امتحان کردن آدرس عمومی.