دسترسی به یک /24 دور از طریق تونل: NETMAP، DNAT یا مسیر؟
کل یک پیشوند را با NETMAP نگاشت کنید، قواعد DNAT بهازای هر میزبان اضافه کنید یا بازه واقعی را مسیریابی کنید، و بر اساس آنچه طرف دور باید ببیند و چه کسی میتواند ترافیک را آغاز کند تصمیم بگیرید.
میتوانید به سه روش به یک زیرشبکه پشت نقطه انتهایی تونل برسید، و یک دقیقه جمعآوری واقعیت معمولاً دو روش را حذف میکند. واقعیتها اینها هستند: آیا سرورهای آنجا باید کاربران را از هم تشخیص دهند، آیا کسی آنجا هرگز به سمت بازه شما شماره میگیرد، و چه کسی اجازه دارد روتر انتهای دور را ویرایش کند. به این سه پاسخ دهید تا طراحی خودش انتخاب شود. بقیه فرض میکند شما نقطه انتهایی را اداره میکنید و اجازه ویرایش فایروال آن را دارید.
سه گزینه، و اینکه هرکدام واقعاً چه چیزی را تغییر میدهد
نگاشت پیشوند، DNAT بهازای هر میزبان و پیشوند مسیریابیشده همه بستهها را بین همان دو بازه جابهجا میکنند، اما چیزهای متفاوتی را تغییر میدهند. نگاشت یک بازه مستعار میسازد و آدرسها را در پرواز بهصورت حسابی بازنویسی میکند. قواعد هر میزبان هم بازنویسی میکنند، با این تفاوت که هر مقصد دستی نامگذاری میشود. پیشوند مسیریابیشده هیچ چیز را بازنویسی نمیکند: بستهها آدرسهای واقعی را حفظ میکنند و دو طرف بر سر اینکه این آدرسها کجا زندگی میکنند توافق دارند.
| What the far side needs | Prefix mapping | Per-host DNAT | Routed prefix |
|---|---|---|---|
| Users visible to its logs | Only without source NAT | Same condition | Yes, unchanged |
| To start a connection toward you | No, alias is local | No, same reason | Yes, both ends route |
| To absorb a new host | Yes, arithmetic only | No, one rule per address | Yes, it simply routes |
| To require no config change | Yes, with source NAT | Yes, same condition | No, it needs a route back |
حذف را از طرف دور شروع کنید، جایی که محدودیتها سختترین تغییر هستند. اگر سروری آنجا آدرس مشتریان را در گزارشها مینویسد، آنها را با فهرست مجاز بررسی میکند یا به سیستم دیگری میسپارد، ترجمه مبدأ تنها شناسه آن را نابود میکند. اگر طرف دور هم باید تماس بگیرد، ترجمه کاملاً منتفی است، چون هیچکس آنجا نمیداند که مستعار وجود دارد. تنها وقتی طرف دور فقط به درخواستها پاسخ میدهد، گزینههای ارزانتر ایمن میشوند.
جفتهای پیشوند، و اینکه چرا اندازهها باید برابر باشند
NETMAP هدفی در جدول nat است که روی جفتی از پیشوندهای هماندازه کار میکند. درون آن جدولی بهازای هر آدرس نیست: پیشوند را برمیدارد، بیتهای میزبان را نگه میدارد و آنها را به پیشوند جدید میچسباند، به همین دلیل /24 روی /24 نگاشت میشود و هرگز روی /25 نه. موقعیت جهت را تعیین میکند: تطابق مقصد در PREROUTING بازنویسی میکند که بسته به کجا میرود، و تطابق مبدأ در POSTROUTING بازنویسی میکند که از کجا آمده است.
یک میزبان در 192.168.2.17 برای مشتریان شما بهصورت 10.50.1.17 دیده میشود، و هشتگانه آخر تزئینی نیست — همان عدد در هر دو طرف است. فردا میزبانی در 192.168.2.40 اضافه کنید و مستعارش 10.50.1.40 خواهد بود، بدون هیچ قاعدهای برای ویرایش.
مشتریان هنوز به مسیری برای بازه مستعار نیاز دارند که به جعبه شما اشاره کند، مگر اینکه مستعار درون زیرشبکهای باشد که از قبل به آن میرسند. دروازه به مسیری برای مستعار نیاز ندارد، چون ترجمه مقصد در PREROUTING و پیش از جستوجوی مسیر اجرا میشود. ارسال هم باید روشن باشد، وگرنه هسته بسته را پس از بازنویسی دور میریزد. سه فرمان زیر کل تنظیمات روی دروازهای به سبک Debian است با مشتریان روی br0، مستعار روی 10.50.1.0/24 و تونل روی tun0.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -i br0 -d 10.50.1.0/24 -j NETMAP --to 192.168.2.0/24
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADEپاسخ باید خودش راه بازگشت را پیدا کند
بازنویسی مقصد فقط تعیین میکند بسته کجا تحویل داده شود. سرور طرف دور هنوز باید به آدرسی پاسخ دهد که میتواند به آن برسد، و دو راه برای چیدن این کار وجود دارد. مبدأ را ترجمه کنید تا پاسخها به جعبه شما برگردند، یا مبدأ را دستنخورده بگذارید و به طرف دور مسیری برای بازه مشتریان بدهید.
masquerade در مسیر خروج کوتاهترین راه است: یک قاعده در POSTROUTING و طرف دور آدرس تونل شما را میبیند، پس به مسیر خودش نیازی ندارد. هزینه این است که همه کاربران در یک آدرس ادغام میشوند و گزارشهای هر کاربر معنای خود را از دست میدهند. دستنخورده گذاشتن مبدأ آن اطلاعات را حفظ میکند، اما آنگاه سایت دور باید پاسخهای بازه مشتریان را از طریق تونل بازگرداند. روی یک OpenVPN سرور این یک push "route 10.50.9.0 255.255.255.0" ارسالشده است، بهعلاوه یک خط route 192.168.2.0 255.255.255.0.
شکست گران، انجام نیمی از هر دو است. اگر بخشی از ترافیک را masquerade کنید در حالی که طرف دور هم مسیر بازگشتی برای ترافیک دیگری دارد، پاسخها روی رابطی میرسند که ورودی ردیابی اتصال هرگز در آن دیده نشده است. مشتری برای درخواستی که سرور آن را بهعنوان سرویسشده ثبت کرده، پایان مهلت گزارش میکند. هر دو جهت یک جریان باید از همان نمونه netfilter بگذرند: یک دروازه ترجمه میکند، نه دو فایروال پشت سر هم.
conntrack -L -d 10.50.1.17
iptables -t nat -L PREROUTING -v -nورودی را در هر دو جهت بخوانید: چندتایی اصلی مستعار شما را روی مقصد نگه میدارد، در حالی که چندتایی پاسخ آدرس واقعی را حمل میکند. اگر چندتایی پاسخ وجود ندارد، مشکل مسیر بازگشت است نه قاعده. اگر شمارندههای PREROUTING هرگز تکان نخوردند، بسته هرگز به آن قلاب نرسیده است.
برخوردها و جستوجویی که اول اجرا میشود
دو بازه متفاوت میتوانند برخورد کنند و هر دو خرابی مثل تونل شکسته به نظر میرسند نه قاعده بد. مستعاری که میسازید باید در تمام مسیر استفادهنشده باشد، و بازه واقعی طرف دور نباید از قبل در شبکه شما وجود داشته باشد. تکراری بودن ترافیک متناوب به میزبان اشتباه تولید میکند، که تشخیصش از اتصال ردشده سختتر است. پیش از افزودن قاعده از جدول مسیریابی بپرسید.
روی دروازه، ip route get 192.168.2.17 باید دستگاه تونل را نام ببرد؛ یک پل محلی یعنی بازه دور سایه افتاده و هیچ قاعده nat آن را درست نمیکند. اگر شبکه خودتان از قبل 192.168.2.0/24 را استفاده میکند، سایت دور را دوباره شمارهگذاری کنید نه اینکه نگاشتی روی برخورد سوار کنید.
آزمایش از یک مشتری واقعی، سپس نگهداشتن آن
از ماشینی آزمایش کنید که واقعاً از مستعار استفاده خواهد کرد، نه از دروازه، چون ترافیک تولیدشده محلی هرگز به همان شکل از PREROUTING نمیگذرد. اتصالی به یک میزبان مستعار باز کنید و ببینید شمارندهها و ورودی conntrack با هم ظاهر میشوند، سپس آن را ببندید و تأیید کنید که ورودی میرود. ورودی کهنه به اتصال نیمهباز اشاره دارد، که معمولاً یعنی پاسخ هرگز برنگشته است.
curl -sv http://10.50.1.17/ -o /dev/null
ss -tn dst 10.50.1.17
conntrack -L -d 10.50.1.17دو یا سه اتصال موفق حساب را اثبات میکند، اما درباره پایداری یا مهندس بعدی چیزی نمیگوید. قواعد را جایی ذخیره کنید که فرایند راهاندازی آنها را میخواند، که در Debian و Ubuntu یعنی iptables-save > /etc/iptables/rules.v4 با netfilter-persistent فعال. نگاشتی که در راهاندازی مجدد ناپدید میشود بدتر از هیچ است، چون قطعی بدون تغییر اخیری که بتوان سرزنش کرد میآید.
یادداشتی کنار قواعد بگذارید: بازه مستعار، بازه واقعی، دلیل جفت و اینکه کدام طرف میتواند آغاز کند. آن یادداشت طراحی را از تودهای قاعده که کسی جرئت حذفشان را ندارد جدا میکند. پرسش بعدی را هم حل میکند، وقتی سایت دور میزبانی اضافه میکند و آدرسی که کسی پیکربندی نکرده از قبل پاسخ میدهد. اگر یادداشت بگوید طرف دور به مسیر بازگشت نیاز دارد، نفر بعدی میداند که حذف قاعده masquerade اتصال را قطع میکند. مستندسازی اینجا ارزان است؛ کشف دوباره وابستگی به NAT در ساعت سه بامداد نه.