مسدود کردن یک کلاینت OpenVPN از LAN بدون توقف تونل
آدرس تونل کلاینت را به گواهیاش سنجاق کنید، ترافیک LAN آن را در ابتدای FORWARD بیندازید، سپس IPv6، نشستهای ردیابیشده و بقا پس از راهاندازی مجدد را بررسی کنید.
یک کلاینت روی سرور OpenVPN شما باید دسترسی به LAN را از دست بدهد در حالی که همه تونلهای دیگر برپا میمانند. اگر این را جستوجو کنید، پاسخ برتر معمولاً میگوید دیمن نمیتواند این کار را بکند، که فقط نیمی درست است: OpenVPN دیوار آتش برای هر کلاینت ندارد، اما میزبانی که تونل را پایان میدهد از قبل بستهها را فیلتر میکند. دو تصمیمی که اهمیت دارند هویتی است که مسدود میکنید و جای قاعده. اگر این دو را درست انجام دهید، تغییر به یک خط تبدیل میشود که میتوانید بیازمایید و بردارید.
کلاینت را پیش از نوشتن قاعده سنجاق کنید
OpenVPN آدرسهای تونل را از یک استخر اجاره میدهد، پس 10.8.0.6 یک صندلی است نه یک شخص. وقتی نشست تمام میشود اجاره برمیگردد و میتواند به اتصال بعدی داده شود، یعنی قاعدهای که علیه آن آدرس نوشته شده صندلی را دنبال میکند نه کاربر را. پس اول تصمیم بگیرید واقعاً چه چیزی را مسدود میکنید: آدرسی برای یک آزمایش کوتاه، یا گواهیای برای کسی که میخواهید بیرون بماند.
برای بستن آدرس به گواهی، فایلی در پوشهای که client-config-dir نام میبرد بسازید و دقیقاً common name گواهی را به فایل بدهید. یک دستور در آن بگذارید، ifconfig-push 10.8.0.6 255.255.255.0، و آن کلاینت همان آدرس تونل را در اتصالهای دوباره نگه میدارد. برای اثرگذاری این کار دو تنظیم باید وجود داشته باشد: client-config-dir باید در پیکربندی سرور اعلام شود، و آدرس فرستادهشده باید در زیرشبکهای باشد که سرور بتواند مسیریابی کند. اگر یکی کم باشد، فایل بدون خطا نادیده گرفته میشود و این آزمون دیوار آتش بعدی را گمراهکننده میکند.
یک مسدودسازی موقت میتواند از آدرس استخر استفاده کند، به شرطی که تیکت ثبت کند کدام نشست در آن زمان آن را داشته است.
ترتیب تعیین میکند که افتادن اجرا میشود یا نه
روی دروازه Linux که میان تونل و LAN ارسال میکند، بستهها از زنجیره FORWARD میگذرند. دستور زیر را مانند یک جمله بخوانید: در ابتدای FORWARD درج کن، ترافیکی را که از tun0 وارد میشود، از همان یک میزبان، با مقصد زیرشبکه LAN تطبیق بده و بینداز.
iptables -I FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP-I همان چیزی است که قاعده را به اجرا درمیآورد. اگر با -A افزوده شود، زیر هر پذیرش گسترده برای زیرشبکه تونل میافتد و هرگز بستهای نمیبیند. جای آن را با iptables -vnL FORWARD --line-numbers بررسی کنید و شمارندهها را هم بخوانید: افتادنی در بالا که چیزی نمیشمارد یعنی ترافیک از مسیر دیگری میرسد.
آدرس LAN خود دروازه مسیر دیگری است. بستههای فرستادهشده به خود جعبه به INPUT میروند نه FORWARD، پس کلاینت میتواند میزبان LAN را از دست بدهد و باز هم صفحه مدیریت روتر را باز کند. وقتی این مهم است قاعده INPUT متناظر را اضافه کنید.
آنچه فیلتر نمیتواند ببیند
فیلتر کردن هنگام ارزیابی بسته رخ میدهد، پس یک نشست TCP برقرارشده میتواند تا بستهشدن یا بازنشانی ادامه یابد. اگر مسدودسازی باید فوراً اثر کند، جریانهای ردیابیشده آن منبع را با conntrack -D -s 10.8.0.6 پس از درج قاعده پاک کنید. اگر چند ثانیه همپوشانی پذیرفتنی است، آن انتخاب را ثبت کنید نه اینکه آن را تلویحی بگذارید. در هر حال، نفر بعدی باید بداند قاعده ترافیک زنده را متوقف میکند یا فقط اتصالهای تازه را.
ترافیک همتایان هرگز به دیوار آتش میزبان نمیرسد. با فعال بودن client-to-client، OpenVPN آن بستهها را درون دیمن ارسال میکند، پس نه FORWARD و نه INPUT آنها را میبیند. تنها راهحلها خاموش کردن client-to-client یا پذیرفتن این است که همتایان میتوانند به هم برسند؛ قاعده iptables آن ترافیک را نخواهد دید.
IPv6، فریمور و بقا پس از راهاندازی مجدد
قاعده IPv4 چیزی درباره IPv6 نمیگوید. اگر تونل و LAN هر دو خانواده را حمل کنند، قاعده معادل باید در ip6tables وجود داشته باشد، یا در مجموعه قواعد nftables که سیاست را روی آن میزبان در اختیار دارد. فریمور روتر اغلب netfilter را پشت انتزاع خود پنهان میکند، پس نحو و نام جدولهای کپیشده از انجمن ممکن است اعمال نشود.
روی OpenWrt، مسیر مستند یک ورودی پیکربندی دیوار آتش است نه یک خط iptables دستنویس، و خط دستنویس میتواند هنگام بارگذاری دوباره دیوار آتش ناپدید شود. توزیعهای دیگر قواعد را از طریق netfilter-persistent، یک واحد بوت یا انبار فروشنده بازمیگردانند و این سازوکارها قابل تعویض نیستند. هر کدام را برگزیدید با یک راهاندازی مجدد اثبات کنید، زیرا بارگذاری دوباره مسیر دیگری را تمرین میکند.
بررسی بر اساس مسیر، سپس بازگشت پاک
هر مسیر را جداگانه بیازمایید، زیرا یک بررسی موفق بقیه را پنهان میکند. کلاینت مسدودشده باید همچنان از طریق تونل به اینترنت برسد اما در برابر میزبان LAN شکست بخورد، کلاینت دوم باید به همان میزبان برسد، و آدرس دروازه و مسیر همتا هر کدام مشاهده خود را نیاز دارند. نتایج را کنار قاعده بنویسید تا تغییر بعدی خط پایه داشته باشد. جدول زیر مجموعهای است که ارزش نگهداشتن در تیکت را دارد.
| مسیر | انتظار با قاعده | وقتی شکست میخورد |
|---|---|---|
| کلاینت مسدودشده به میزبان LAN | بدون پاسخ | قاعده زیر یک پذیرش است، یا منبع مطابقت ندارد |
| کلاینت مسدودشده به اینترنت | از tun0 کار میکند | قاعده بیش از حد گسترده است، بدون تطبیق مقصد |
| کلاینت دوم به همان میزبان LAN | کار میکند | قاعده بیش از میزبان موردنظر را تطبیق داد |
| کلاینت مسدودشده به آدرس LAN دروازه | فقط با قاعده INPUT متناظر مسدود میشود | قاعده INPUT وجود ندارد |
| کلاینت مسدودشده به آدرس تونل یک همتا | همچنان کار میکند | client-to-client فعال است و بیرون از گستره دیوار آتش |
بازگشت یک حذف بر اساس مشخصه است نه flush: iptables -D FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP دقیقاً همان ورودی را برمیدارد و بقیه زنجیره را دستنخورده میگذارد. همان خط را از هر فایلی که قواعد را در بوت بازمیگرداند بردارید، آن را دوباره بارگذاری کنید و تأیید کنید که کلاینت دوباره به میزبان LAN میرسد. flush کردن FORWARD قواعدی را هم که ننوشتهاید باطل میکند، و این بازگشت را به حادثه دوم تبدیل میکند.
پیش از بستن تیکت، سه چیز را تأیید کنید: آدرس سنجاقشده با گواهی مطابقت دارد، قاعده بالای پذیرشها با شمارنده غیرصفر است، و فایل ماندگاری همان قاعدهای را دارد که آزمودید. اگر یکی از اینها نباشد، مسدودسازی توهمی در یک نشست shell است.