چگونه فقط یک زیرشبکه خصوصی را از VPN عبور دهیم
بین مسیر روی سرویسگیرنده، مسیری که سرور هل میدهد و انتخابگرهای مورد توافق یکی را انتخاب کنید، سپس یک زیرشبکه خصوصی را بدون تونل کامل عبور دهید.
عبور یک زیرشبکه خصوصی از تونل و رفتن همه چیز دیگر از مسیر معمول شما درخواستی کوچک است که راههای زیادی برای خراب کردنش وجود دارد. آنچه نتیجه را تعیین میکند کادر تیک با برچسب split tunneling نیست، بلکه جایی است که تصمیم اعمال میشود: جدول مسیر خود سرویسگیرنده، مسیری که سرور هل میدهد، یا سیاستی که دو طرف بر سرش مذاکره میکنند. لایه اشتباه را انتخاب کنید و یا تونل کاملی میگیرید که هرگز نمیخواستید، یا مسیری به تونلی که طرف مقابل از پذیرفتنش سر باز میزند. من پیش از باز کردن هر پیکربندی از آزمونی با سه شرط استفاده میکنم و سپس یکی از سازوکارهای زیر را برمیگزینم.
سه شرطی که طراحی را تعیین میکنند
نخست، به پیشوند و ماسک دقیق از مالک شبکه نیاز دارید. شبکه 10.x یک پیشوند نیست؛ 10.20.0.0/16 پیشوند است. تأیید کنید که با LAN خانگی، پل Docker یا VPN دیگری که اجرا میکنید همپوشانی ندارد، زیرا همپوشانی مسیر را مبهم میکند و هسته ورودیای را انتخاب میکند که قصدش را نداشتید.
دوم، چه کسی به ترافیک برگشتی پاسخ میدهد. مسیردهی بسته به داخل تونل فقط آن را به سرور VPN میرساند. اگر زیرشبکه پشت روتر دیگری باشد که مسیری بازگشتی به استخر سرویسگیرندگان شما ندارد، سرور باید ترافیک را ماسک کند، یا آن روتر باید استخر شما را یاد بگیرد. هیچ مسیری در سمت سرویسگیرنده مسیر بازگشت نبوده را درست نمیکند.
سوم، نقطه اعمال. برخی سرویسگیرندگان مسیری نصب میکنند و سیستمعامل بقیه کار را انجام میدهد. برخی دیگر سیاستی را مذاکره میکنند، و سیاستی که دروازه نمیپذیرد هیچ تونلی تولید نمیکند: بستهها بدون خطای آشکار دور ریخته میشوند. پیش از نوشتن هر چیزی مشخص کنید کدام یک از این دو مورد شماست.
WireGuard: AllowedIPs همان جدول مسیر است
روی سرویسگیرنده، AllowedIPs مقصدهایی را فهرست میکند که میتوانند وارد تونل شوند، و wg-quick هر ورودی را به یک مسیر معمولی تبدیل میکند. پس نیمه سرویسگیرنده این کار یک خط است.
[Peer]
PublicKey = ...
Endpoint = vpn.example.net:51820
AllowedIPs = 10.20.0.0/16اکنون ورودی سرور برای همان سرویسگیرنده را مقایسه کنید. این ورودی توصیف میکند سرور چه چیزی به سرویسگیرنده میفرستد، که معمولاً نشانی تونل سرویسگیرنده است، نه زیرشبکه خصوصی.
[Peer]
PublicKey = ...
AllowedIPs = 10.99.0.2/32جابهجا کردن این دو خطایی است که بیشتر از همه میبینم. قرار دادن 10.20.0.0/16 زیر بخش peer سرور یعنی کل زیرشبکه پشت آن سرویسگیرنده است، و این ادعای سایت به سایت است نه اجازه. بستههایی که با AllowedIPs هیچ peer مطابقت ندارند بیصدا دور ریخته میشوند، پس یک ورودی اشتباه دقیقاً مانند مشکل دیوار آتش به نظر میرسد.
اگر مسیرها را خودتان مدیریت میکنید، Table = off را زیر [Interface] تنظیم کنید و مسیری که میخواهید اضافه کنید. آنگاه هیچ چیز خودکار اضافه نمیشود، پس مسیر باید در همان چیزی باشد که رابط را بالا میآورد.
OpenVPN: مسیر را هل بدهید، سپس مطمئن شوید که میرسد
روی یک سرور معمولی تغییر یک دستور در پیکربندی سرور است، کنار استخر سرویسگیرندگان.
push "route 10.20.0.0 255.255.0.0"سرویسگیرنده هنگام اتصال آن را اضافه میکند. حالت خرابی هنگامی رخ میدهد که همان پروفایل redirect-gateway را هم هل بدهد، یا کسی پیشتر route-nopull را اضافه کرده باشد: اولی جلسه را به تونل کامل تبدیل میکند و دومی همه مسیرهای هلشده از جمله مسیر شما را دور میریزد.
سرویسگیرندهای که در برابر سرور تونل کامل به رفتار باریک نیاز دارد باید تنها بخشهایی را که نمیخواهد نادیده بگیرد. در OpenVPN 2.4 و بعد از آن، pull-filter دقیقاً برای همین وجود دارد.
pull-filter ignore "redirect-gateway"
route 10.20.0.0 255.255.0.0خانوادههای نشانی را جدا نگه دارید: مسیر IPv4 هلشده برای سرویس داخلیای که به IPv6 تفکیک میشود کاری نمیکند، و آن سرویس از تونل شکست میخورد در حالی که بقیه چیزها درست به نظر میرسند.
وقتی زیرشبکه خصوصی روی سرور VPN نیست بلکه پشت سرویسگیرنده دیگری است، باید به سرور گفته شود. از طریق client-config-dir یک فایل برای هر سرویسگیرنده اضافه کنید که iroute 10.20.0.0 255.255.0.0 را در بر دارد، بههمراه route متناظر تا سرویسگیرندگان دیگر مسیر را یاد بگیرند. بدون iroute سرور دلیلی برای فرستادن آن پیشوند از همان تونل خاص ندارد.
IPsec: انتخابگرهای ترافیک باید توافق داشته باشند
در IPsec مسیری برای هل دادن وجود ندارد. دو طرف بر سر اینکه کدام نشانیها داخل تونل هستند مذاکره میکنند، و ترافیک بیرون از انتخابگرهای توافقشده نه رمزگذاری میشود و نه از آن عبور میکند. روی سرویسگیرنده strongSwan انتخابگرها صریحاند.
leftsubnet=192.168.1.0/24
rightsubnet=10.20.0.0/16اگر دروازه در هر دو طرف با 0.0.0.0/0 پیکربندی شده باشد، باریکشدن IKEv2 معمولاً SA فرزند را به اشتراک دو پیشنهاد کاهش میدهد، که همان نتیجه مطلوب است. برخی دروازهها بهجای آن پیشنهادی را رد میکنند که با انتخابگرهای پیکربندیشدهشان همخوان نیست، و آنگاه گزارش یک SA فرزند ناموفق نشان میدهد نه شکایت مسیردهی. وقتی این رخ دهد تغییر باید روی دروازه انجام شود، زیرا مسیر سرویسگیرنده نمیتواند تونلی برای انتخابگری بسازد که طرف دیگر آن را نمیپذیرد.
در Windows سرویسگیرنده داخلی همان تصمیم را پشت دو تنظیم پنهان میکند. تقسیم تونل باید روشن باشد و پیشوند باید روی پروفایل ثبت شود.
Set-VpnConnection -Name Office -SplitTunneling $true
Add-VpnConnectionRoute -ConnectionName Office -DestinationPrefix 10.20.0.0/16ثبت پیشوند همان چیزی است که آن را در برابر اتصال دوباره پایدار میکند، کاری که مسیر دستی چنین نمیکند.
نقطه پایانی و DNS را بیرون از تصمیم نگه دارید
نقطه پایانی VPN باید بدون تونل قابل دسترس بماند، وگرنه تونل روی خودش فرو میریزد. وقتی تنها 10.20.0.0/16 مسیردهی میشود این خودکار است، چون نقطه پایانی یک نشانی عمومی است. در پروفایل تونل کامل چنین نیست، و سرویسگیرنده به یک مسیر میزبان صریح به نقطه پایانی پیش از بالا آمدن تونل نیاز دارد.
DNS تصمیم دومی است که هل دادن مسیر به جای شما نمیگیرد. نامهای داخلی معمولاً از طریق تفکیککنندهای حل میشوند که تنها شبکه خصوصی به آن میرسد. اگر سرور یک سرور DNS هل بدهد، هر نامی از آن عبور میکند؛ اگر ندهد، نامهای داخلی یا شکست میخورند یا بهصورت عمومی به چیزی تفکیک میشوند که قصدش را نداشتید. DNS تقسیمشده یک دامنه جستوجو را روی تفکیککننده داخلی نگه میدارد، اما به پشتیبانی سرویسگیرنده بستگی دارد، پس آن را کاری مستقل بدانید نه عارضهای از مسیردهی.
بررسی کنید، سپس راهاندازی مجدد و باز هم بررسی کنید
سه آزمون پرسش مسیردهی را پوشش میدهد. از هسته بپرسید یک نشانی دوردست به کجا میرود، چیزی از داخل زیرشبکه بگیرید، سپس تأیید کنید که یک درخواست عمومی معمولی همچنان از اتصال معمول شما بیرون میرود.
ip route get 10.20.5.7
curl -sS http://10.20.5.7/health
curl -sS https://ifconfig.meخط اول یک رابط را نام میبرد. اگر رابط فیزیکی شما را نام ببرد، مسیر هرگز مستقر نشده. در Windows Find-NetRoute -RemoteIPAddress 10.20.5.7 به همان پرسش پاسخ میدهد، و آزمون آخر باید همچنان نشانی معمول شما را نشان دهد نه نشانی سرور VPN.
سپس راهاندازی مجدد کنید. مسیرهایی که با دست اضافه شدهاند ناپدید میشوند، در حالی که مسیرهای آمده از پروفایل، از پیکربندی هلشده یا از AllowedIPs باز میگردند. اگر دسترسی باریک پیش از راهاندازی مجدد کار کند و پس از آن شکست بخورد، ایراد در نحوه آغاز تونل است نه در خود مسیر.
پیش از آنکه آن را تمامشده بنامید، چهار چیز را تأیید کنید: پیشوند از مالک شبکه آمده و با هیچ چیز محلی همپوشانی ندارد، مسیر بازگشت وجود دارد یا قاعدهای ماسک جای آن را میگیرد، سازوکاری که پیکربندی کردهاید همانی است که مسیردهی را روی سکوی شما اعمال میکند، و همان آزمونها پس از راهاندازی مجدد تمیز هم موفق میشوند. یادداشتهای strongSwan درباره ارسال خواندنش میارزد اگر مسیر بازگشت همان بخشی باشد که مدام شکست میخورد.