انتقال پورت به یک peer از WireGuard در پشت NAT: DNAT بههمراه SNAT
DNAT درخواست را تحویل میدهد، اما پاسخ از آدرس اشتباه خارج میشود. یک قاعده SNAT منطبق اضافه کنید و هر دو را پس از پیکربندی تونل قرار دهید.
یک مرورگر https://203.0.113.10:8443 را درخواست میکند، پراکسی اتصال را میپذیرد و سرویس روی peer از WireGuard هرگز پاسخ نمیدهد. قاعده DNAT کار خود را انجام میدهد؛ بخشی که شکست میخورد پاسخ است. بسته را از هر دو ترجمه دنبال کنید و قاعده گمشده آشکار میشود. راهحل یک دستور NAT دیگر در hook درست است، نه یک تونل تازه.
یک درخواست را از ابتدا تا انتها دنبال کنید
درخواست با آدرس عمومی کلاینت بهعنوان مبدأ و آدرس پراکسی بهعنوان مقصد روی رابط عمومی پراکسی میرسد. در nat PREROUTING قاعده DNAT مقصد را به آدرس تونل peer، یعنی 10.90.0.2 بازنویسی میکند. سپس تصمیم مسیریابی بسته را از طریق wg0 بیرون میفرستد و مسیر ارسال کامل میشود.
روی peer، بسته اکنون آدرس مبدأ عمومی اصلی را حمل میکند، چون چیزی آن را بازنویسی نکرده است. سرویس اتصال را میپذیرد و پاسخ خود را به دروازه پیشفرض خود میفرستد، یعنی روتر خانگی جلوی peer. آن روتر هیچ وضعیتی برای جریانی که هرگز ندیده ندارد و یا بسته را دور میریزد یا آن را به آدرس عمومی خودش ترجمه میکند، که کلاینت نخواهد پذیرفت.
عدم تقارن تمام مشکل است: درخواست از پراکسی میگذرد و پاسخ تلاش میکند مستقیم برود. ردیابی اتصال پراکسی فقط وقتی کمک میکند که پاسخ از طریق پراکسی برگردد، و تا وقتی آدرس مبدأ هنوز به کلاینت اصلی اشاره میکند نمیتواند به آنجا برگردد.
ترجمه برگشتی را اضافه کنید
مبدأ جریان ارسالشده را بازنویسی کنید به آدرس تونل پراکسی، پیش از آنکه به سمت peer برود. سپس سرویس به 10.90.0.1 پاسخ میدهد، پراکسی آن را دریافت میکند و ردیابی اتصال هر دو ترجمه را برمیگرداند پیش از آنکه بسته به کلاینت برگردد.
iptables -t nat -A PREROUTING -p tcp -m multiport --dports 8080,8443 -j DNAT --to-destination 10.90.0.2
iptables -t nat -A POSTROUTING -d 10.90.0.2 -o wg0 -p tcp -m multiport --dports 8080,8443 -j SNAT --to-source 10.90.0.1قاعده POSTROUTING عمداً باریک است: با مقصد ترجمهشده و رابط تونل مطابقت دارد، بنابراین ترافیک نامرتبطی را که تصادفاً از wg0 خارج میشود بازنویسی نمیکند. یک قاعده masquerade گسترده نیز آدرس کلاینت را پنهان میکرد، اما این کار را برای هر جریان انجام میداد و بازرسی جدول NAT را سختتر میکرد.
قاعدهها را جایی بگذارید که تونل وجود دارد
قاعدههایی که به آدرس یا رابط تونل ارجاع میدهند باید پس از پیکربندی آن توسط wg-quick اجرا شوند. رابط پیش از PreUp ساخته میشود، اما آدرسها، MTU، DNS و مسیرها پس از آن اعمال میشوند و PostUp زمانی اجرا میشود که همه اینها سر جای خود باشند. افزودنها را در PostUp و حذفها را در PreDown بگذارید.
PostUp = iptables -t nat -A PREROUTING -p tcp -m multiport --dports 8080,8443 -j DNAT --to-destination 10.90.0.2
PostUp = iptables -t nat -A POSTROUTING -d 10.90.0.2 -o wg0 -p tcp -m multiport --dports 8080,8443 -j SNAT --to-source 10.90.0.1
PreDown = iptables -t nat -D PREROUTING -p tcp -m multiport --dports 8080,8443 -j DNAT --to-destination 10.90.0.2
PreDown = iptables -t nat -D POSTROUTING -d 10.90.0.2 -o wg0 -p tcp -m multiport --dports 8080,8443 -j SNAT --to-source 10.90.0.1حذفها باید توکن به توکن با افزودنها مطابقت داشته باشند، از جمله تطابقهای multiport و رابط. حذفی که در یک تطابق تفاوت دارد چیزی را برنمیدارد و اتصال بعدی نسخه دومی از قاعده را اضافه میکند. پس از چند اتصال مجدد، جدول شامل تکراریهایی است که نسبت دادنشان به یک خط پیکربندی دشوار است.
نتیجه را با iptables -t nat -S پس از اتصال مجدد بررسی کنید. اگر همان قاعده دو بار ظاهر شود، خط PreDown مطابقت ندارد و پاکسازی بیصدا شکست میخورد.
ارسال، فیلتر و NAT دیگر
ارسال IPv4 را بهصورت پایدار فعال کنید، سپس جریان ارسالشده را در جدول فیلتر مجاز کنید. DNAT پیش از زنجیره FORWARD رخ میدهد، بنابراین قاعده فیلتر با مقصد ترجمهشده مطابقت دارد نه با آدرس عمومی. اگر UFW فایروال را مدیریت میکند، اجازه را بهصورت قاعده مسیر بیان کنید؛ یک قاعده میزبان ساده ترافیک ارسالشده را پوشش نمیدهد.
دو لایه دیگر NAT هنوز میتوانند مسیر را حتی وقتی قاعدههای پراکسی درست هستند بشکنند. در اتصال خانگی، آدرس عمومی متعلق به روتر است و باز کردن پورت در فایروال آن با ساختن یک ورودی انتقال پورت که آن پورت را به پراکسی میفرستد یکی نیست. پورتی که از بیرون باز به نظر میرسد در حالی که هیچ چیز پاسخ نمیدهد، اغلب دقیقاً همان نگاشت را ندارد.
در VPS با NAT، ارائهدهنده یک پورت عمومی را به آدرس خصوصی نگاشت میکند. نگاشت باید با پورتی که اعلام میکنید همخوان باشد و ناسازگاری دقیقاً مانند یک تونل خراب به نظر میرسد. پیش از تغییر پیکربندی WireGuard، نگاشت ارائهدهنده را تأیید کنید.
مسیر برگشت را بررسی کنید و هزینه را بپذیرید
از شبکهای که LAN پراکسی نیست متصل شوید، سپس جفت ترجمه را در حالی که اتصال باز است بررسی کنید:
conntrack -L -p tcp --dport 8080
tcpdump -ni any tcp port 8080ورودی conntrack باید تاپل اصلی، تاپل ترجمهشده و جهت پاسخ را نشان دهد. اگر پاسخ نیست، peer از طریق تونل ارسال نمیکند، که معمولاً یعنی قاعده SNAT اعمال نشده یا فایروال خود peer جریان را انداخته است.
یک بار راهاندازی مجدد کنید تا ثابت شود PostUp قاعدهها را دوباره اعمال میکند، سپس تونل را متوقف کنید و تأیید کنید PreDown آنها را حذف کرده است. قاعدههای مردهای که از قطع اتصال جان سالم به در میبرند دلیل رفتار غیرقابل پیشبینی یک تغییر بعدی هستند.
در پایان، بپذیرید SNAT چه هزینهای دارد. سرویس هر درخواست را از پراکسی میبیند، بنابراین گزارشهای دسترسی، محدودیت نرخ هر کلاینت و فهرستهای آدرس مجاز دیگر کاربران را از هم جدا نمیکنند. مورد hairpin به ترجمه مبدأ خودش برای کلاینتهای LAN پراکسی نیاز دارد. اگر peer به آدرسهای واقعی کلاینت نیاز دارد، جایگزین یک مسیر برگشت به شبکه کلاینت است که کار بیشتری است اما اطلاعات را حفظ میکند.