چرا قلاب فایروال VPN همان قاعده را دو بار اضافه میکند
اتصال دوباره میتواند قلاب شما را دوباره اجرا کند، پس برای حالت مطلوب طراحی کنید: زنجیرههای متعلق به خود، آزمایشی پیش از درج، یک تغییر سریالشده و برچیدن محدود.
قلاب بار اول کار میکند، و پس از سه اتصال دوباره زنجیره سه نسخه از همان قاعده را نگه میدارد. هیچ چیز با صدای بلند شکست نخورد؛ اسکریپت هر بار که اجرا میشد فقط همان کاری را میکرد که به آن گفته شده بود. قلاب VPN یک عملیات پیکربندی است که میتواند بیش از یک بار اجرا شود، پس به مالک، حالت مطلوب و تغییر سریالشده نیاز دارد. این ترتیب را دنبال کنید تا تکرارها متوقف شوند.
پیش از نوشتن هر قاعده، برای قواعد یک مالک تعیین کنید
پیش از نوشتن حتی یک قاعده تصمیم بگیرید این یکپارچهسازی مالک کدام زنجیره یا جدول است. یک زنجیره اختصاصی که قلاب آن را میسازد و خالی میکند روشنترین شکل مالکیت است، زیرا پاکسازی میتواند آن زنجیره را بدون دست زدن به سیاست دیگران حذف کند. اگر ناچارید قواعدی به زنجیره مشترک اضافه کنید، آنها را با یک نظر علامت بزنید تا جستجوی بعدی دقیقاً قواعد شما را پیدا کند. مالکیت همان چیزی است که برچیدن را ایمن میکند، و برچیدن همان بخشی است که بیصدا شکست میخورد.
iptables -N VPN_HOOK 2>/dev/null || true
iptables -C INPUT -j VPN_HOOK 2>/dev/null || iptables -I INPUT -j VPN_HOOK
iptables -S VPN_HOOK
نظر در اینجا تزئین نیست. تفاوت میان حذف قاعده شما و حذف قاعدهای است که تصادفاً شبیه به نظر میرسد، و در مجموعه قواعد ذخیرهشده باقی میماند. نظر را یک بار در یک متغیر بنویسید و همان رشته را در هر فرمانی که اضافه میکند، آزمایش میکند یا حذف میکند به کار ببرید.
بهجای افزودن دوباره، حالت مطلوب را آزمایش کنید
بنویسید تا وقتی تونل بالاست چه چیزی باید وجود داشته باشد: کدام واسطها، کدام مبدأ و مقصد، کدام پروتکل و کدام درگاه. سپس هر قاعده را بهصورت آزمایشی که پس از آن درج میآید بیان کنید، تا اجرای دوم قاعده را پیدا کند و هیچ کاری نکند. فرمان بررسی وقتی قاعده وجود دارد با صفر خارج میشود، و این دقیقاً همان سیگنالی است که اسکریپت لازم دارد. مرجع iptables شکلهای بررسی، افزودن و درج مورد استفاده در اینجا را مستند میکند.
iptables -C VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT ||
iptables -A VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
مراقب موقعیت باشید. بررسی یک قاعده و درج آن در ابتدا میتواند یک اجازه را پیش از یک رد عمدی که قبلاً اول میآمد جابهجا کند، بنابراین اجرای دوم رفتار را تغییر میدهد حتی بدون اینکه چیزی اضافه کند. داخل زنجیره خودتان به انتها اضافه کنید و ترتیب را با جای پرش به آن زنجیره کنترل کنید. اگر ترتیب درون زنجیره مهم است، زنجیره را از یک فهرست شناختهشده دوباره بسازید نه اینکه قاعدهبهقاعده وصلهاش کنید.
اگر قاعدهای که لازم دارید بهصورت آزمایش پایدار بیان نمیشود، توقف کنید. این معمولاً یعنی حالت مطلوب هنوز مبهم است.
بهجای امید به دوام، تغییر را سریال کنید
دو فراخوانی قلاب میتوانند همپوشانی داشته باشند و هر دو میتوانند پیش از آنکه یکی اضافهاش کند، نبودن قاعده را ببینند. گزینه انتظار xtables فرمان را وادار میکند برای قفل صبر کند، اما دنباله بررسیسپسافزودن را در دو فرمان اتمی نمیکند. کل عملیات را با قفل خودتان سریال کنید، یا از مدیریتی استفاده کنید که دسته اعلامشده را بهصورت یک تراکنش اعمال میکند. nftables دومی را میتواند، و این یکی از دلایل ترجیح آن روی میزبانهایی است که در دسترس است.
flock /run/vpn-hook.lock /usr/local/sbin/vpn-firewall-apply
nft -f /etc/nftables/vpn-hook.nft
هر سازوکاری که انتخاب کنید، بخش بحرانی را کوتاه نگه دارید و آن را دوبارهورودی کنید: قلابی که در میانه شکست میخورد باید اجرای دوبارهاش ایمن باشد. نتیجه را ثبت کنید تا اجرای تکراری در ژورنال دیده شود نه اینکه از شمار قواعد استنتاج شود. اگر دو ناظر متفاوت میتوانند قلاب را فراخوانی کنند، اول آن را درست کنید؛ هیچ قفلی دو مالک را درست نمیکند.
فقط آنچه را مالک آن هستید برچینید
برچیدن باید اتصال جانشین را از اتصالی که بازنشسته کرده تشخیص دهد، و باید رویدادی را دوام آورد که هرگز پاکسازی آرامی نمیگیرد. با همان شناسههایی که برای افزودن به کار برديد حذف کنید، و هرگز زنجیره مشترک را برای سادهکردن پاکسازی خالی نکنید. پس از توقف سخت، در شروع بعدی یک گذر تطبیق اجرا کنید نه اینکه فرض کنید قلاب پایین اجرا شده است.
iptables -D VPN_HOOK -i tun0 -p tcp --dport 443 -j ACCEPT
iptables -F VPN_HOOK
ip -brief link show type tun
عمر واسط هم بخشی از طراحی است. اتصال دوباره میتواند دستگاهی با نامی متفاوت بسازد، بنابراین قاعدهای که نام تونل دوم را سختکد میکند در حالی که هنوز معتبر به نظر میرسد کهنه میشود. هویتی را ترجیح دهید که خود اتصال آشکار میکند، و در هر اجرا دوباره آن را بخوانید. سه رویداد را جداگانه آزمایش کنید: اتصال تکراری، اتصال جانشین و خاموششدن. ترافیک مجاز باید هر سه را بدون تکرار دوام آورد، و سرویسهای نامرتبط باید دستنخورده بمانند.
قدمزدن زمانی پایان مییابد که قلاب مالکی، آزمایشی برای هر قاعدهای که اضافه میکند، یک مسیر سریالشده و برچیدنی داشته باشد که فقط حالت خودش را حذف میکند. قلابی که اجرای دوبارهاش ایمن است بیشتر از قلابی میارزد که یک بار هوشمند است.