← شروع آموزش

WIUNIX ACADEMY

تغییر اتمیک nftables؛ برگشت زمان‌دار رو قبل از قطع دسترسی تمرین کن

صفحهٔ 3 از 4؛ قبل از ادامه، مراحل قبلی و چیزهایی رو که لازم داری مرور کن.

آموزش متناسب با محیط تو

کجا اجرا می‌کنی؟

سیستم‌عامل و نسخهٔ سرورت رو انتخاب کن تا مراحل، دستورها و راه‌حل‌های همون محیط رو ببینی.

AlmaLinux 9بررسی‌شده با مستندات رسمی ·

آموزش متناسب با مقادیر تو

تنظیمات این آموزش

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

اگر آی‌پی، دامنه یا پورت‌های نمونه با سرورت فرق دارن، بخش تنظیمات پایین رو باز کن. مقدارها رو عوض کن و «اعمال در آموزش» رو بزن؛ بعد دستورهای تازه رو کپی کن.

تنظیم مقادیر برای محیط من8 مقدار قابل‌تغییر
09

قدم بعدی

اول برگشت رو مسلح کن، بعد قانون عمداً خراب رو اعمال کن

کل این پنل رو یک‌جا اجرا کن. پوستهٔ root قفل انحصاری می‌گیره، پیشنهاد رو دوباره بررسی می‌کنه، timer مستقل رو می‌سازه و فعال‌بودنش رو قبل از بارگذاری می‌سنجه. سرویس برگشت همان قفل رو می‌گیره؛ اگر مهلت وسط اعمال کند برسد، منتظر آزادشدن قفل می‌مونه و بعد قانون قبلی رو برمی‌گردونه. این‌طوری برگشت زودتر اجرا نمی‌شه که بعدش یک پیشنهاد دیررس دوباره ارتباط رو قطع کنه.

قفل فقط دو دستور همین تمرین رو هماهنگ می‌کنه؛ firewalld، اپراتور دیگر یا برنامه‌ای که قفل رو رعایت نمی‌کنه متوقف نمی‌شه. وقتی timer مسلحه، فایل‌ها، نام namespace و نسخهٔ برگشت رو عوض نکن. قطع ترمینال معمولاً timer سیستم رو لغو نمی‌کنه، ولی reboot، خرابی مدیر سرویس، حذف namespace یا شکست بازگردانی همچنان بازیابی رو از کار می‌ندازه.

انتظار داریم ping فوری پاسخ echo نگیره. کد خروج ۱ به‌تنهایی می‌تونه از قطع‌شدن مسیر در جای دیگری باشه؛ فقط وقتی افت رو به این قانون نسبت بده که شمارندهٔ drop موردنظر هم بالا رفته باشه. خطای دیگرِ ping پنل رو متوقف می‌کنه. برگشت رو مسلح نگه دار. اگر ping جواب داد، ممکنه timer قبلاً قانون سالم رو برگردونده باشه یا پیشنهاد روی مسیر بررسی‌شده اثر نکرده باشه؛ وضعیت واقعی رو بخون.

bash

ترمینال ماشین مجازی آزمایشی قابل‌حذف

ip_bin=$(sudo sh -c 'command -v ip') || exit 1
nft_bin=$(sudo sh -c 'command -v nft') || exit 1
flock_bin=$(sudo sh -c 'command -v flock') || exit 1
sudo /bin/sh -c 'set -eu
exec 9>"$1/change.lock"
"$4" -x 9
test "$(systemctl show -p LoadState --value "$2.timer")" = not-found
test "$(systemctl show -p LoadState --value "$2.service")" = not-found
"$5" netns exec "$6" "$7" -c -f "$1/candidate.nft"
systemd-run --unit="$2" --on-active="$3"s --timer-property=AccuracySec=1s --property=Type=oneshot --property=RemainAfterExit=yes "$4" -x "$1/change.lock" "$5" netns exec "$6" "$7" -f "$1/rollback.nft"
systemctl is-active --quiet "$2.timer"
"$5" netns exec "$6" "$7" -f "$1/candidate.nft"
' sh '/var/lib/academy-nft-rollback-lab' 'academy-nft-rollback' '90' "$flock_bin" "$ip_bin" 'academy-nft-server' "$nft_bin" || exit 1
if sudo ip netns exec 'academy-nft-client' ping -c 1 -W 2 '192.0.2.1'; then
  printf 'UNEXPECTED: candidate did not block the lab probe\n' >&2
  exit 1
else
  probe_status=$?
  if test "$probe_status" -ne 1; then
    printf 'Probe error, not evidence of a firewall drop: exit=%s\n' "$probe_status" >&2
    exit "$probe_status"
  fi
  printf 'No echo reply; inspect the intended drop counter; leave rollback armed\n'
fi
sudo ip netns exec 'academy-nft-server' nft -n list table inet '"academy_guard"' || exit 1
systemctl list-timers --all 'academy-nft-rollback.timer'
از کجا بفهمم درست انجام شده؟

timer قبل از یک تغییر اتمیک جدول مسلح شده و وقتی قانون drop عمدی فعاله، بررسی تازهٔ کلاینت قطع می‌شه.

10

قدم بعدی

بعد از مهلت، خود مسیر رو بسنجیم

مدت انتخاب‌شده رو صبر کن و بعد سرویس برگشت، جدول و بررسی تازهٔ کلاینت رو ببین. timer نسبی زمان‌بندی بلادرنگ نیست؛ اگر نتیجه هنوز نرسیده، تأخیر مدیر سرویس و قفل رو در نظر بگیر. رسیدن نوبت به معنی موفق‌شدن دستورش نیست.

فقط وقتی بازیابی رو قبول کن که سرویس موفق شده، مجوز اولیه برگشته و بررسی تازه جواب داده. این نتیجهٔ ICMP در آزمایش است؛ ثابت نمی‌کنه نشست SSH عملیاتی یا ورود SSH تازه از یک تغییر واقعی فایروال جان سالم برده.

bash

ترمینال ماشین مجازی آزمایشی قابل‌حذف

sleep '90'
sudo systemctl show 'academy-nft-rollback.service' -p ActiveState -p Result -p ExecMainStatus
sudo journalctl -u 'academy-nft-rollback.service' --no-pager -n 40
test "$(systemctl show -p ActiveState --value 'academy-nft-rollback.service')" = active || exit 1
test "$(systemctl show -p SubState --value 'academy-nft-rollback.service')" = exited || exit 1
test "$(systemctl show -p Result --value 'academy-nft-rollback.service')" = success || exit 1
test "$(systemctl show -p ExecMainStatus --value 'academy-nft-rollback.service')" = 0 || exit 1
sudo ip netns exec 'academy-nft-server' nft -n list table inet '"academy_guard"'
sudo ip netns exec 'academy-nft-client' ping -c 2 -W 2 '192.0.2.1' || exit 1
از کجا بفهمم درست انجام شده؟

بازگردانی با کد صفر تموم شده، قانون مجوز اولیه برگشته و بررسی تازهٔ کلاینت جواب می‌ده.

11

قدم بعدی

اگر برگشت خودکار نشد، فقط همین نمونه رو از کنسول برگردون

از ابزار مدیریت ماشین مجازی، کنسول خود همان ماشین آزمایشی رو باز کن و خطای برگشت رو ببین. این شل ماشین لینوکسی بیرون از فضای شبکهٔ فیلترشده قرار داره. پنل پایین قفل هماهنگی همین تمرین رو می‌گیره، فقط جدول ثبت‌شده رو بارگذاری می‌کنه و بعد ارتباط رو می‌سنجه. فایل‌ها و شواهد timer برای پیداکردن علت باقی می‌مونن.

اگر namespace یا جدول حذف شده یا شیء دیگری صاحب نام شده، ادامه نده؛ نسخهٔ برگشت رو برای وضعیتی ناشناخته دست‌کاری نکن. اگر جدول مورد انتظار پیدا نشه، بازگردانی شکست می‌خوره. این مجوزی برای خالی‌کردن قانون‌های میزبان یا خاموش‌کردن فایروال نیست.

bash

ترمینال ماشین مجازی آزمایشی قابل‌حذف

ip_bin=$(sudo sh -c 'command -v ip') || exit 1
nft_bin=$(sudo sh -c 'command -v nft') || exit 1
sudo flock -x '/var/lib/academy-nft-rollback-lab/change.lock' "$ip_bin" netns exec 'academy-nft-server' "$nft_bin" -f '/var/lib/academy-nft-rollback-lab/rollback.nft' || exit 1
sudo ip netns exec 'academy-nft-client' ping -c 2 -W 2 '192.0.2.1' || exit 1
از کجا بفهمم درست انجام شده؟

برگشت دستیِ همان جدول موفق شده و ارتباط برگشته؛ وگرنه خطای دقیق بازگردانی هنوز باز است.

از همان بخشی که شکست خورده پیگیری کن

هر بررسی پایین فقط وضعیت آزمایش یا واحد نام‌برده رو می‌خونه. خطا رو نگه دار و کمبود مجوز رو با مسئول ماشین مجازی حل کن. هیچ دستور این بخش حفاظت SELinux/AppArmor رو خاموش نمی‌کنه، مدیر فایروال میزبان رو عوض نمی‌کنه و سیاست بستهٔ میزبان رو بازتر نمی‌کنه.

ساخت namespace اجازه داده نمی‌شه

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

bash
uname -r
cat /proc/1/comm
sudo ip netns list
sudo journalctl -k --since '-10 min' --no-pager -n 60
بررسی nft خطا می‌ده

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

bash
sudo nft --version
sudo ip netns exec 'academy-nft-server' nft -n list table inet '"academy_guard"'
sudo ip netns exec 'academy-nft-server' nft -c -f '/var/lib/academy-nft-rollback-lab/candidate.nft'
نوبت timer رسید ولی ارتباط برنگشت

نتیجهٔ دستور، لاگ و جدول فعلی رو ببین. نبود namespace، نرسیدن به فایل یا خطای بازگردانی با تأخیر زمان‌بندی فرق داره. قبل از برگشت کنسولی مطمئن شو عملیات دیگر همین تمرین قفل رو نگه نداشته.

bash
systemctl show 'academy-nft-rollback.timer' 'academy-nft-rollback.service' -p Id -p ActiveState -p SubState -p Result -p ExecMainStatus
sudo journalctl -u 'academy-nft-rollback.service' --no-pager -n 60
sudo ip netns exec 'academy-nft-server' nft -n list table inet '"academy_guard"'
بررسی اولیه یا برگشتی شکست می‌خوره ولی شمارندهٔ drop بالا نمی‌ره

وضعیت لینک، آدرس‌ها و مسیر مستقیم هر دو فضا رو بررسی کن. شکست بررسی ممکنه از آدرس‌دهی بیاد، نه برخورد با فیلتر. برای پنهان‌کردن توپولوژی اشتباه، به میزبان مسیر اضافه نکن و forwarding رو روشن نکن.

bash
sudo ip -n 'academy-nft-server' -br address
sudo ip -n 'academy-nft-client' -br address
sudo ip -n 'academy-nft-client' route get '192.0.2.1'
sudo ip netns exec 'academy-nft-server' nft -n list table inet '"academy_guard"'

از این تمرین چه چیزی وارد برنامهٔ تغییر واقعی می‌شه؟

قبل از هر تغییر مجزای مجاز روی میزبان، مدیر واحدِ مسئول و محدودهٔ دقیق سیاست رو بشناس، وضعیت قبلیِ نسخه‌دار رو نگه دار و کنسول خارج از مسیر شبکهٔ درحال‌تغییر رو واقعاً در دسترس داشته باش. ترمینال SSH دوم کمک می‌کنه، ولی کافی نیست؛ قانون اتصال برقرار می‌تونه نشست فعلی رو زنده نگه داره و هم‌زمان همهٔ ورودهای تازه رو قطع کنه. ورود مدیریتی تازه و مستقل، مسیر برنامه، IPv6، DNS و ترافیک عبوری و کانتینر رو از مبدأ واقعی خودشان بسنج.

میزبانی با سیاست پیش‌فرض drop به مجوز بررسی‌شدهٔ مبدأ مدیریت و رفتار اتصال established/related قبل از اعمال نیاز داره. قانون ICMP این تمرین جای اون نیست. accept جدول تو هنوز می‌تونه در زنجیرهٔ دیگری به drop برسه؛ نام جدول مستقل، هم‌زیستی رو خودکار حل نمی‌کنه. روش پشتیبانی‌شدهٔ firewalld/UFW یا برنامه رو نگه دار و پشت سر Docker، Fail2ban و CrowdSec جدول‌های متعلق به آن‌ها رو عوض نکن.

در تغییر موفق واقعی، برگشتِ معلق فقط بعد از تمام بررسی‌های پذیرش و کنترل تغییر هم‌زمان لغو می‌شه. اگر بازگردانی شروع شده، اول نتیجهٔ واقعی اون رو روشن کن؛ بعد بگو کدام سیاست نهایی شده. لغو timer، قانون فعال و ماندگاری بعد از بوت سه وضعیت جدا هستن. این آموزش عمداً می‌ذاره تغییر ناموفق آزمایشی برگرده و فرمان عمومی برای نهایی‌کردن فایروال عملیاتی نمی‌ده.

12

قدم بعدی

ماندگاری رو جدا ببین؛ قانون تمرین رو به بوت وصل نکن

قانون‌های موقت nft با حذف فضای شبکه از بین می‌رن و این تمرین سیاست بوت نمی‌نویسه. قبل از استفادهٔ واقعی، فایل سرویس نصب‌شده رو بخون. اوبونتو/دبیان و آرچ معمولاً فایل اصلی nftables خودشان رو می‌خونن؛ خانوادهٔ RHEL از فایل include در sysconfig استفاده می‌کنه. یادداشت محیط مسیر بومی رو مشخص می‌کنه، ولی مرجع آخر همان واحد نصب‌شده است.

شروع، بارگذاری دوباره و توقف سرویس ممکنه دستورهای گسترده اجرا کنه. مثلاً واحد دبیانیِ بررسی‌شده موقع توقف، کل ruleset میزبان رو خالی می‌کنه. برای جمع‌کردن یک جدول داخل namespace، سرویس nftables میزبان رو متوقف یا دوباره راه‌اندازی نکن. در firewalld، حالت موقت و دائمی جداست؛ NetworkManager هم ممکنه zone اتصال رو دوباره اعمال کنه. تغییر مجاز واقعی رو فقط از مدیر مسئولش ماندگار کن و بازیابی بعد از reload/reboot رو اول در نسخهٔ آزمایشی قابل‌حذف بسنج.

bash

ترمینال ماشین مجازی آزمایشی قابل‌حذف

systemctl cat nftables.service
systemctl show nftables.service -p FragmentPath -p DropInPaths -p ExecStart -p ExecReload -p ExecStop
systemctl show firewalld.service ufw.service NetworkManager.service -p Id -p LoadState -p ActiveState
از کجا بفهمم درست انجام شده؟

بارگذار واقعی، فایل‌ها و رفتار چرخهٔ سرویس معلوم شده؛ قانون آزمایش ماندگار نشده و سرویسی تغییر نکرده.

همهٔ آموزش‌های آکادمی ↗