یک میزبان عمومی برای VPN و وب: چگونه نقشها را تقسیم کنیم
یک IP عمومی میتواند تونلها را خاتمه دهد، HTTPS سرویس دهد و به دو LAN خصوصی برسد. اول تصمیم بگیرید که مالک نشانی، هر پورت و سیاست ارسال چه کسی است.
یک ماشین میتواند هر سه نیاز را همزمان برآورده کند: تونلها را خاتمه دهد، به HTTPS پاسخ دهد و بین دو LAN خصوصی ارسال کند. اینکه این کار منطقی باشد به سه چیز بستگی دارد که میتوانید روی کاغذ روشن کنید: چه کسی مالک نشانی عمومی است، چه کسی مالک هر جفت پورت و پروتکل است، و به کدام فرایند اجازه داده شده بستهها را ارسال کند. اگر اینها را درست انجام دهید، میزبان مشترک چیز قابل توجهی نیست. اگر اشتباه کنید، یک آخر هفته را صرف سرویسی میکنید که تمیز بالا میآید و هرگز پاسخ نمیدهد.
آنچه میآید یک رویه تصمیمگیری است، نه یک برگه ساخت. هر گام با بررسیای پایان مییابد که ثابت کند نقشی که همین حالا افزودهاید واقعا جدا است.
پیش از پورتها، مالک نشانی را انتخاب کنید
یک نقطه پایانی تونل و یک وب سرور میتوانند هسته را مشترک کنند؛ اشتراک یک نشانی، پورت و پروتکل در یک زمان چیزی است که شکست میخورد. WireGuard معمولا UDP 51820 را میگیرد، OpenVPN UDP 1194 یا TCP 443 را میگیرد و یک وب سرور TCP 443 را. جفت دردناک OpenVPN روی TCP 443 در کنار HTTPS است، چون هر دو همان سوکت را میخواهند و هسته آن را به هر کدام که اول bind کرده بدهد. تنها یک demultiplexer در جلو، مانند sslh یا یک پروکسی آگاه به TLS، اجازه میدهد این پورت را شریک شوند و کامپوننتی اضافه میکند که خرابیاش دقیقا شبیه مشکل فایروال است.
پیش از هر تغییری به مالکان نگاه کنید: ss -lntup نشانی محلی، پورت و فرایند هر سوکت در حال شنیدن را چاپ میکند. دو ردیفی که 0.0.0.0:443 را نشان میدهند یعنی سرویس دوم هرگز bind نشده، هر چقدر هم اسکریپت init آن شادمان بوده باشد. پل زدن مالک را هم جابهجا میکند. وقتی eth0 به br0 میپیوندد، IP به br0 منتقل میشود و هر قاعده فایروالی که eth0 را نام میبرد دیگر مطابقت نمیکند، پس سرویسها را روی پل bind کنید و با ip -br addr تأیید کنید.
همان قاعده مالکیت شگفتی را توضیح میدهد که با ماشینهای مجازی پیش میآید. یک سرور تونل که داخل یک مهمان روی همان LAN اجرا میشود، نشانی مهمان را نگه میدارد، پس اتصالهایی که به نشانی خود میزبان نشانه رفتهاند روی میزبان میمانند و تونل مهمان هرگز آنها را نمیبیند، هر چه پروفایل کلاینت بگوید.
مسیریابی بین دو LAN یا NAT کردن یک طرف
دو LAN که همدیگر را نمیبینند میتوانند هر یک به میزبان عمومی زنگ بزنند و آنگاه بین تونلها ارسال کند. این طراحی مسیریابی سه چیز لازم دارد: ارسال روشن، یک مسیر به سمت هر پیشوند دور، و یک سیاست ارسال که عبور را اجازه دهد. sysctl -w net.ipv4.ip_forward=1 اولی را پوشش میدهد، ip route add 10.20.0.0/24 dev wg1 دومی، و یک خط nftables مانند nft add rule inet filter forward iifname "wg0" oifname "wg1" accept سومی.
NAT مبدأ آسانتر نصب میشود و سختتر اشکالزدایی میشود. Masquerade نشانی کلاینت را بازنویسی میکند، پس طرف دور hub را میبیند نه میزبان واقعی را، و قواعد دسترسی و گزارشهایش دیگر برای انتساب مفید نیستند. وقتی هر دو شبکه مال شماست، مسیریابی کنید. وقتی یک طرف مال شخص ثالثی است که مسیر برگشت اضافه نمیکند، NAT گزینهای است که این هفته تحویل میشود. در هر حال، طرح نشانی را بنویسید، چون دو /24 همپوشان را هیچ مقدار پیکربندی نمیتواند مسیریابی کند.
هیچ چیز در اینکه جعبه به عنوان خروجی اینترنت برای یک لپتاپ عمل کند مانع نمیشود که همان جعبه تونلهای ورودی را خاتمه دهد. تنها نشانیهای همپوشان مانع میشوند و به همین دلیل طرح نشانی سند مهم است.
تقسیم را وقتی دو نقش متوقفاند بیازمایید
آزمون سودمند تفریق است: دو نقش را متوقف کنید و تأیید کنید نقش سوم هنوز پاسخ میدهد. یک درخواست وب باید با سرویس تونل خاموش کامل شود و یک دستدادن تونل باید با وب سرور متوقفشده کامل شود. اگر هر دو فقط وقتی همه چیز اجرا میشود کار کنند، یک وابستگی تصادفی دارید، مانند یک جدول فایروال مشترک، یک مسیر سرگردان یا نامی که به نشانی اشتباه اشاره میکند.
سه فرمان این آزمون را عینی میکند. curl -sk --resolve example.test:443:203.0.113.10 https://example.test/ ثابت میکند شنونده محلی بدون DNS بیرونی پاسخ میدهد، wg show روی کلاینت ثابت میکند دستدادن کامل شده، و tcpdump -ni any port 51820 روی hub مشکل مسیریابی را از مشکل کلید جدا میکند. دستدادنی که هرگز در ضبط ظاهر نمیشود پیش از میزبان مرده است: فایروال ارائهدهنده، نشانی عمومی اشتباه یا قاعده NAT در مسیر.
تفریق را برای LANهای ارسالشده تکرار کنید. با قطع بودن یک همتا، پینگ از hub باید شکست بخورد؛ با وصل شدن دوباره، پینگ باید بدون لمس هیچ قاعدهای بازگردد. پینگی که فقط پس از راهاندازی دوباره تونل بازمیگردد به سیاست اشاره میکند نه به دسترسپذیری، و آن تعمیر دیگری است.
مجموعه قواعد را در حین تفریق نقشها خوانا نگه دارید. nft list ruleset باید برای هر جهتی که واقعا نیاز دارید یک قاعده accept نشان دهد، و زنجیرهای که همه چیز را accept میکند جداسازی نیست، یک دمو کارآمد است.
خطوط دسترسی فقط IPv6 و سرویسهای IPv4
بعضی خطوط دسترسی تنها دسترسپذیری IPv6 میدهند و سرویسها هنوز باید روی IPv4 منتشر شوند. خود تونل از خانوادهای عبور میکند که هنوز ترافیک را رد میکند، در حالی که سرویس منتشرشده روی نشانی درون تونل مینشیند. این فرض معمول را وارونه میکند و بیصدا پایش را میشکند: یک قاعده فایروال یا بررسی uptime که برای مسیر IPv4 نوشته شده اکنون رابطی را میپاید که چیزی حمل نمیکند.
هر خانواده را جداگانه با curl -4 و curl -6 بیازمایید، چون یک درخواست موفق درباره مسیری که امتحان نکردهاید چیزی نمیگوید. مالکیت پورت بین خانوادهها تغییر نمیکند، اما شنونده تغییر میکند: ss -lntup سوکتهای IPv4 و IPv6 را ردیفهای جدا فهرست میکند، و 0.0.0.0:443 پوشش نمیدهد [::]:443 را مگر اینکه فرایند یک سوکت dual-stack خواسته باشد.
سرویسی که در یک خانواده پاسخ میدهد و در دیگری رد میکند معمولا مشکل شنونده است نه مسیریابی. پیش از تمامشده خواندن طراحی، تأیید کنید هر نقش نشانی یا پورت خود را دارد، ارسال روشن و مجاز است، و هر نقش با متوقف بودن دو نقش دیگر هنوز پاسخ میدهد.