امن سازی سرور لینوکس: چک لیست عملی برای Ubuntu و RHEL
چک لیست امن سازی سرور لینوکس در Debian، Ubuntu و RHEL؛ وصلهی خودکار، سرویسها، sudo، فایروال، fail2ban، sysctl، SELinux و AppArmor، auditd، AIDE و Lynis.
در این صفحه
- ۱. به روزرسانی خودکار وصلههای امنیتی
- ۲. سرویسها و بستههای اضافه
- ۳. کاربران، sudo و سیاست رمز
- ۴. SSH
- ۵. فایروال: همه چیز بسته، مگر آن چه لازم است
- ۶. fail2ban
- ۷. مجوز فایلها و umask
- ۸. گزینههای mount برای /tmp و /dev/shm
- ۹. تنظیمات kernel با sysctl
- ۱۰. SELinux و AppArmor
- ۱۱. لاگ، audit و ارسال لاگ
- ۱۲. همگام سازی زمان با chrony
- ۱۳. بررسی یکپارچگی فایلها با AIDE
- ۱۴. بکاپ
- ۱۵. اسکن با Lynis و مقایسه با CIS
- چک لیست نهایی
امن سازی سرور لینوکس یعنی کوچک کردن سطح حمله و ثبت هر اتفاق: وصلههای امنیتی خودکار نصب شوند، فقط سرویسها و پورتهای لازم باز بمانند، هر مدیر با حساب شخصی و sudo کار کند، ورود SSH فقط با کلید باشد، SELinux یا AppArmor فعال بماند و لاگها روی سرور دیگری هم ذخیره شوند. این چک لیست هر مورد را برای Debian، Ubuntu، RHEL، Rocky و Alma با دستور و روش بررسی میآورد.
۱. به روزرسانی خودکار وصلههای امنیتی
Ubuntu: بستهی unattended-upgrades از پیش نصب است و روزانه فقط وصلههای امنیتی را نصب میکند. فعال بودنش را بررسی کنید:
cat /etc/apt/apt.conf.d/20auto-upgrades
sudo unattended-upgrade --dry-runخروجی دستور اول باید APT::Periodic::Update-Package-Lists "1"; و APT::Periodic::Unattended-Upgrade "1"; باشد.
Debian: ممکن است بسته نصب یا فعال نباشد:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgradesRHEL، Rocky و Alma: در بخش [commands] فایل /etc/dnf/automatic.conf مقدار upgrade_type = security را بگذارید و timer نصب را فعال کنید:
sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic-install.timerوصلهی kernel تا ریبوت اثر ندارد. در Ubuntu فایل /var/run/reboot-required و در RHEL دستور sudo dnf needs-restarting -r نیاز به ریبوت را نشان میدهد. ریبوت خودکار (Automatic-Reboot در Ubuntu و reboot در dnf-automatic) پیش فرض خاموش است؛ برای ریبوت پنجرهی زمانی بگذارید.
۲. سرویسها و بستههای اضافه
هر سرویسی که گوش میدهد یک در ورودی است:
sudo ss -tulpn
systemctl list-unit-files --type=service --state=enabled
sudo systemctl disable --now cups.service
sudo systemctl mask cups.servicemask جلوی روشن شدن دوبارهی سرویس به عنوان وابستگی را هم میگیرد. بستهی بیاستفاده را کلاً حذف کنید (apt purge یا dnf remove).
۳. کاربران، sudo و سیاست رمز
- هر مدیر حساب شخصی دارد و رمز root بین افراد پخش نمیشود.
- دسترسی مدیریتی از طریق گروه
sudo(Debian و Ubuntu) یاwheel(خانوادهی RHEL) داده میشود. - قانونهای اضافه را با
visudoدر فایل جدا زیر/etc/sudoers.d/بنویسید؛ خطای نحوی در sudoers میتواند sudo را از کار بیندازد.
awk -F: '$3 == 0 {print $1}' /etc/passwd # فقط root باید باشد
sudo usermod -aG sudo ali # Debian و Ubuntu
sudo usermod -aG wheel ali # RHEL، Rocky و Alma
sudo visudo -f /etc/sudoers.d/ops
sudo chage -E 0 olduser # غیرفعال کردن حساب بدون حذفبرای رمزهای محلی، ماژول pam_pwquality حداقل کیفیت را اجبار میکند. در Debian و Ubuntu بستهی libpam-pwquality را نصب کنید؛ در خانوادهی RHEL ماژول از پیش در PAM فعال است. در /etc/security/pwquality.conf:
minlen = 14
minclass = 3
dictcheck = 1
enforce_for_rootبدون enforce_for_root، اگر root رمز ضعیفی بگذارد فقط هشدار میگیرد.
۴. SSH
SSH مهمترین در ورودی سرور است: ورود فقط با کلید، بستن ورود root و رمز عبور و محدود کردن آن به IPهای مدیریتی. جزئیات و ترتیب امن اعمال تغییرات در راهنمای سخت سازی SSH آمده است.
۵. فایروال: همه چیز بسته، مگر آن چه لازم است
روی هر سرور فقط یکی از ufw، firewalld یا nftables را مدیریت کنید و قبل از فعال کردن فایروال، قانون SSH را اضافه کنید.
ufw (Ubuntu): نصب است ولی پیش فرض خاموش است.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 198.51.100.0/24 to any port 22 proto tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbosefirewalld (RHEL، Rocky و Alma): zone پیش فرض public هر ورودی را رد میکند، به جز ICMP و سرویسهای فهرست شده (پیش فرض ssh، dhcpv6-client و cockpit).
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --remove-service=cockpit # اگر از Cockpit استفاده نمیکنید
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reloadnftables (Debian): فایل /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state vmap { established : accept, related : accept, invalid : drop }
iifname "lo" accept
meta l4proto { icmp, ipv6-icmp } accept
ip saddr 198.51.100.0/24 tcp dport 22 accept
tcp dport 443 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
}
}sudo apt install nftables
sudo nft -c -f /etc/nftables.conf # فقط بررسی نحو
sudo systemctl enable --now nftablesflush ruleset همهی قانونهای موجود را پاک میکند، از جمله قانونهایی که Docker یا libvirt ساختهاند؛ روی چنین سرورهایی این قالب را مستقیم به کار نبرید. ICMPv6 را نبندید، چون IPv6 بدون آن کار نمیکند.
۶. fail2ban
fail2ban بعد از چند تلاش ناموفق IP را موقتاً میبندد؛ وقتی ورود SSH فقط با کلید است، بیشتر لاگ و بار را کم میکند. نصب: sudo apt install fail2ban یا در خانوادهی RHEL از مخزن EPEL با sudo dnf install fail2ban. فایل jail.conf را ویرایش نکنید و /etc/fail2ban/jail.local بسازید:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 198.51.100.0/24
[sshd]
enabled = true
backend = systemdsudo systemctl enable --now fail2ban
sudo fail2ban-client status sshdbackend = systemd لاگ را از journald میخواند و روی سیستمی که /var/log/auth.log ندارد (مثل Debian 12 به بعد بدون rsyslog) لازم است؛ اگر سرویس با آن بالا نیامد، بستهی python3-systemd را نصب کنید.
۷. مجوز فایلها و umask
sudo find / -xdev -type f -perm -4000 2>/dev/null # فایلهای SUID
sudo find / -xdev -type f -perm -0002 2>/dev/null # فایلهای قابل نوشتن برای همه
sudo rpm -Va # RHEL: مقایسهی فایلها با بسته
sudo dpkg --verify # Debian و Ubuntuفایل SUID ناآشنا، در مقایسه با یک سرور تازه نصب شده، نشانهی خطر است. روی سرورهای حساس umask را از 022 به 027 برسانید (کلید UMASK در /etc/login.defs یا پروفایل shell) تا فایلهای تازه برای دیگران خواندنی نباشند.
۸. گزینههای mount برای /tmp و /dev/shm
/tmp و /dev/shm برای همه قابل نوشتناند و مهاجم معمولاً ابزارش را آنجا میگذارد؛ گزینههای nodev، nosuid و noexec این راه را تنگتر میکنند. در Debian 13 و Ubuntu 26.04 مسیر /tmp به طور پیش فرض tmpfs است (در Debian تا ۵۰ درصد RAM) و واحد tmp.mount آن را با nosuid,nodev ولی بدون noexec mount میکند. وضعیت فعلی:
findmnt /tmp /dev/shmبرای افزودن noexec، این خطها را در /etc/fstab بگذارید (بر tmp.mount مقدم است؛ size را متناسب با RAM تعیین کنید):
tmpfs /tmp tmpfs rw,nosuid,nodev,noexec,size=2G,mode=1777 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0sudo systemctl daemon-reload
sudo mount -o remount /tmp
sudo mount -o remount /dev/shmاگر /tmp تا حالا mount جدا نبوده (مثلاً در خانوادهی RHEL)، remount خطا میدهد؛ یک بار ریبوت کنید تا tmpfs از ابتدای بوت روی /tmp قرار بگیرد.
۹. تنظیمات kernel با sysctl
فایل /etc/sysctl.d/99-hardening.conf:
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.tcp_syncookies = 1
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1sudo sysctl --system
sysctl net.ipv4.conf.all.rp_filter kernel.dmesg_restrictrp_filter = 1حالت strict طبق RFC 3704 است و بسته با آدرس مبدأ جعلی را رد میکند؛ با مسیریابی نامتقارن یا چند کارت شبکه،2(loose) بگذارید.accept_redirects = 0جلوی تغییر مسیر با ICMP redirect را میگیرد؛ پیش فرض kernel برای host مقدار1است.tcp_syncookiesدر kernel پیش فرض1است و فقط برای اطمینان آمده.kptr_restrict = 2آدرسهای kernel را حتی از root پنهان میکند؛ اگر ابزار profiling لازم دارید1بگذارید.dmesg_restrict = 1خواندنdmesgرا به کاربر دارایCAP_SYSLOGمحدود میکند.- روی سروری که روتر، VPN gateway یا میزبان Docker است، کلیدهای شبکه، به ویژه
send_redirects، را با نقش همان سرور تطبیق دهید.
۱۰. SELinux و AppArmor
خانوادهی RHEL: SELinux پیش فرض در حالت enforcing است و Red Hat صریحاً توصیه میکند جز در موارد خاص آن را غیرفعال نکنید. فایلهایی که در زمان خاموش بودن SELinux ساخته شوند برچسب ندارند و برگشت به enforcing مشکل ساز میشود. وقتی سرویسی به خاطر SELinux کار نمیکند، علت را پیدا کنید:
getenforce # باید Enforcing باشد
sudo ausearch -m AVC,USER_AVC -ts recent # موارد رد شدهی اخیر
sudo setsebool -P httpd_can_network_connect on # نمونه: اجازهی اتصال شبکه به وب سرور
sudo semanage port -a -t ssh_port_t -p tcp 2222 # نمونه: پورت غیر استاندارد SSHاگر لازم است، فقط همان سرویس را موقتاً permissive کنید (sudo semanage permissive -a httpd_t)، نه کل سیستم را.
Debian و Ubuntu: AppArmor از Debian 10 به بعد پیش فرض فعال است. sudo aa-status پروفایلهای enforce و complain را نشان میدهد؛ aa-enforce و aa-complain در بستهی apparmor-utils هستند.
۱۱. لاگ، audit و ارسال لاگ
journald ماندگار: بدون /var/log/journal لاگ ممکن است فقط در RAM بماند و با ریبوت پاک شود:
sudo mkdir -p /etc/systemd/journald.conf.d
printf '[Journal]\nStorage=persistent\nSystemMaxUse=1G\n' | sudo tee /etc/systemd/journald.conf.d/persistent.conf
sudo systemctl restart systemd-journald
journalctl --list-boots | tail -3auditd تغییر فایلهای حساس را ثبت میکند. نصب: sudo apt install auditd یا sudo dnf install audit. فایل /etc/audit/rules.d/50-hardening.rules:
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k sshdsudo augenrules --load
sudo auditctl -l
sudo ausearch -k identity -ts todayارسال لاگ: مهاجمی که root گرفته لاگ محلی را پاک میکند؛ لاگ را به سرور مرکزی هم بفرستید، مثلاً با rsyslog در /etc/rsyslog.d/90-forward.conf:
*.* action(type="omfwd" target="logs.example.com" port="514" protocol="tcp")این اتصال رمزنگاری نمیشود؛ آن را از شبکهی مدیریت یا VPN بفرستید یا TLS را در rsyslog فعال کنید.
۱۲. همگام سازی زمان با chrony
لاگ با ساعت اشتباه برای بررسی رخداد بیارزش است. در Ubuntu 26.04 chrony پیش فرض است و با NTS (NTP احراز هویت شده و رمزنگاری شده) به سرورهای Ubuntu وصل میشود. در بقیه، اگر chrony نصب نیست نصبش کنید و سرورهای داخلی را در /etc/chrony/chrony.conf (Debian و Ubuntu) یا /etc/chrony.conf (RHEL) بگذارید، مثلاً server ntp1.example.com iburst.
chronyc tracking
chronyc sources۱۳. بررسی یکپارچگی فایلها با AIDE
AIDE از فایلهای سیستمی hash میگیرد و تغییرشان را گزارش میکند:
sudo dnf install aide # RHEL
sudo aide --init
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz
sudo aide --checkدر Debian و Ubuntu: sudo apt install aide و بعد sudo aideinit. Red Hat بررسی را دست کم هفتگی و ترجیحاً روزانه توصیه میکند. بعد از هر به روزرسانی مجاز، پایگاه داده را با aide --update تازه کنید و نسخهای از آن را بیرون از سرور نگه دارید، چون مهاجم پایگاه دادهی روی همان سرور را هم میتواند عوض کند.
۱۴. بکاپ
از داده و /etc بکاپ منظم بگیرید، یک نسخه را خارج از سایت و دور از دسترس همین سرور نگه دارید و بازیابی را تست کنید (قاعدهی بکاپ ۳-۲-۱).
۱۵. اسکن با Lynis و مقایسه با CIS
Lynis ابزار ممیزی متن باز (GPL) است که hardening index و فهرست پیشنهادها را گزارش میکند. آخرین نسخه در شهریور ۱۴۰۵، 3.1.7 است و نسخهی مخزن توزیع ممکن است قدیمیتر باشد:
git clone https://github.com/CISOfy/lynis
cd lynis && sudo ./lynis audit systemجزئیات در lynis.log و یافتهها در lynis-report.dat (پیش فرض در /var/log) ذخیره میشوند. اسکن را قبل و بعد از امن سازی اجرا کنید.
برای مرجع کاملتر، CIS Benchmark توزیع خودتان را ببینید؛ PDF آن برای استفادهی غیرتجاری رایگان است. پروفایل Level 1 تنظیمات پایه با کمترین اثر بر کارکرد است و Level 2 برای محیطهای بسیار حساس است و ممکن است سرویسی را از کار بیندازد؛ پیشنهادها را با تست اعمال کنید. در RHEL بستهی scap-security-guide پروفایلهای آماده برای بررسی خودکار انطباق دارد.
چک لیست نهایی
| مورد | Debian و Ubuntu | RHEL، Rocky و Alma | بررسی |
|---|---|---|---|
| وصلهی امنیتی خودکار | unattended-upgrades |
dnf-automatic-install.timer |
systemctl list-timers |
| سرویسهای اضافه خاموش | systemctl disable --now |
همان | ss -tulpn |
| حساب شخصی و sudo | گروه sudo |
گروه wheel |
فقط root با UID 0 |
| SSH با کلید و محدود به IP | راهنمای SSH | همان | sshd -T |
| فایروال با ورودی بسته | ufw یا nftables | firewalld | ufw status verbose یا firewall-cmd --list-all |
| fail2ban | apt |
EPEL | fail2ban-client status sshd |
/tmp و /dev/shm با noexec |
/etc/fstab |
همان | findmnt /tmp |
| sysctl | /etc/sysctl.d/99-hardening.conf |
همان | sysctl --system |
| MAC فعال | AppArmor | SELinux در حالت Enforcing | aa-status یا getenforce |
| لاگ ماندگار، auditd و ارسال لاگ | journald، auditd، rsyslog |
journald، audit، rsyslog |
journalctl --list-boots و auditctl -l |
| زمان دقیق | chrony | chrony | chronyc tracking |
| یکپارچگی فایل | aideinit |
aide --init |
aide --check |
| بکاپ خارج از سرور | ابزار بکاپ | ابزار بکاپ | بازیابی آزمایشی |
| ممیزی | Lynis | Lynis | hardening index |
منابع
- Ubuntu Server documentation — Automatic updates ubuntu.com
- Ubuntu Server documentation — Firewalls ubuntu.com
- Ubuntu 26.04 LTS release notes — Summary for LTS users documentation.ubuntu.com
- Debian Wiki — UnattendedUpgrades wiki.debian.org
- Debian Wiki — AppArmor HowToUse wiki.debian.org
- Release Notes for Debian 13 (trixie) — Issues to be aware of www.debian.org
- Red Hat — RHEL 10, Automating software updates in RHEL docs.redhat.com
- Red Hat — RHEL 10, Using and configuring firewalld docs.redhat.com
- Red Hat — RHEL 10, Changing SELinux states and modes docs.redhat.com
- Red Hat — RHEL 10, Auditing the system docs.redhat.com
- Red Hat — RHEL 10, Checking integrity with AIDE docs.redhat.com
- Linux kernel documentation — IP Sysctl docs.kernel.org
- Linux kernel documentation — Documentation for /proc/sys/kernel/ docs.kernel.org
- nftables wiki — Simple ruleset for a server wiki.nftables.org
- Lynis — CISOfy cisofy.com