در این مقاله
هر سروری که یک آیپی عمومی داشته باشد، از همان دقیقهی اول هدف اسکنهای خودکار قرار
میگیرد. اگر لاگ یک سرور تازهنصب را بعد از چند ساعت ببینید، دهها تلاش ناموفق ورود
با نامهای root، admin و ubuntu در آن پیدا میکنید. این رباتها شما را
نمیشناسند؛ کل فضای آیپی را جارو میکنند و دنبال سروری میگردند که رمز ساده یا
سرویس فراموششده داشته باشد. امنسازی سرور لینوکس یعنی بستن همین درهای ساده،
پیش از آنکه کسی آنها را امتحان کند.
خبر خوب این است که بخش بزرگی از این کار با پنج تصمیم انجام میشود و بیش از نیمساعت وقت نمیگیرد: ورود فقط با کلید، بستن ورود مستقیم روت، فایروالی که بهصورت پیشفرض همهچیز را میبندد، ابزاری که آیپیهای مهاجم را موقتاً بلاک میکند و بهروزرسانی خودکار وصلههای امنیتی. هیچکدام از اینها به دانش تخصصی امنیت نیاز ندارند.
در این راهنما همهی این مراحل را روی Ubuntu 24.04/26.04 و Debian 13 انجام
میدهیم. دستورها با کاربر root اجرا میشوند؛ اگر با کاربر عادی کار میکنید، پیش از
هر دستور sudo بگذارید.
پیشنیازها
- یک سرور ابری با Ubuntu 24.04/26.04 یا Debian 13 و دسترسی root.
- یک جفت کلید SSH روی کامپیوتر خودتان (در گام ۲ میسازیم).
- یک ترمینال دوم که همین حالا به سرور وصل باشد. تمام تغییرهای این مقاله روی دسترسی SSH و فایروال اثر میگذارند؛ داشتن یک نشست باز و سالم، تفاوت میان «اشتباه کردم و برگشتم» و «از سرور خودم بیرون ماندم» است.
- دسترسی به کنسول تحت وب کنترل پنل ابر سپهر بهعنوان راه نجات، اگر با وجود همهی احتیاطها SSH قطع شد.
گام ۱: بهروزرسانی سیستم و ساخت کاربر غیرروت
اول از همه بستهها را بهروز میکنیم. بسیاری از رخنهها نه از راه پیکربندی اشتباه، که از راه یک بستهی وصلهنشده اتفاق میافتند:
apt update && apt upgrade -y
سپس یک کاربر عادی میسازیم و او را عضو گروه sudo میکنیم:
adduser deploy
usermod -aG sudo deploy
adduser رمز و چند اطلاعات اختیاری میپرسد و خودش پوشهی خانگی و شل را تنظیم
میکند. دلیل این کار فقط «رعایت اصول» نیست: وقتی ورود مستقیم روت بسته باشد، مهاجم
باید هم نام کاربری درست را حدس بزند و هم کلید داشته باشد. ضمناً هر دستور حساس با
sudo در لاگ ثبت میشود و میدانید چه کسی چه کاری کرده است.
گام ۲: ورود با کلید SSH بهجای رمز عبور
روی کامپیوتر خودتان (نه سرور) یک کلید ed25519 بسازید:
ssh-keygen -t ed25519 -C "deploy@my-laptop"
ed25519 نسبت به RSA کوتاهتر، سریعتر و امنتر است و همهی نسخههای امروزی OpenSSH از آن پشتیبانی میکنند. وقتی پرسید passphrase بگذارید یا نه، بگذارید؛ اگر کسی به لپتاپ شما دسترسی پیدا کند، کلید بدون passphrase یعنی دسترسی مستقیم به سرور.
حالا کلید عمومی را روی سرور بگذارید:
ssh-copy-id deploy@SERVER_IP
اگر ssh-copy-id در دسترس نیست، همان کار را دستی انجام دهید:
ssh deploy@SERVER_IP "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
cat ~/.ssh/id_ed25519.pub | ssh deploy@SERVER_IP "cat >> ~/.ssh/authorized_keys"
ssh deploy@SERVER_IP "chmod 600 ~/.ssh/authorized_keys"
دسترسیهای 700 و 600 اختیاری نیستند؛ اگر پوشه یا فایل برای دیگران قابل نوشتن
باشد، خودِ OpenSSH بهدلایل امنیتی کلید را نادیده میگیرد و شما بدون هیچ پیام روشنی
دوباره سراغ رمز فرستاده میشوید.
پیش از رفتن به گام بعد، در یک ترمینال جدید ورود با کلید را امتحان کنید:
ssh deploy@SERVER_IP
اگر بدون پرسیدن رمز وارد شدید، کار درست انجام شده است.
گام ۳: سختکردن پیکربندی SSH
روی توزیعهای امروزی، فایل /etc/ssh/sshd_config در ابتدای خود یک Include دارد که
فایلهای داخل /etc/ssh/sshd_config.d/ را میخواند. بهترین کار این است که فایل اصلی
را دستنخورده بگذاریم و تنظیمهای خودمان را در یک فایل جدا بنویسیم:
nano /etc/ssh/sshd_config.d/10-hardening.conf
با این محتوا:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
X11Forwarding no
AllowUsers deploy
چند نکته که ترتیب اهمیتشان از بالا به پایین است:
PasswordAuthentication noمهمترین خط این مقاله است. با بستن ورود با رمز، حملهی brute-force عملاً بیمعنا میشود؛ مهاجم چیزی برای حدسزدن ندارد.PermitRootLogin noورود مستقیم روت را میبندد. از این پس باdeployوارد میشوید و باsudoکارهای مدیریتی را انجام میدهید.AllowUsers deployفهرست سفید کاربران مجاز است. اگر بعداً کاربر دیگری ساختید و یادتان رفت اینجا اضافه کنید، آن کاربر نمیتواند وارد شود.KbdInteractiveAuthentication noراه دور دیگری برای ورود با رمز را میبندد؛ بدون آن، بستنPasswordAuthenticationروی برخی پیکربندیها کامل نیست.
نکتهی ظریفی که خیلیها را گرفتار میکند: در OpenSSH اولین مقداری که برای یک
گزینه خوانده شود برنده است، نه آخرین. فایلهای sshd_config.d/ هم به ترتیب حروف
الفبا خوانده میشوند. ایمیجهای ابری معمولاً فایلی مثل 50-cloud-init.conf دارند که
در آن PasswordAuthentication yes نوشته شده است؛ اگر نام فایل شما 99-… باشد،
دیرتر خوانده میشود و تنظیمتان بیاثر میماند. به همین دلیل نام 10-hardening.conf
را انتخاب کردیم.
بهجای حدسزدن، پیکربندی نهایی و تفسیرشده را از خود sshd بپرسید:
sshd -t
sshd -T | grep -E "^(permitrootlogin|passwordauthentication|pubkeyauthentication)"
sshd -t خطای نگارشی را پیش از راهاندازی مجدد پیدا میکند و sshd -T مقدار
واقعی و مؤثر هر گزینه را چاپ میکند. اگر خروجی passwordauthentication no بود،
تنظیم شما برنده شده است. حالا سرویس را دوباره راهاندازی کنید:
systemctl restart ssh
ترمینال فعلی خود را نبندید. یک ترمینال جدید باز کنید و ورود را امتحان کنید. تا وقتی از نشست تازه مطمئن نشدهاید، نشست قدیمی تنها راه بازگشت شماست. اگر هر دو بسته شد، از کنسول تحت وب کنترل پنل ابر سپهر وارد سرور شوید و فایل را اصلاح کنید.
گام ۴: فایروال UFW با سیاست پیشفرضِ بستن
فایروال درست، فایروالی است که بهصورت پیشفرض همهچیز را میبندد و فقط چیزی را که لازم دارید باز میکند:
apt install -y ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
دو خط default قلب ماجرا هستند: ترافیک ورودی جز مواردی که صریحاً اجازه دادهاید
مسدود میشود، ولی سرور همچنان میتواند به بیرون وصل شود (برای apt، DNS و بهروزرسانی).
ufw allow OpenSSH هم یک پروفایل آماده است که پورت ۲۲ را باز میکند.
اگر روی سرور وبسرور دارید، پورتهای آن را هم باز کنید:
ufw allow 'Nginx Full'
و در پایان فایروال را فعال کنید:
ufw enable
ufw status verbose
ufw enableرا هرگز پیش از افزودن قاعدهیOpenSSHاجرا نکنید. این تنها اشتباهی است که در همان لحظه شما را از سرور بیرون میاندازد و تنها راه بازگشت، کنسول تحت وب پنل است.
اگر سرویسی مثل پایگاه داده دارید که فقط باید از یک آیپی مشخص در دسترس باشد، بهجای باز کردن پورت برای همه، آن را محدود کنید:
ufw allow from 203.0.113.10 to any port 5432 proto tcp
این الگو برای اتصال امن به پایگاه داده از بیرون هم بهکار میآید؛ جزئیات بیشتر در راهنمای نصب PostgreSQL روی اوبونتو آمده است.
چرا فایروال بهتنهایی جلوی کانتینرهای داکر را نمیگیرد؟
اگر روی سرور داکر دارید، بدانید که داکر قواعد خودش را مستقیم در iptables مینویسد و
پورتهایی که با -p 8080:8080 منتشر میکنید از کنار UFW رد میشوند؛ یعنی با وجود
deny incoming از اینترنت در دسترساند. راهحل ساده این است که کانتینرها را فقط روی
لوکالهاست منتشر کنید:
docker run -d -p 127.0.0.1:8080:8080 ...
و دسترسی بیرونی را از مسیر پراکسی معکوس بدهید. همین الگو در راهنمای نصب داکر روی اوبونتو هم توضیح داده شده است.
گام ۵: مسدودسازی حملههای brute-force با Fail2ban
Fail2ban لاگها را میخواند و آیپیهایی را که پشتسرهم شکست میخورند، برای مدتی بلاک میکند:
apt install -y fail2ban python3-systemd
بستهی python3-systemd برای خواندن لاگ از journald لازم است. روی Debian 13 و
نصبهای کمحجم اوبونتو، فایل /var/log/auth.log لزوماً وجود ندارد و لاگها فقط در
ژورنال systemd هستند؛ اگر این نکته را نادیده بگیرید، Fail2ban بالا میآید ولی هیچوقت
چیزی پیدا نمیکند.
فایل پیکربندی محلی را بسازید (فایلهای jail.conf با هر بهروزرسانی بازنویسی میشوند،
پس هرگز آنها را ویرایش نکنید):
nano /etc/fail2ban/jail.local
با محتوای زیر:
[DEFAULT]
backend = systemd
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
معنی این اعداد ساده است: اگر یک آیپی در بازهی ۱۰ دقیقه (findtime) پنج بار
(maxretry) شکست بخورد، یک ساعت (bantime) بلاک میشود. در ignoreip میتوانید
آیپی ثابت دفتر خودتان را هم اضافه کنید تا در اثر یک اشتباه، خودتان بلاک نشوید.
سرویس را فعال و وضعیت را بررسی کنید:
systemctl enable --now fail2ban
fail2ban-client status sshd
خروجی این دستور تعداد تلاشهای ناموفق و فهرست آیپیهای بلاکشده را نشان میدهد. اگر آیپیای را اشتباهی بلاک کردید:
fail2ban-client set sshd unbanip 203.0.113.10
شاید بپرسید وقتی ورود با رمز بسته است، Fail2ban چه فایدهای دارد. دو فایده: حجم تلاشهای بیفایده و مصرف منابع را کم میکند و لاگها را تمیز نگه میدارد، بهطوری که وقتی اتفاق غیرعادی افتاد، آن را میان هزاران خط نویز گم نمیکنید.
گام ۶: بهروزرسانی خودکار وصلههای امنیتی
بیشتر سرورهایی که هک میشوند، با یک آسیبپذیری شناختهشده و وصلهشده هک میشوند که کسی وصله را نصب نکرده است. این کار را به سیستم بسپارید:
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
دستور دوم فایل /etc/apt/apt.conf.d/20auto-upgrades را میسازد و بهروزرسانی روزانه
را فعال میکند. برای اطمینان از اینکه همهچیز درست کار میکند، یک اجرای آزمایشی
بگیرید:
unattended-upgrade --dry-run --debug
بهصورت پیشفرض فقط بستههای مخزن امنیتی نصب میشوند، یعنی احتمال شکستن سرویسهای
شما بسیار کم است. اگر میخواهید سرور پس از بهروزرسانیهایی که نیاز به ریبوت دارند
خودش ریبوت شود، در فایل /etc/apt/apt.conf.d/50unattended-upgrades این دو خط را
از حالت کامنت خارج و تنظیم کنید:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
ریبوت خودکار برای سرورهای وب معمولاً پذیرفتنی است، اما اگر روی سرور سرویس حساس یا پایگاه دادهی بزرگ دارید، بهتر است ریبوت را دستی و در زمان مناسب انجام دهید.
گام ۷ (اختیاری): تغییر پورت SSH
تغییر پورت SSH امنیت واقعی اضافه نمیکند اما حجم نویز لاگ را بهشدت کم میکند. روی
Ubuntu 24.04 و Debian 13 نکتهای هست که خیلیها را سردرگم میکند: SSH با
socket activation بالا میآید و در این حالت دستور Port در sshd_config نادیده
گرفته میشود. پورت را باید در خود سوکت عوض کنید:
systemctl edit ssh.socket
و در بخش ویرایشپذیر این را بنویسید:
[Socket]
ListenStream=
ListenStream=2222
خط خالی ListenStream= مقدار پیشفرض (پورت ۲۲) را پاک میکند؛ بدون آن، سرویس روی
هر دو پورت گوش میدهد. سپس پورت جدید را در فایروال باز و سرویس را راهاندازی کنید:
ufw allow 2222/tcp
systemctl daemon-reload
systemctl restart ssh.socket
پیش از بستن پورت ۲۲ (ufw delete allow OpenSSH) حتماً ورود روی پورت جدید را با
ssh -p 2222 deploy@SERVER_IP امتحان کنید.
نگهداری: بهروزرسانی و بکآپ
امنسازی یک کار یکباره نیست؛ چند دقیقه بازبینی در ماه، بیشتر از هر ابزار گرانقیمتی ارزش دارد. سه عادت ساده کافی است: سرکشی به لاگ ورودها، بررسی قواعد فایروال بعد از هر تغییر، و گرفتن اسنپشات از کنترل پنل ابر سپهر پیش از هر تغییر پرخطر.
برای دیدن ورودهای اخیر و تلاشهای ناموفق:
journalctl -u ssh --since "24 hours ago" | grep -Ei "accepted|failed"
last -n 20
journalctl تصویر دقیقی از تلاشهای ورود میدهد و last فهرست آخرین ورودهای موفق
را نشان میدهد. اگر ورودی موفق از آیپی ناآشنا دیدید، آن را جدی بگیرید.
| کار | دستور | چه زمانی |
|---|---|---|
| بررسی تنظیم مؤثر SSH | sshd -T | grep passwordauthentication |
پس از هر تغییر پیکربندی |
| وضعیت فایروال | ufw status verbose |
پس از افزودن هر سرویس |
| آیپیهای بلاکشده | fail2ban-client status sshd |
هفتگی |
| بستههای قابل ارتقا | apt list --upgradable |
ماهانه |
| بررسی ورودهای اخیر | journalctl -u ssh --since "24 hours ago" |
هنگام مشاهده رفتار مشکوک |
| بکآپ کامل | اسنپشات کنترل پنل | پیش از هر تغییر پرخطر |
فراموش نکنید که فایروال و Fail2ban جای بکآپ را نمیگیرند. اگر هنوز برنامهی مشخصی برای بکآپ ندارید، راهنمای بکآپ خودکار سرور با Restic مکمل مستقیم همین مقاله است.
جمعبندی
امنسازی سرور لینوکس با همین شش گام، سرور شما را از دسترس ۹۹ درصد حملههای خودکار خارج میکند: کاربر غیرروت، ورود فقط با کلید SSH، فایروال با سیاست پیشفرضِ بستن، Fail2ban و بهروزرسانی خودکار امنیتی.
سه تصمیمی که بیشترین تفاوت را میسازند: بستن PasswordAuthentication، اطمینان از
مؤثر بودن آن با sshd -T (نه فقط نوشتنش در فایل) و منتشر نکردن پورت کانتینرها روی
اینترنت. بقیهی موارد لایههای بعدی دفاعاند.
اگر میخواهید همین پیکربندی را روی یک سرور تازه پیاده کنید، از صفحه خرید سرور ابری شروع کنید؛ کنسول تحت وب و اسنپشات، دو ابزاری هستند که هنگام آزمونوخطا با فایروال و SSH بیشترین کاربرد را دارند.
مقالات مرتبط
بکآپ خودکار سرور با Restic روی فضای ذخیرهسازی ابری
راهاندازی بکآپ خودکار سرور با Restic؛ رمزنگاری سمت سرور، ارسال به فضای S3، زمانبندی با systemd، سیاست نگهداری نسخهها و تمرین بازیابی.
ادامه مطلبآموزش نصب PostgreSQL روی اوبونتو
نصب PostgreSQL روی اوبونتو از مخزن رسمی PGDG؛ ساخت کاربر و دیتابیس، دسترسی امن از راه دور با pg_hba.conf، تنظیم فایروال، تیونینگ پایه و بکآپ.
ادامه مطلبویژگیهای Ubuntu 26.04 LTS و تازههای Resolute Raccoon
مرور کامل ویژگیهای Ubuntu 26.04 LTS با نام Resolute Raccoon؛ کرنل لینوکس ۷.۰، گنوم ۵۰، رمزنگاری کامل دیسک با TPM، پشتیبانی بومی CUDA و پنج سال پشتیبانی.
ادامه مطلب