שרת מגדירים פעם אחת, ואחר כך הוא חי לבדו. כעבור חודש חלק מהחבילות ממתינות לעדכון, התעודה התקרבה לשלושה שבועות מפקיעתה, אחרי התקנה של משהו לא קשור הופיעה שורה מיותרת בתצורת SSH, והכלא שאמור לשמור על הכניסות נעצר בלי שאיש הבחין. שום דבר מזה אינו צועק. הכול פשוט מפסיק בשקט להיות נכון.

להלן שנים עשר דברים ששווה לבדוק באופן קבוע, עם הפקודות. הסיבוב נמשך כרבע שעה. הסדר הולך ממה שנכנסים דרכו אל מה שנשבר מעצמו.

SSH: חמש שורות

מה שצריך לבדוק אינו הקובץ אלא התצורה בפועל: היא מורכבת מ-/etc/ssh/sshd_config, מכל התיקייה sshd_config.d ומברירות המחדל של הבנייה.

sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|permitemptypasswords|maxauthtries|x11forwarding'

מה שאנחנו רוצים לראות: permitrootlogin no, passwordauthentication no, permitemptypasswords no, maxauthtries בטווח 3–4 ו-x11forwarding no. שלושת הראשונים הם הדלת, שני האחרונים הצירים שלה — תקרה למספר הניסיונות לכל חיבור, והעברת גרפיקה שלשרת אין בה כל צורך.

שתי הסתייגויות, שתיהן דרך קלה לנעול את עצמך בחוץ. ראשית: אל תכבו את הכניסה בסיסמה ואת כניסת root לפני שווידאתם שהמפתח שלכם עובד — בהפעלה נפרדת, בלי לסגור את הנוכחית. אם אתם קוראים זאת כשאתם מחוברים כ-root עם סיסמה, שתי השורות האלה ינעלו בחוץ דווקא אתכם.

שנית: סדר הקבצים. OpenSSH לוקח את הערך של הפרמטר שהוא פוגש ראשון, והקבצים שב-sshd_config.d נקראים לפי סדר האלפבית. תצלומי ענן משאירים שם בדרך כלל 50-cloud-init.conf, והוא יגבר על הקובץ שלכם אם קראתם לו משהו כמו 90-hardening.conf. ההגדרות שלכם הולכות תחת מספר נמוך יותר — 00- או 10-. ואת התוצאה בודקים עם sshd -T, לא בקריאת הקובץ.

חומת אש: בדיקה אחת

sudo ufw status verbose

כאן כדאי לזכור שהפלט מציג כוונות ולא תוצאות. כלל יכול לעמוד ברשימה ולא לסגור דבר: UFW עצמו כבוי, את הפורט משרת משהו ש-Docker פרסם (הוא כותב כללים משלו ל-iptables מתחת ל-UFW), או שהתעבורה מגיעה לשרת בדרך אחרת. לכן משתלם להציב את רשימת הכללים מול מה שבאמת מאזין החוצה:

sudo ss -tulpn | grep -v '127.0.0.1\|::1'

fail2ban: שתי בדיקות

לא די בכך שהשירות רץ — דרוש גם כלא עובד עבור SSH.

sudo fail2ban-client status
sudo fail2ban-client status sshd

הצרה הנפוצה ביותר כאן היא כלא שותק. ב-Debian 12 ובגרסאות Ubuntu החדשות ייתכן ש-/var/log/auth.log כלל אינו קיים: rsyslog אינו מותקן והרשומות חיות רק ב-journald. כלא עם logpath מקורי עולה אז, מדווח על עצמו כפעיל ולעולם אינו חוסם איש. התרופה היא להפנות אותו ליומן systemd:

printf '[sshd]\nenabled = true\nbackend = systemd\n' | sudo tee /etc/fail2ban/jail.d/sshd-systemd.local
sudo systemctl restart fail2ban

הסימן שמסגיר זאת בלי חפירה בתצורות: ב-fail2ban-client status sshd השורות «Currently failed» ו-«Total failed» עומדות על אפס בעוד שביומן יש בבירור כניסות כושלות.

עדכונים: שלוש בדיקות

בנפרד: כמה חבילות ממתינות בסך הכול, כמה מהן נוגעות לאבטחה, והאם המערכת מבקשת אתחול לאחר עדכון ליבה.

sudo apt update
apt list --upgradable 2>/dev/null | grep -c -- '-security'
ls /var/run/reboot-required 2>/dev/null && echo 'נדרש אתחול'

הבדיקה השלישית היא אם עדכוני האבטחה האוטומטיים מופעלים, כדי ששתי הראשונות לא יהפכו לטקס חודשי:

systemctl status unattended-upgrades --no-pager
cat /etc/apt/apt.conf.d/20auto-upgrades

בקובץ הזה צריכה לעמוד הספרה 1 בשתי השורות. אם החבילה חסרה: sudo apt install unattended-upgrades && sudo dpkg-reconfigure -plow unattended-upgrades.

תעודות: בדיקה אחת

תעודת Let's Encrypt חיה תשעים יום, והחידוש עובד מעצמו בדיוק עד היום שבו הוא מפסיק. מה שצריך לבדוק אינו לוח הרשם אלא מה שהשרת באמת מגיש:

echo | openssl s_client -connect localhost:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
sudo certbot renew --dry-run

הפקודה הראשונה נותנת את תאריך הסיום של התעודה המוגשת עבור אותו שם; השנייה מוודאת שהחידוש יעבור, בלי להמתין למועד האמיתי. כדאי לעבור על כל השמות שהשרת משרת, לא רק על הדומיין הראשי: מה שנשכח הוא בדרך כלל תת-הדומיין שנוסף מאוחר יותר.

דיסק: בדיקה אחת

df -h
df -i

שתי פקודות, מפני שמקום ורשומות קבצים נגמרים בנפרד זה מזה. ברוב השרתים השנייה פוגעת בתקרה ראשונה — מיליוני קבצים זעירים בהפעלות PHP או במטמון היישום נותנים IUse% של 100 כשעוד פנויים ג'יגה-בייטים. על שני המקרים יש לנו טקסט נפרד.

מה לא בסדר ברשימה הזאת

הרשימה נכונה, אבל יש לה תכונה אחת: היא דורשת שמישהו יזכור אותה. רבע שעה בשבוע זה לא הרבה, כל עוד השרת אחד וכל עוד יש סיבה. אחרי חודשיים רגועים הסיבוב נדלג, ועל כך שהכלא נעצר לומדים מהיומנים של מישהו אחר.

לכן אספנו בדיוק את שתים עשרה הבדיקות האלה ללוח חינמי נפרד — Arcivéo FREE. הוא מותקן בפקודה אחת, רץ על השרת שלכם, אינו שולח אלינו דבר ואינו דורש הרשמה. אוסף נתונים רץ מ-cron כל חמש דקות וכותב את אותם הדברים למסד נתונים מקומי: כניסות SSH וחיבורים שנדחו, מצב UFW ו-fail2ban, עדכוני אבטחה ממתינים, מועדי התעודות, מקום בדיסק. ההיסטוריה היא שבעה ימים, הממשק קיים ב-34 שפות. המחיר הוא אפס, גם על שרת עבודה: הרישיון מתיר להתקין את הלוח על מכונות שלכם, מכונות של החברה בכלל זה, ואינו מתיר למכור אותו מחדש או להפעילו כשירות עבור שרתים של אחרים.

המחסנית של המהדורה החינמית צנועה: היא מתקינה ומפעילה את UFW ואת fail2ban, ומשם ואילך מציגה את המצב. ModSecurity, Suricata, AIDE ושאר המודולים אינם בה, אלה שייכים לגרסה בתשלום. אבל כדי להפסיק לשאת את הסיבוב השבועי בראש, היא מספיקה. איך נראים אותם נתונים בלוח המלא מציגים דפי ההדגמה שלהלן.