محافظت معمول در برابر حلقه یک مسیر میزبان است: ترافیک به نشانی عمومی سرور VPN را از uplink بیرون بفرستید تا نشست رمزنگاری‌شده هرگز وارد تونل خودش نشود. این کار دقیقاً تا لحظه‌ای کار می‌کند که می‌خواهید از طریق تونل به یک سرویس وب روی همان سرور هم برسید، چون استثنا به مقصد گره خورده و مقصد یکسان است. راه خروج این است که دسته‌بندی بر اساس مقصد را رها کنید و دسته‌بندی بر اساس این‌که کدام سوکت بسته را فرستاد را آغاز کنید.

با دو جریانی شروع کنید که می‌خواهید جدا کنید

یکی از جریان‌ها خودِ انتقال رمزنگاری‌شده OpenVPN است که باید از uplink بیرون برود، وگرنه تونل اتصال بیرونی خودش را حمل می‌کند. دیگری یک درخواست HTTPS معمولی به همان نشانی عمومی است که می‌خواهید داخل تونل باشد تا از منبع تونل به سرویس برسد. مقصد یکسان، در بسیاری موارد شماره پورت یکسان، مسیر لازم متفاوت.

در این توضیح فرض کنید کلاینتی روی 10.90.0.10 از طریق tun1 است، نشانی عمومی سرور 198.51.100.25 است، و جدول اصلی دست‌نخورده است و مسیر پیش‌فرضش به uplink معمول اشاره می‌کند. سمت سرور هم باید سرویس وب را در مسیر داخلی بپذیرد و ترافیک را به منبع تونل برگرداند؛ فرستادن بسته به یک نشانی عمومی شنونده یا سیاست دیوار آتش سرور را لغو نمی‌کند.

پیش از تغییر هر چیز، قواعد کنونی میزبان را ثبت کنید و مقادیری برگزینید که کس دیگری به کار نمی‌برد: یک نشانه، یک شماره جدول و سه اولویت قاعده. مسیر بازگشتی نگه دارید که از این اتصال نمی‌گذرد، چون خطا در اینجا دسترسی از راه دور خودتان را می‌گیرد، نه فقط یک زبانه مرورگر را می‌شکند.

سوکتی را که پاکت را حمل می‌کند نشانه‌گذاری کنید

پیکربندی کلاینت برای بسته‌های خروجی رمزنگاری‌شده‌اش یک نشانه می‌گیرد و خودش نصب مسیر را کنار می‌گذارد، تا سیاست جانشین تنها چیزی باشد که مسیرها را تعیین می‌کند:

mark 42
route-noexec
disable-dco

دهدهی 42 همان شانزده‌شانزدهی 0x2a است و شکلی که قواعد مسیریابی تطبیق می‌دهند همان شکل شانزده‌شانزدهی است. مرجع link-options mark را چیزی توصیف می‌کند که بر بسته‌های خروجی رمزنگاری‌شده در لینوکس اعمال می‌شود، یعنی همان سوکتی که باید مسیرش را کنترل کنید. خاموش کردن بارگذاری کانال داده این نمونه را روی مسیر فضای کاربر نگه می‌دارد، جایی که رفتار نشانه همان رفتار توصیف‌شده است.

route-noexec افزودن و حذف خودکار مسیرها توسط OpenVPN را سرکوب می‌کند. چیزی به جای آن نصب نمی‌کند، بنابراین از این لحظه صاحب مسیرها باید هر مسیری را که تونل لازم دارد نگه دارد. اگر پس از تغییر مقصدی خصوصی ناپدید شود، آن سیاست جانشین غایب است، نه نقص در نشانه.

در حین انجام این کار مسیر میزبان برای 198.51.100.25 را در جدول اصلی نگه ندارید. چنین مسیری همان استثنایی را بازمی‌گرداند که طراحی می‌کوشد تنگش کند، و پیش از آن‌که از هیچ‌یک از سیاست‌های زیر پرسیده شود، برای جریان HTTPS برنده می‌شود.

همه چیز دیگر را به جدول تونل بفرستید

وقتی سطح تونل وجود دارد و نشانی‌اش را نگه می‌دارد، سیاست چنین است:

ip -4 route add default dev tun1 src 10.90.0.10 table 47100
ip -4 rule add priority 20000 lookup main suppress_prefixlength 0
ip -4 rule add priority 20001 not fwmark 0x2a lookup 47100
ip -4 rule add priority 20002 not fwmark 0x2a unreachable

قاعده نخست مسیرهای خاص میزبان را دیدنی نگه می‌دارد، از جمله هر شبکه محلی تأییدشده، و در همان حال مسیر پیش‌فرض جدول اصلی را برای این جست‌وجو نادیدنی می‌کند. این تفاوت مهم است: سرکوب پیش‌فرض همان نادیده گرفتن جدول نیست، و استثناهای محلی که هنوز لازم دارید به همین دلیل زنده می‌مانند. آن استثناها را یکی‌یکی بخوانید، به‌جای این‌که فرض کنید نتیجه یک کلید توقف فراگیر است.

ترافیک نشانه‌نخورده سپس به جدول تونل می‌افتد، منبع تونل را برمی‌دارد و از VPN بیرون می‌رود. ترافیک نشانه‌خورده در آزمون fwmark روی دو قاعده بعد شکست می‌خورد و به جست‌وجوی اصلی معمول پایین‌تر در فهرست ادامه می‌دهد، جایی که پیش‌فرض uplink هنوز هست. قاعده پایانی unreachable همان چیزی است که نمی‌گذارد جریانی نشانه‌نخورده وقتی مسیر تونل نیست، بی‌صدا به uplink برگردد. گزینشگر از آغاز تا پایان نشانه است و نشانی مقصد هرگز به تصمیم وارد نمی‌شود.

آن نگهبان را در میان قطع‌شدن‌ها سر جایش نگه دارید و آن را همراه بقیه سیاست نصب کنید، نه دستی. قاعده‌ای که با سطح ناپدید می‌شود سیاست نیست، تصادف است. پاک کردن سیاست وقتی تونل می‌افتد حالت خطا را از «مسدود» به «نشت‌کرده» تغییر می‌دهد، و مسیر تونل کهنه‌ای که بعداً منقضی می‌شود بسیار آسان‌تر از ترافیکی توضیح‌دادنی است که از سطح اشتباه بیرون رفته.

بگذارید مسیر بازگشت همان نشانه را ببیند

نشانه‌های خروجی فقط نیمی از سازوکارند و این همان بخشی است که بیشتر بازتولیدها جا می‌اندازند. پاسخ‌های نشست رمزنگاری‌شده از uplink می‌رسند و تابع اعتبارسنجی مسیر بازگشت‌اند، که می‌پرسد آیا منبع از همان راهی که آمد بازگردانده می‌شود. بی کمک، آن جست‌وجو سیاست نشانه‌نخورده تونل شما را اعمال می‌کند و نتیجه می‌گیرد بسته روی سطح اشتباه است.

اصلاح از آن صاحب دیوار آتش است: نشانه را روی اتصال خروجی ذخیره کنید، آن را روی بسته‌های ورودی منطبق بازگردانید، و پردازش نشانه تأییدشده با منبع را برای مسیر مربوط فعال کنید. این‌که OpenVPN نشانه سوکت می‌گذارد هیچ‌یک از این سه را انجام نمی‌دهد، و دستوری که فقط گزینه‌های کلاینت را فهرست می‌کند ناقص است. آن یکپارچه‌سازی را کتبی بخواهید، چون کم‌دیده‌ترین بخش طراحی است و در بازسازی آسان‌ترین از دست رفتن.

بررسی سهل‌گیرانه مسیر بازگشت هم جانشین نیست. حالت سهل‌گیرانه هنوز به وجود مسیری برای منبع نیاز دارد، و نگهبان unreachable که افزودید برای جست‌وجوهای نشانه‌نخورده یکی را عمداً برمی‌دارد. پیش از تکیه بر این طراحی، یکپارچه‌سازی نشانه اتصال را تمام و بازبینی کنید، و فیلترهای میزبان را پرسش جداگانه بدانید: نشانه یک سیگنال مسیریابی است، نه اجازه. اگر یکپارچه‌سازی نباشد، نشانه نشستی است که برقرار می‌شود و سپس به‌محض رسیدن پاسخ‌ها خاموش می‌شود.

با دو جست‌وجوی مسیر اثباتش کنید

مقایسه کنید هسته برای دو بافت چه تصمیمی می‌گیرد، و به‌جای وضعیت خروج فیلدهای dev و src را بخوانید:

ip -4 route get 198.51.100.25
ip -4 route get 198.51.100.25 mark 0x2a

جست‌وجوی نخست باید با منبع تونل به tun1 حل شود و دومی به uplink. این‌ها جست‌وجوهای مصنوعی‌اند، پس سیاست را اثبات می‌کنند نه فرایند زنده را: مسیر واقعی انتقال کلاینت در حال اجرا را جداگانه تأیید کنید، سپس درخواست HTTPS واقعی با بررسی گواهی روشن بفرستید.

پیش از اعلام پایان، بنویسید طراحی چه چیزهایی را پوشش نمی‌دهد. DNS، IPv6 و چرخه عمر قواعد هر یک تصمیم خود را می‌خواهند، و این نمونه مسیریابی IPv4 است نه پیکربندی کامل حریم خصوصی. ارزشش در گزینشگر است: پاکت استثنای uplink را می‌گیرد، و سرویس معمولی روی همان نشانی لازم نیست آن را به ارث ببرد.

مقالات مرتبط