FAQ

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

מאיפה להתחיל

01. התקנת הפאנל — בחרו שיטה

התקנת הפאנל מתוארת בעמודים נפרדים שלב-אחר-שלב. בחרו שיטה:

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

סקירה כללית

02. מהו Arcivéo Monitor

Arcivéo Monitor — לוח בקרה לאבטחת השרת. אוסף נתונים מהכלים המותקנים (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco ועוד) ומציג אותם בממשק אחיד עם דאשבורד, מפת התקפות ודפים מפורטים לכל כלי.

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

03. כיצד המוניטור פועל בשרת

המוניטור פועל מקומית בלבד — יש להתקין אותו על אותו שרת שאותו הוא מנטר. אין SSH או API מרוחק.

את כל הפקודות (fail2ban-client, ufw status, ipset list וכו') הפאנל מריץ בשם משתמש שרת האינטרנט (בדרך כלל www-data, ובפאנלי אירוח — חשבון האתר) עם קבוצת הרשאות מצומצמת של sudo — רק לכלים ספציפיים, ללא גישת root כללית. התוצאות מנותחות ומוצגות בדפדפן.

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

04. כיצד מחושב ציון האבטחה

הציון מתחיל מהמקסימום ויורד עבור כל בעיה שמזוהה:

  • UFW אינו פעיל — −30
  • Fail2ban אינו פועל (אין jail פעילים) — −25
  • אין מפתחות WebAuthn — −15
  • Lynis hardening index < 60 — −20; 60–79 — −10
  • IPset ipsum לא נטען — −10
  • ClamAV מצא איומים — −20
  • שינויים בקבצים לפי AIDE — −15
  • SSL פג תוקף — −30, פג בעוד <14 יום — −15, <30 יום — −5
  • CrowdSec מותקן אך אינו פועל — −5
  • Suricata מותקנת אך אינה פועלת — −5
  • מסד נתונים/מטמון (MySQL, PostgreSQL, Redis…) נגישים מבחוץ — −10
  • מותרת כניסת root דרך SSH (PermitRootLogin yes) — −20
  • ממתינים להתקנה עדכוני אבטחה — −5

סיכום: 80+ = מוגן, 60–79 = לתשומת לב, <60 = בסיכון.

הניכויים עבור ClamAV, AIDE, CrowdSec ו-Suricata חלים רק אם הכלי מותקן. Lynis ו-AIDE ללא מסד נתונים מאותחל מוצגים כ“אין נתונים” ואינם מפחיתים את הציון. מספר ההתקפות של היום מוצג בלוח הבקרה, אך אינו משפיע על ציון האבטחה.

הגדרות ורישיון

05. WebAuthn — אימות דו-שלבי

WebAuthn — תקן אימות ללא סיסמה באמצעות מפתח חומרה. תומך ב-YubiKey, Touch ID, Face ID, Windows Hello, Passkey.

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

להגדרה, פתחו את מפתחות WebAuthn בתפריט הצד ולחצו על “רישום מפתח”. רשמו מיד שני מפתחות: אם המפתח היחיד יאבד או יישבר, לא ניתן יהיה להתחבר לפאנל באמצעותו.

WebAuthn פועל רק דרך HTTPS. בחיבור HTTP רישום והתחברות באמצעות מפתח אינם זמינים.

06. התראות: Telegram ואימייל

הפאנל יכול לשלוח דוח אבטחה ל-Telegram ולדוא"ל (בלחיצה ולפי לוח זמנים). ההגדרה מתבצעת בקטע “הגדרות”.

Telegram. נדרשים טוקן של הבוט ו-chat id:

  1. ב-Telegram כתבו אל @BotFather/newbot ← קבלו טוקן בצורה 123456:ABC....
  2. שלחו לבוט החדש שלכם הודעה כלשהי (כדי שיוכל להשיב לכם).
  3. גלו את ה-chat id שלכם: כתבו לבוט @userinfobot, או פתחו https://api.telegram.org/bot<TOKEN>/getUpdates ומצאו "chat":{"id":...}.
  4. הזינו את הטוקן וה-chat id ב“הגדרות” ← Telegram, ולחצו “שמור ושלח בדיקה”.

אימייל. שתי דרכים לבחירה ב“הגדרות” ← Email:

  • SMTP — מארח, פורט (465/SSL או 587/TLS), שם משתמש וסיסמה של תיבת הדואר שלכם;
  • Resend — API מודרני: ציינו מפתח API (re_...) ודומיין שולח מאומת.
הכפתור “שלח בדיקה” יבדוק מיד את הערוץ. לוח הזמנים של הדוח האוטומטי — דרך cron (הקטע “כל משימות ה-cron”): הוא מפעיל את השליחה, והערוצים נלקחים מההגדרות.

סטטוס הדוח: “שים לב” או “תקין”. הכותרת הופכת ל“שים לב” רק בעת בעיה אמיתית או פעולה ממתינה: זוהה איום ClamAV, שינויי קבצים ב-AIDE, אירועים קריטיים של Falco (Emergency/Alert/Critical ב-24 השעות האחרונות), שירות שנפל ב-Monit, נדרשת הפעלה מחדש, פג תוקף SSL (≤14 ימים) או ממתינים עדכוני אבטחה. רעש רקע — ניסיונות SSH של בוטים, כתובות IP שנחסמו ב-fail2ban, התראות Suricata, אזהרות Lynis ובקשות ModSecurity שכבר נהדפו — אינו מעלה את הסטטוס, ולכן מספרים כאלה בדוח אינם משמעם “שים לב” כשלעצמם.

07. רישיון — הזנה והפעלה

מודולי הניטור המפורטים (Lynis, UFW, ModSecurity, מפת התקפות, AIDE, ClamAV ועוד) נפתחים בעת קיום רישיון בתוקף. בלעדיו לוח הבקרה, ההגדרות והחשבון פועלים, אך המודולים מציגים כרטיס “נדרש רישיון”.

לאחר הרכישה באזור האישי יש ברשותכם קוד הפעלה בפורמט ARCIVEO-XXXX-XXXX-XXXX-XXXX. יש “להפעיל” אותו על הדומיין של הפאנל שלכם — פעולה זו הופכת את הקוד לקובץ רישיון חתום (בלוק [license]), שאותו אתם מדביקים בפאנל.

איך מפעילים (3 שלבים):

  1. קחו את קוד ההפעלה. האזור האישי my.arciveo.com ← מדור “רישיונות” / “הפעלת רישיון” — העתיקו את הקוד ARCIVEO-….
  2. הפעילו את הקוד על הדומיין שלכם. באותו אזור אישי פתחו “הפעלת רישיון”, והזינו: קוד הפעלה, האימייל שלכם ואת דומיין הפאנל (הכתובת שבה נפתח המוניטור, למשל monitor.example.com). לחצו הפעל — המערכת תיצור קובץ רישיון הקשור לדומיין זה ותציג אותו בשדה עם הכפתור “העתק”.
  3. הדביקו את המפתח בפאנל. העתיקו את כל טקסט הרישיון ← בפאנל פתחו “הגדרות” ← בלוק “רישיון”, הדביקו ולחצו “שמור”. המודולים ייפתחו מיד.

הפאנל בודק את המפתח קריפטוגרפית: החתימה, הקישור לדומיין ותוקף הרישיון.

הדומיין בעת ההפעלה חייב להתאים בדיוק לכתובת הפאנל. קחו אותו מהקבוע APP_URL שב־config.php והזינו רק את שם המארח — ללא https:// וללא הקידומת www. ההפעלה חד־פעמית: הקוד הופך לרישיון עבור הדומיין שהוזן ואינו ניתן להפעלה חוזרת — אם תטעו בדומיין, המפתח לא יתאים לפאנל שלכם, והקוד ינוצל. לכן הזינו את הדומיין בקפידה.
אם התוקף פג או הדומיין השתנה — בראש הפאנל תופיע אזהרה. הרישיון קשור לדומיין לצמיתות ואינו ניתן להעברה לדומיין אחר: לתקופה חדשה או לדומיין חדש נדרש מפתח חדש (נרכש באזור האישי ומופעל באופן חד־פעמי).

08. קובץ config.php — כל הגדרות הפאנל

כל הפרמטרים העיקריים של הפאנל מוגדרים בקובץ יחיד config.php בשורש (לצד התיקייה public/) בעזרת קבועים רגילים define(). הקובץ נוצר בעת ההתקנה; לעריכה ידנית תזדקק לעיתים רחוקות — בעיקר בעת החלפת דומיין, העברה או חיבור למסד נתונים אחר. לאחר כל עריכה הפעל מחדש את PHP-FPM (אחרת בגלל OPcache השינויים לא ייכנסו לתוקף).

הצב את הערכים שלך במקומות המודגשים; את השאר השאר כפי שהוא:

// --- מסד נתונים --- define('DB_HOST', 'localhost'); // להשאיר define('DB_NAME', 'db_name'); // מה שהגדרת בעת יצירת המסד define('DB_USER', 'user'); // מה שהגדרת בעת יצירת המסד define('DB_PASS', 'db_password'); // מה שהגדרת בעת יצירת המסד define('DB_CHARSET', 'utf8mb4'); // להשאיר // --- אפליקציה --- define('APP_URL', 'https://monitor.example.com'); // כתובת הפאנל, בלי לוכסן בסוף define('TIMEZONE', 'Asia/Jerusalem'); // אזור הזמן שלך // --- זמן הפעלה --- define('SESSION_LIFETIME', 28800); // חוסר פעילות עד כניסה חוזרת, שנ' (28800 = 8 שע')

מסד נתונים. פרטי החיבור ל-MySQL/MariaDB:

  • DB_HOST — מארח מסד הנתונים, כמעט תמיד localhost;
  • DB_NAME — שם מסד הנתונים של הפאנל;
  • DB_USER — משתמש מסד הנתונים (גישה למסד שלו בלבד);
  • DB_PASS — הסיסמה של משתמש זה;
  • DB_CHARSET — קידוד החיבור, השאר utf8mb4.

אפליקציה.

  • APP_URL — הכתובת המלאה של הפאנל (למשל https://monitor.example.com). חייבת להתאים לדומיין שעליו הופעל הרישיון — אחרת המפתח יידחה (ראה סעיף “רישיון”);
  • TIMEZONE — אזור הזמן של PHP: משפיע רק על אופן הצגת התאריכים והשעות בפאנל. על זמן הפעלת משימות ה-cron אינו משפיע — שם חל אזור הזמן של המערכת (ראה “כל משימות ה-cron”).

זמן הפעלה. SESSION_LIFETIME — פסק זמן של חוסר פעילות בהפעלה, בשניות (מתגלגל: מתעדכן בעת פעילות). כברירת מחדל 28800 = 8 שעות; לאחר זמן זה של חוסר פעילות הפאנל יבקש להיכנס מחדש. לדוגמה, 3600 = שעה אחת, 86400 = יממה.

תיעוד שגיאות. שגיאות לעולם אינן מוצגות למבקרים, אלא נכתבות ל-logs/php_errors.log — הן נראות בדף “יומני האפליקציה”. את השורות הללו (display_errors=0, log_errors=1, הנתיב error_log) בדרך כלל אין צורך לשנות — ההגדרות נקבעו ישירות בקובץ ואינן תלויות ב-php.ini.

config.php — קובץ סודי. בו נמצאת סיסמת מסד הנתונים. הוא ממוקם בשורש הפאנל (לצד public/), ואצל פאנל זה שורש האתר (DocumentRoot) הוא בדיוק שורש הפאנל, לא public/. הקובץ עצמו אינו “דולף”: ב-.htaccess שבשורש קיים איסור מפורש עליו (Require all denied) — השרת מחזיר 403. גם בלי כלל זה קוד המקור לא היה דולף: זהו PHP — השרת מריץ אותו ולא מחזיר אותו כטקסט. ליתר ביטחון: אל תעלה אותו למאגרים ציבוריים ואל תעביר לתמיכה עם סיסמה אמיתית. הרשאות הקובץ — 640.
בעת העברה או שחזור גישה הקובץ הזה הוא המקור העיקרי לפרטים: שם המסד, המשתמש והסיסמה נלקחים בדיוק מכאן (ראה סעיפים “עדכון והעברת הפאנל” ו“שחזור גישה”).

כלי אבטחה

09. חומת אש UFW

UFW (Uncomplicated Firewall) — ממשק פשוט ל-nftables/iptables. חוסם את כל הפורטים הנכנסים מלבד אלה שהותרו במפורש. הדף “חומת אש UFW” מציג את הסטטוס ואת הכללים.

sudo apt install ufw # התרת SSH (חובה לפני ההפעלה!) ואינטרנט sudo ufw allow OpenSSH sudo ufw allow 80,443/tcp # חסימת מסד הנתונים מבחוץ (גישה מקומית בלבד) sudo ufw deny 3306 # הפעלה ובדיקה sudo ufw enable sudo ufw status verbose
לפני ufw enable יש להתיר SSH (ufw allow OpenSSH), אחרת תאבד את הגישה לשרת.
“חשיפה חיצונית” בלוח הבקרה מתחשבת ב-UFW: פורט שנחסם בכלל deny אינו נחשב נגיש מבחוץ.
Skipping adding existing rule — זו אינה שגיאה. כך UFW מודיע שכלל זהה כבר קיים ואינו מוסיף אותו שוב. בהרצה חוזרת של ההגדרה האוטומטית (שהיא אידמפוטנטית) זו הודעה שגרתית — אין צורך להגיב.

10. התקנת Fail2ban

חוסם אוטומטית כתובת IP לאחר חריגה ממספר ניסיונות הכניסה הכושלים. מנתח את יומני SSH, nginx, Apache ושירותים נוספים.

sudo apt install fail2ban sudo systemctl enable --now fail2ban # בדיקת סטטוס: sudo fail2ban-client status
תצורת עבודה (jail.local עם עשרות jail וחסימה אוטומטית מ-ipsum) — בסעיף הבא.

11. תצורת עבודה של Fail2ban + ipsum

ההתקנה הבסיסית — למעלה. כאן — תצורת עבודה שמעניקה עשרות jail פעילים ואלפי חסימות: הגדרות כלליות, jail מרכזיים וחסימה אוטומטית של כתובות IP זדוניות מהרשימה ipsum.

הקובץ /etc/fail2ban/jail.local — הגדרות כלליות ו-jail החשובים ביותר:

[DEFAULT] bantime = 1w findtime = 900 maxretry = 3 backend = systemd banaction = nftables-multiport ignoreip = 127.0.0.1/8 ::1 <YOUR_IP> <TRUSTED_NETS> # חסימה מדורגת: כל חזרה — ארוכה יותר bantime.increment = true bantime.factor = 2 bantime.maxtime = 5w bantime.rndtime = 300 [sshd] enabled = true maxretry = 5 bantime = -1 # חסימה קבועה על ניסיון brute-force ב-SSH findtime = 3600 # עבריינים חוזרים: מי שנחסם כמה פעמים — נחסם לצמיתות [recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = -1 findtime = 86400 maxretry = 2 [http-get-dos] enabled = true maxretry = 100 findtime = 300 bantime = 1w # שירותי אינטרנט (apache-*, nginx-*, php-url-fopen, phpmyadmin-syslog): [nginx-http-auth] enabled = true port = http,https [apache-badbots] enabled = true port = http,https # … ושאר ה-jail לפי שירותים (dovecot, exim, postfix-sasl, # mysqld-auth, vsftpd, portscan, pam-generic) — enabled = true
ב-ignoreip חובה לרשום את ה-IP שלכם ואת הרשתות המהימנות, אחרת אפשר לחסום את עצמכם. אחרי העריכה: sudo fail2ban-client reload.

טעינה אוטומטית של רשימת החסימות ipsum — ל-cron של root (sudo crontab -e): level 1 (100+ אלף IP) נטען אל הסט ipsum, שנחסם בחומת האש (פרטים נוספים — בפרק “רשימת חסימות IPset”):

# 04:00 — עדכון ipset ipsum (level 1, כיסוי מרבי): 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1
הסט חייב להיקרא ipsum — זה מה שהדשבורד קורא (הכרטיס “IPset ipsum”). רמות: levels/1.txt — כיסוי מרבי, levels/3.txt — מדויק יותר (3+ מקורות).

מדוע “מוניטור האבטחה” מחולק לשני אזורים. ההגנה פועלת בשתי רמות, והדשבורד לא מערבב ביניהן:

  • מתקפות אמיתיות (תגובתי) — כל מה ש-fail2ban תפס: ניסיונות פריצה חיים (ה-jail sshd, apache-*, nginx-* וכדומה) ועבריינים חוזרים זדוניים (jail recidive — אלה שכבר נחסמו כמה פעמים). אלו כתובות IP שבאמת ניסו לפרוץ אליכם — הן על מפת המתקפות וב“ציר הזמן”.
  • חסימה מונעת (יזומה) — רשימת חסימות ציבורית של כתובות IP זדוניות ידועות ipset ipsum, שנחסמת בחומת האש באמצעות כלל DROP. רוב הכתובות האלה בכלל לא נגעו בשרת שלכם — הן נחסמות מראש; המונה “IPset ipsum” מציג כמה נחסמו באופן מונע.

ההבדל פשוט: תגובתי — “אלה תקפו וקיבלו חסימה”, מונע — “אלה נחסמו עוד לפני הניסיון”. בעבר הוזרם ל-recidive באופן מלאכותי list-3 של ipsum (מכאן החלוקה הישנה “recidive מהרשימה”); כעת recidive — רק עבריינים חוזרים אמיתיים, וההגנה המונעת כולה בחומת האש.

12. רשימת חסימה של IPset (ipsum)

ipsum — רשימה ציבורית של כתובות IP זדוניות, מתעדכנת מדי יום. המוניטור מציג את מספר הכתובות שנטענו בלוח הבקרה ובמפת המתקפות ומביא אותו בחשבון בציון האבטחה (−10 אם הרשימה לא נטענה).

הגרסה המינימלית ללא fail2ban — רשימה נפרדת ipsum עם חסימה דרך iptables:

# יצירת הרשימה (פעם אחת): sudo ipset create ipsum hash:ip # סקריפט העדכון /usr/local/bin/update-ipsum.sh: #!/bin/bash ipset flush ipsum for ip in $(curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/3.txt); do ipset add ipsum "$ip" 2>/dev/null done iptables -C INPUT -m set --match-set ipsum src -j DROP 2>/dev/null \ || iptables -I INPUT -m set --match-set ipsum src -j DROP # Cron (sudo crontab -e, מדי יום ב-4:00): 0 4 * * * /usr/local/bin/update-ipsum.sh
הגרסה המורחבת עם fail2ban-recidive — בסעיף “תצורת עבודה של Fail2ban + ipsum”.
ipset שוכן בזיכרון ואובד באתחול מחדש. קרון יומי בלבד ישאיר את הרשימה ריקה מרגע האתחול ועד ההרצה הבאה (לוח הבקרה יציג 0). טענו את הרשימה גם בעת האתחול — העבירו את הטעינה לסקריפט ותלו אותו על @reboot. אגב כך הפקודה create … -exist מגדירה מגבלה maxelem 300000 (ברירת המחדל 65536 — level 1 לא נכנס, יופיע “Hash is full”):
# /usr/local/bin/load-ipsum.sh #!/bin/bash curl -s https://raw.githubusercontent.com/stamparm/ipsum/master/levels/1.txt \ | grep -v '^#' | sed 's/^/add ipsum /' \ | (echo "create ipsum hash:ip hashsize 131072 maxelem 300000 -exist"; echo "flush ipsum"; cat) \ | ipset restore -exist # sudo crontab -e — מדי יום ב-04:00 וגם בכל אתחול: 0 4 * * * /usr/local/bin/load-ipsum.sh @reboot sleep 60 && /usr/local/bin/load-ipsum.sh
איך זה עובד בהתקנה אוטומטית. הסקריפט טוען את הרשימה המלאה level 1 (100+ אלף כתובות IP) לרשימה ipsum, ואם חומת האש מנוהלת על ידי המתקין (VPS חדש — פרופילי “מלאה”/“מוקלת”), מחבר את הרשימה ל-UFW בכלל DROP — התעבורה מכתובות ה-IP הללו נחסמת בפועל. הכלל ממוקם אחרי ESTABLISHED,RELATED, ולכן החיבורים הקיימים (כולל ה-SSH שלכם) לא מתנתקים — נחסמים רק חיבורים חדשים מהרשימה. הרשימה משוחזרת בעת טעינת השירות ipsum-load.service לפני חומת האש (אחרת UFW לא היה עולה), ומתעדכנת בקרון ב-04:00. בשרת שכבר מוגדר (פאנל, חומת אש משלכם) המתקין לא נוגע בחומת האש — שם ipsum נשארת רשימה עבור לוח הבקרה ומפת המתקפות, וכלל ה-DROP מתווסף ידנית לפי הצורך (הגרסה המינימלית עם iptables … --match-set ipsum … -j DROP — למעלה). בהתקנה אוטומטית אין צורך לעשות דבר ידנית.

13. התקנת CrowdSec

תחליף מודרני ל-Fail2ban עם threat intelligence קהילתי: חסימות מהקהילה בתוספת כללים משלך. דורש bouncer נפרד ליישום החסימות על חומת האש.

curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash sudo apt install crowdsec sudo systemctl enable --now crowdsec # Bouncer עבור iptables/nftables: sudo apt install crowdsec-firewall-bouncer-iptables # בדיקת סטטוס: sudo systemctl status crowdsec sudo cscli decisions list sudo cscli bouncers list
סטטוס “לא פועל” בלוח הבקרה = השירות מותקן, אך היחידה אינה פעילה (המוניטור בודק אותה באמצעות systemctl is-active crowdsec). הפעלה: sudo systemctl enable --now crowdsec; בעת כשל בדוק sudo journalctl -u crowdsec -n 30. אותו כלל לכל שירות בסטטוס “לא פועל” (Suricata, Falco, Monit, MySQL).
“0 תרחישים” או “0 bouncers” בלוח המחוונים. CrowdSec מגיע כמעט ריק מהקופסה — ללא אוספים הוא לא מזהה דבר, וללא bouncer רשום החסימות אינן מיושמות על חומת האש. התקן אוספי בסיס וודא שה-bouncer מופיע ברשימה:
# אוספי בסיס (Linux + SSH + שרת אינטרנט): sudo cscli collections install crowdsecurity/linux crowdsecurity/sshd crowdsecurity/base-http-scenarios sudo systemctl reload crowdsec # ה-bouncer חייב להופיע ברשימה ועם סטטוס חיבור פעיל: sudo cscli bouncers list
ביומן של ה-bouncer מופיע stream halted / החסימות אינן מיושמות. זהו מפתח api יתום: ה-bouncer הוסר מ-cscli bouncers list, אך המפתח הישן שלו נשאר ב-/etc/crowdsec/bouncers/*.yaml. רשום מחדש את ה-bouncer והזן מפתח חדש:
sudo cscli bouncers add fw-bouncer # יפיק api_key חדש # הזן מפתח זה בשדה api_key: בקובץ /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml sudo systemctl restart crowdsec-firewall-bouncer
ההתקנה האוטומטית (פרופיל “הגנה מלאה”) מתקינה בעצמה את האוספים ורושמת את ה-firewall-bouncer — ידנית זה נדרש רק בהתקנה ידנית או לאחר התערבות ידנית ב-CrowdSec.

14. התקנת AIDE

AIDE (Advanced Intrusion Detection Environment) יוצר תמונת מצב של מערכת הקבצים, ובכל בדיקה מדווח על שינויים ב־/etc, /bin, /usr. לאחר ההתקנה חובה לאתחל את מסד הנתונים (aideinit).

sudo apt install aide # אתחול מסד הנתונים (5–15 דקות): sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db # Ubuntu 24.04: התיקייה /var/lib/aide נוצרת במצב 700 (בעלים _aide), # והלוח (www-data) לא רואה את המסד → מציג “לא אותחל”. # פתחו את התיקייה למעבר (קובצי המסד נשארים 600): sudo chmod 755 /var/lib/aide # בדיקה ראשונה עם כתיבה ליומן שהמוניטור קורא. # ב-Ubuntu/Debian תוכנת aide דורשת --config מפורש (אחרת “missing configuration”; # הקובץ הבינארי aide.wrapper אינו נכלל בגרסאות החדשות): sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
במהלך aideinit הטרמינל תקוע 5–15 דקות על השורה Running aide --init... — זה תקין (חישוב האש של כל מערכת הקבצים, עומס על הדיסק). אל תפסיקו ב-Ctrl+C. אם התהליך “תקוע” אך לא כותב דבר — ייתכן שהוא ממתין לתשובה על בקשה נסתרת Overwrite existing aide.db.new [Yn]? (הקישו Y). לבדיקת פעילות מסשן אחר: pgrep -af aide.
שגיאת aideinit: “21_aide_spamassassin … printf: invalid number” (return code 20) — באג ידוע במקטע התצורה של AIDE ב-Ubuntu 22.04. המסד לא נוצר. הוציאו את המקטע הפגום וחזרו על הפעולה:
sudo mv /etc/aide/aide.conf.d/21_aide_spamassassin /etc/aide/21_aide_spamassassin.disabled sudo aideinit sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
מצבים בלוח הבקרה. “לא אותחל” = הלוח לא רואה את קובץ המסד: או ש-aideinit לא הופעל, או (Ubuntu 24.04) שהתיקייה /var/lib/aide נוצרה במצב 700 ואינה נגישה ל-www-data — נפתר עם sudo chmod 755 /var/lib/aide (ראו הבלוק למעלה). “לא בוצעו בדיקות” = המסד קיים, אך עדיין לא בוצעה בדיקה — זו אינה שגיאה. את התוצאות המוניטור קורא מ־/var/log/aide/aide.log.
בדיקה סדירה → יומן ללוח. ה-/etc/cron.daily/aide הרגיל ב-Ubuntu/Debian החדשים עשוי לא לכתוב את /var/log/aide/aide.log בצורה הנדרשת (וגם aide.wrapper כבר אינו קיים בהם). אמין יותר להוסיף cron משלכם עם --config מפורש — הוא כותב יומן מ-root במצב 644, והמוניטור קורא אותו ללא קבוצות נוספות:
# sudo crontab -e — בדיקה יומית ב-02:00: 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # להפעיל עכשיו, בלי להמתין ללוח הזמנים: sudo bash -c 'aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1'
ההתקנה האוטומטית כבר עושה את כל זה: chmod 755 /var/lib/aide ו-cron בדיקה ב-02:00 — אין צורך בכלום ידנית.
בצעו את האתחול הראשון על שרת נקי — לפני התקנת יישומי ווב. לאחר שינויים לגיטימיים צרו מחדש את המסד: sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.

15. התקנת ClamAV

סורק אנטי-וירוס ל-Linux. שימושי במיוחד לבדיקת /var/www אחר PHP-שלים וקוד זדוני.

sudo apt install clamav clamav-daemon sudo systemctl enable --now clamav-daemon # עדכון מסד החתימות: sudo freshclam # סריקת תיקייה ידנית: sudo clamscan -r /var/www --infected
ה-daemon‏ clamd מציג “לא פעיל” אחרי enable --now? שלוש סיבות אופייניות:

1. בקובץ ההגדרות נותרה השורה Example — clamd מסרב לעלות כל עוד היא קיימת:

sudo sed -i '/^Example/d' /etc/clamav/clamd.conf sudo systemctl restart clamav-daemon

2. מסד החתימות לא הורד — clamd לא עולה בלעדיו:

sudo systemctl stop clamav-freshclam sudo freshclam sudo systemctl start clamav-freshclam sudo systemctl restart clamav-daemon

3. פשוט נטען — clamd טוען כ-8 מיליון חתימות לזיכרון תוך 30–60 שנ'. המתן ובדוק: systemctl is-active clamav-daemon (מצב activating ← עדיין נטען).

אבחון: sudo journalctl -u clamav-daemon -n 30 --no-pager.
בלוח הבקרה “קבצים שנבדקו: 0” / “סריקה אחרונה: —”? ה-daemon‏ clamd רק מחזיק את החתימות בזיכרון, הוא עצמו אינו סורק דבר לפי לוח זמנים. הפאנל מציג את תוצאות הסריקה המתוזמנת, לכן דרוש cron שסורק וכותב יומן. ההתקנה האוטומטית מתקינה עטיפה /usr/local/bin/clamav-scan.sh ו-cron בשעה 01:30 — לאחר ההרצה הראשונה יתמלאו “קבצים שנבדקו” ו“סריקה אחרונה”. להרצה מיידית, בלי להמתין ללוח הזמנים: sudo /usr/local/bin/clamav-scan.sh.

16. התקנת Linux Malware Detect (maldet)

Linux Malware Detect (LMD) — סורק תוכנות זדוניות לאיומים מבוססי-אינטרנט: PHP-שֶלים, דלתות אחוריות לאתרים, מורידנים. משתמש במנוע של ClamAV ומשלים אותו בחתימות משלו.

wget https://www.rfxn.com/downloads/maldetect-current.tar.gz tar -xzf maldetect-current.tar.gz dir=$(ls -d maldetect-*/ | head -1) && cd "$dir" && sudo bash install.sh && cd ~ rm -rf maldetect-* maldetect-current.tar.gz # עדכון חתימות: sudo maldet -u # סריקת /var/www: sudo maldet -a /var/www
LMD ו-ClamAV עובדים היטב יחד. הדוח האחרון: maldet --report.
בעת ההתקנה עלולה להופיע השורה update-rc.d: error: unable to read /etc/init.d/maldet — היא לא מזיקה. maldet אינו משתמש ב-init.d, עדכון החתימות והסריקות מופעלים דרך /etc/cron.daily/maldet. אם למטה מופיע installation completed — הכול הותקן.
בעמוד LMD מופיע “לא מותקן” למרות שהוא מותקן? maldet אינו מותקן דרך apt אלא ב-/usr/local/maldetect, וכאשר open_basedir מופעל, נוכחותו נבדקת דרך shell — ראה סעיף “העמוד ריק למרות שהנתונים קיימים בשרת”.

17. התקנת Suricata

מערכת רשתית לזיהוי חדירות: מנתחת את התעבורה ברמת החבילות ומכירה אלפי חתימות של מתקפות. משלימה את ModSecurity (שפועל ברמת HTTP, בעוד Suricata פועלת ברמת TCP/IP).

sudo add-apt-repository ppa:oisf/suricata-stable sudo apt update && sudo apt install suricata # הורדת הכללים העדכניים: sudo suricata-update sudo systemctl enable --now suricata
Suricata במצב “פעיל”, אך הלוח לא מציג התראות / מספר האירועים 0? Suricata כותבת אל /var/log/suricata/eve.json תחת root עם הרשאה 750 על התיקייה, ושרת האינטרנט (www-data) אינו יכול לקרוא אותה. פתחו את התיקייה למעבר — הקבצים שבתוכה נשארים מוגנים:
sudo chmod o+rx /var/log/suricata
ההתקנה האוטומטית עושה זאת בעצמה — אין צורך לבצע זאת ידנית.

18. התקנת Falco

יירוט קריאות מערכת דרך eBPF/kernel module וזיהוי חריגות בזמן אמת: shell מתוך nginx, קריאת /etc/passwd על ידי תהליך אינטרנט, כתיבה אל /bin וכדומה.

curl -fsSL https://falco.org/repo/falcosecurity-packages.asc > /tmp/falco.asc gpg --dearmor < /tmp/falco.asc | sudo tee /usr/share/keyrings/falco-archive-keyring.gpg > /dev/null sudo chmod 644 /usr/share/keyrings/falco-archive-keyring.gpg && rm /tmp/falco.asc echo "deb [signed-by=/usr/share/keyrings/falco-archive-keyring.gpg] https://download.falco.org/packages/deb stable main" \ | sudo tee /etc/apt/sources.list.d/falcosecurity.list sudo apt update && sudo apt install falco sudo systemctl enable --now falco
המוניטור קורא אירועי Falco דרך journalctl -u falco (ללא sudo — דרך הקבוצה systemd-journal). ודא ש‑www-data נמצא בקבוצה זו — ראה “הגדרת sudo” (סעיף 2) בעמוד ההתקנה הידנית.
“0 אירועים ב‑24 שעות” — זהו מצב תקין, לא שגיאה. Falco הוא event-driven: הוא שותק כל עוד הכול תקין, ורושם אירוע רק בעת חריגה (shell מתהליך אינטרנט, קריאת /etc/passwd, כתיבה אל תיקיות מערכת). אפס אירועים קריטיים ביממה בשרת רגוע — זהו מצב בריא.
ללוח הבקרה עדיף פלט לקובץ. קריאה דרך journalctl דורשת הרשאות ליומן; כדי שהלוח יראה את האירועים באופן יציב, ההתקנה האוטומטית מפעילה ב‑Falco את file_output/var/log/falco/falco.log ומגדירה לשירות UMask=0022 (היומן נקרא על ידי שרת האינטרנט). בהתקנה חדשה אין צורך להגדיר זאת ידנית.

19. התקנת ModSecurity (WAF)

ModSecurity — חומת אש לאתרים (WAF) עבור Apache או Nginx. חוסמת מתקפות ברמת האפליקציה: הזרקות SQL, XSS, מעבר נתיבים, סורקים.

# Apache: sudo apt install libapache2-mod-security2 sudo a2enmod security2 # מערך הכללים OWASP Core Rule Set: sudo apt install modsecurity-crs # חובה: ללא קובץ זה מנוע הכללים כבוי sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf sudo sed -i 's/^SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf sudo apache2ctl configtest && sudo systemctl reload apache2 # בדיקה: אמור להחזיר 403 curl -s -o /dev/null -w '%{http_code}\n' "https://monitor.example.com/?id=1%20UNION%20SELECT%201,2--"
התקנת החבילה כשלעצמה אינה מגינה על דבר. Apache מחבר את קבצי התצורה בשורה IncludeOptional /etc/modsecurity/*.conf, ואילו החבילה מניחה רק את modsecurity.conf-recommended — הוא אינו נכלל בתבנית *.conf. אם לא תעתיק אותו אל modsecurity.conf, SecRuleEngine נשאר Off: המודול נטען, כללי CRS נטענים, אך התעבורה אינה נבדקת ויומן הביקורת אינו נוצר. המצב הביניים DetectionOnly רק רושם אירועים ליומן מבלי לחסום בקשות — הלוח מציג אותו בצהוב.

גישת הלוח ליומן הביקורת. היומן /var/log/apache2/modsec_audit.log שייך ל-root (הרשאות 640), משתמש הרשת אינו יכול לקרוא אותו. הלוח מקבל את הנתונים דרך עוטף — צרו אותו:

sudo tee /usr/local/bin/monitor-modsec >/dev/null <<'EOF' #!/bin/sh echo "ENGINE=$(grep -hE '^SecRuleEngine[[:space:]]+' /etc/modsecurity/*.conf 2>/dev/null | tail -1 | awk '{print $2}')" echo "---LOG---" tail -n 3000 /var/log/apache2/modsec_audit.log 2>/dev/null echo "---RULES---" for f in /etc/modsecurity/crs/rules/*.conf /usr/share/modsecurity-crs/rules/*.conf /etc/modsecurity/custom-rules.conf; do [ -f "$f" ] && { echo "===FILE:$(basename "$f")==="; cat "$f"; } done EOF sudo chown root:root /usr/local/bin/monitor-modsec sudo chmod 755 /usr/local/bin/monitor-modsec # ב-/etc/sudoers.d/monitor (המשתמש = זה שתחתיו רץ PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-modsec
העוטף לוקח את הדירקטיבה SecRuleEngine האחרונה ללא הזחה: שורות עם הזחה נמצאות בתוך בלוקים של <LocationMatch>/<Directory> (למשל, ניטרול ה-WAF עבור phpMyAdmin) ואינן קובעות את המצב הגלובלי.
המשתמש ב-sudoers חייב להתאים למשתמש של מאגר ה-FPM: ב-Apache/Debian רגיל זהו www-data, וב-HestiaCP מאגר האתר רץ תחת בעל האתר (למשל, admin) — בדקו עם grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.
אם האתר נמצא מאחורי פרוקסי Nginx (HestiaCP), Apache רואה כלקוח את הפרוקסי עצמו — הלוח לוקח את כתובת ה-IP האמיתית של התוקף מכותרת X-Forwarded-For. לסטטיסטיקה נכנסות רק טרנזקציות עם כלל שהופעל: הדירקטיבה SecAuditLogRelevantStatus רושמת ליומן הביקורת כל תגובת 4xx/5xx, ולכן נכנסות לשם גם 403/500 רגילות — הלוח אינו מחשיב אותן כאירועי WAF.
הבלוק ---RULES--- נחוץ למקטע “כל הכללים הפעילים” — הלוח מציג לא רק כללים שהופעלו, אלא בכלל את כל כללי ה-CRS שנטענו + מותאמים אישית. שלושת הנתיבים בלולאה for f in … הם המקומות הטיפוסיים לכללי CRS ולתוספות מקומיות; אם אצלכם פריסה אחרת (החבילה מניחה קבצים בספריה משלה, או שהכללים המותאמים אינם ב-/etc/modsecurity/custom-rules.conf), מצאו את הנתיבים האמיתיים בפקודה sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null והציבו אותם ברשימה. אם העוטף ישן (ללא מקטע זה) — המקטע פשוט יציג אזהרה “לא זמין”, שאר העמוד עובד כמקודם.

20. התקנת Auditd

Auditd (Linux Audit Daemon) מתעד קריאות מערכת ברמת הליבה: כניסות ויציאות, פקודות sudo, ניסיונות אימות כושלים ושינויים בקבצים. המוניטור מציג כניסות, ניסיונות כושלים ופקודות sudo של היום.

sudo apt install auditd audispd-plugins sudo systemctl enable --now auditd # בדיקת סטטוס ואירועים: sudo systemctl status auditd sudo ausearch -m USER_LOGIN -ts today
המוניטור קורא אירועים דרך ausearch (/usr/sbin/ausearch) ובמידת הצורך מתוך /var/log/audit/audit.log באמצעות הפקודה tail. שניהם חייבים להיות ב-sudoers.

21. התקנת Monit

עוקב אחר שירותים (nginx, php-fpm, mysql וכו') ומפעיל אותם מחדש בעת קריסה. יכול לשלוח התראות לאימייל.

sudo apt install monit sudo systemctl enable --now monit # קבצי תצורה: sudo nano /etc/monit/monitrc ls /etc/monit/conf.d/
המוניטור מקבל את רשימת השירותים דרך monit status. בקובץ /etc/monit/monitrc חייב להיות מופעל ממשק ה-HTTP (בלוק set httpd עם allow localhost), אחרת monit status יחזיר שגיאה.
בלוח הבקרה מופיע “0 שירותים במעקב”? שתי סיבות. (1) ממשק ה-HTTP כבוי — בקובץ monitrc השורה set httpd מסומנת כהערה (כברירת מחדל היא מופיעה כ-# set httpd port 2812 …). הסר את סימון ההערה מהבלוק והתר את localhost. (2) httpd מופעל כשלעצמו אינו עוקב אחר דבר — Monit סופר רק את מה שמוגדר בסטנזות check; בלעדיהן הרשימה ריקה גם כשהממשק פועל. תצורת מינימום עובדת:
# /etc/monit/conf.d/00-httpd — ממשק HTTP עבור localhost: set httpd port 2812 use address localhost allow localhost # דוגמאות לסטנזות check (מה לעקוב): check process sshd with pidfile /run/sshd.pid start program = "/usr/bin/systemctl start ssh" stop program = "/usr/bin/systemctl stop ssh" check filesystem rootfs with path / if space usage > 90% then alert
sudo monit -t # בדיקת תחביר (Control file syntax OK) sudo systemctl reload monit sudo monit status
ההתקנה האוטומטית מניחה conf.d מוכן עם httpd על 2812 וסט בדיקות — בהתקנה חדשה אין צורך בהגדרה ידנית.
שירות בסטטוס “עם שגיאות”? המוניטור רק מציג מצב ובכוונה אינו מפעיל שירותים מחדש מלוח הבקרה (זה היה מהווה הרצת פקודות root מרחוק בפאנל אבטחה). אבחון והפעלה מחדש — דרך SSH באמצעות Monit:
sudo monit status <service> # סיבת השגיאה sudo monit restart <service> # הפעלה מחדש דרך Monit # אם Monit לא מפעיל את השירות — בדוק את היחידה שלו עצמה: sudo systemctl status <unit> --no-pager sudo journalctl -u <unit> -n 50 --no-pager

22. התקנת PSAD (זיהוי סריקת פורטים)

PSAD מנתח את יומן iptables ומזהה סריקות פורטים ומתקפות רשת, ומקצה לכל מקור רמת סיכון (1–5). משלים את fail2ban ואת Suricata.

sudo apt install psad # PSAD קורא את יומן iptables — יש להפעיל תיעוד (UFW עושה זאת בעצמו). # עבור iptables נקי הוסיפו כללי LOG לשרשראות INPUT/FORWARD. sudo psad --sig-update sudo systemctl enable --now psad
המוניטור קורא את הנתונים דרך psad --Status (נדרש ב-sudoers). ללא תיעוד iptables הדף יהיה ריק — זה תקין כל עוד לא בוצעו סריקות.

23. AppArmor / SELinux (בקרת גישה)

Mandatory Access Control מגביל לאילו קבצים ומשאבים תוכנית יכולה לגשת, גם אם נפרצה. ב-Ubuntu/Debian משתמשים כברירת מחדל ב-AppArmor (בדרך כלל כבר מותקן ופעיל).

# AppArmor (Ubuntu/Debian): sudo apt install apparmor apparmor-utils sudo systemctl enable --now apparmor sudo aa-status # בדיקת פרופילים
המוניטור קורא את הסטטוס דרך aa-status (נדרש ב-sudoers). מציג את מספר הפרופילים במצב enforce/complain ותהליכים ללא פרופיל.

“פרופילים טעונים” יותר מ-enforce + complain — זה תקין. ב-AppArmor 4.x (Ubuntu 24.04 ומעלה) נוסף מצב unconfined: הפרופיל טעון בקרנל, אך אינו מגביל דבר. Ubuntu מסמנת כך עשרות פרופילים לתוכניות המשתמשות ב-user namespaces (דפדפנים, לקוחות torrent וכדומה). כשקיימים פרופילים כאלה, הכרטיס “פרופילים טעונים” הופך לענבר ומציג את מספרם — לדוגמה unconfined: 90 מתוך 120 טעונים ו-26 ב-enforce. באמת מגינים רק הפרופילים ב-enforce; ב-Ubuntu 22.04 (AppArmor 3.x) אין מצב זה והמספרים תמיד מסתדרים.

sudo aa-status | grep -E "profiles are" # פירוט לפי מצבים sudo aa-enforce /etc/apparmor.d/profile-name # העברת פרופיל למצב enforce
כדאי להעביר ל-enforce פרופילים ש-Ubuntu השאירה בכוונה ב-unconfined רק באופן מודע: הם כבויים לא בטעות, אלא כי אחרת עבודת התוכניות עצמן נשברת. פרופילים ב-complain — עניין אחר: שם הכללים כבר כתובים ורק לא מיושמים.

24. התקנת debsums (שלמות חבילות)

debsums בודק שקבצי החבילות המותקנות תואמים לסכומי הביקורת מהמאגר — מזהה קבצי מערכת בינאריים מוחלפים (משלים את AIDE). בדיקה מלאה נמשכת 1–2 דקות, ולכן מופעלת דרך cron, והלוח קורא את התוצאה מ־data/debsums/debsums.log וממיין אותה לקטגוריות בעצמו (חשובים רק קבצים בינאריים וספריות).

המשימה נכנסת ל־root-cron (sudo crontab -e). העטיפה המוכנה debsums-scan.sh מונחת ב־/usr/local/bin/ (chmod +x; ראה סיכום משימות cron) וכותבת את הדוח בעצמה אל data/debsums/ של הלוח.

sudo apt install debsums # שורת Cron (מדי יום 4:30): 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

העטיפה debsums-scan.sh מאתרת בעצמה את data/ של הלוח — אין צורך לציין נתיב.

שינויים ב־/etc/ (קונפיגורציה) וב־/usr/share/ (משאבים) בשרת הם בדרך כלל תקינים — הלוח מסמן אותם בצבע נפרד. מדאיגים שינויים בקבצים בינאריים ובספריות (/bin, /sbin, /usr/lib וכד') — הכרטיס “קבצים בינאריים / ספריות” מציג בדיוק אותם.

25. הגדרת דוחות Lynis

ניתן להריץ את Lynis ידנית או דרך cron. יש לשמור את הדוח בתיקייה data/lynis/ של הפרויקט — המוניטור קורא את הקובץ lynis-report.dat.

# הרצה חד-פעמית (הזינו את הנתיב שלכם לשורש הפאנל): sudo lynis audit system --report-file /path/to/monitor/data/lynis/lynis-report.dat # ביקורת יומית — שורת cron (עטיפה מוכנה lynis-scan.sh ב-/usr/local/bin/, ראו סיכום): 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1
לאחר ההרצה הראשונה, הדף “ביקורת Lynis” יציג מיד את מדד ההקשחה, האזהרות וההמלצות.
הכפתור “הרץ ביקורת” בדף Lynis. הוא מריץ את lynis-scan.sh ברקע ישירות מהפאנל (בלי להמתין ל-cron): מציג “סורק…” ובסיום מעדכן את הדוח בעצמו. לשם כך משתמש הווב צריך שורת sudoers להרצת הסקריפט — תוכנת ההתקנה מוסיפה אותה אוטומטית ל-/etc/sudoers.d/monitor. אם הפאנל הותקן ידנית/מוקדם יותר, הוסיפו אותה עם אותו משתמש שכבר מצוין בקובץ:
u=$(sudo awk '/NOPASSWD/ && !/lynis-scan/ {print $1; exit}' /etc/sudoers.d/monitor) [ -n "$u" ] && echo "$u ALL=(ALL) NOPASSWD: /usr/local/bin/lynis-scan.sh" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c && sudo chmod 440 /etc/sudoers.d/monitor

26. הגדרת דוחות Logwatch

על Logwatch לשמור דוחות יומיים בתיקייה data/logwatch/ של הפרויקט בפורמט .txt. המוניטור מציג את הדוח האחרון ואת הארכיון.

# יומי (6:00) — שורת cron (עטיפה מוכנה logwatch_daily.sh ב-/usr/local/bin/, ראה סיכום): 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1

מודולים של הלוח

27. ניטור רשת (מובנה)

ניטור הרשת אינו דורש התקנה — זהו דף מובנה בלוח הבקרה. הוא מציג את מצב הרשת של השרת ממקורות מקומיים:

  • ממשקים ותעבורה — מתוך /proc/net/dev;
  • מצב הקישורים (UP/DOWN) וכתובות IP — דרך ip;
  • חיבורים ופורטים מאזינים — דרך ss;
  • אירועי רשת של הליבה ב-24 השעות האחרונות — דרך journalctl -k.

שלושת המקורות הראשונים פועלים ללא sudo, ולכן הממשקים, התעבורה, החיבורים והפורטים גלויים מייד. מקטע “אירועי ליבה” משתמש ב-journalctl -k — הוא נקרא דרך הקבוצה systemd-journal (“הגדרת sudo”, סעיף 2), ואין צורך ב-sudo. כדי לבדוק שהכול נגיש למשתמש הרשת:

# בדיקה בשם www-data (תחתיו פועל PHP): sudo -u www-data bash -c 'cat /proc/net/dev' sudo -u www-data bash -c 'ip -o link show' sudo -u www-data bash -c 'ss -s' sudo -u www-data journalctl -k --no-pager -n 5
מקטע “אירועי רשת של הליבה” מציג אירועים של מחסנית הרשת של הליבה (שינוי קישור up/down, שגיאות נשא, “network unreachable”). רשומות חומת האש UFW BLOCK אינן מופיעות כאן — הן בדפים “חומת האש UFW” ו“מפת התקפות”. מקטע ריק עם וי ירוק = ביממה האחרונה לא היו תקלות רשת.

28. דיסק ו-SMART

העמוד המובנה מציג שלושה דברים:

  • מערכות קבצים — ניצול המחיצות (df); הסרגל מאדים ב-‏90%≤;
  • כונני אחסון — רשימת הדיסקים (lsblk), רק הממשיים (loop/snap מוסתרים);
  • תקינות (SMART) — סטטוס הדיסק והמאפיינים (smartctl).

המקום ורשימת ההתקנים פועלים מיד, ללא הגדרה. עבור SMART נדרשת החבילה smartmontools. תהליך ה-Web אינו ניגש ישירות להתקני הדיסק, ולכן ה-SMART נאסף באמצעות cron אל הקובץ data/disk/smart.txt, והלוח קורא אותו.

המשימה נמצאת בקרון של root (sudo crontab -e). עטיפה מוכנה smart-scan.sh ממוקמת ב-/usr/local/bin/ (chmod +x; ראו סיכום משימות cron) וכותבת בעצמה אל data/disk/ של הלוח.

sudo apt install smartmontools # שורת Cron (כל 30 דקות): */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1

העטיפה smart-scan.sh מאתרת בעצמה את data/ של הלוח — אין צורך לציין נתיב. בתוכה lsblk -e7,11 מחריג loop/cdrom.

בדיסקים וירטואליים (QEMU/KVM ודומיהם) בדרך כלל זמין רק הסטטוס הכללי “תקינות: OK”, ואילו הטמפרטורה, שעות הפעולה והסקטורים שהוקצו מחדש עשויים להיות ריקים — זה תקין. בשרת פיזי מוצגים כל המאפיינים.

29. ביצועים (CPU/RAM/רשת/דיסק)

הדף מציג את היסטוריית העומס של השרת ב-24 השעות האחרונות — Load Average, ניצול CPU והמתנת I/O, RAM/Swap, תעבורת רשת (קבלה/שליחה), I/O של דיסק (קריאה/כתיבה), ניצול הדיסק וה-inodes, מתארי קבצים פתוחים וחיבורי MySQL, ובנוסף מספר חיבורי ה-TCP והתהליכים הנוכחי.

הנתונים נאספים על ידי cron/collect_metrics.php — אחת ל-5 דקות נכתב תצלום “גולמי” יחיד של המונים (/proc/loadavg, /proc/meminfo, /proc/stat, /proc/net/dev, /proc/diskstats, df/df -i, /proc/sys/fs/file-nr, SHOW GLOBAL STATUS LIKE 'Threads_connected') לטבלת ה-DB system_metrics; את האחוזים והמהירויות הדף מחשב בעצמו לפי ההפרש בין תצלומים סמוכים (ניצול דיסק/inodes/מתארים/חיבורי MySQL — ערכים רגעיים, ללא חישוב מחדש). אין צורך ב-sudo — המקורות נקראים ללא הרשאות root. נקודות ישנות מ-24 שעות נמחקות אוטומטית בכל כתיבה.

# שורת Cron (כל 5 דקות): */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1

העוטף collect-metrics-all.sh (ראו סיכום משימות ה-cron) מאתר בעצמו את כל מופעי הפאנל המותקנים בשרת ומריץ את cron/collect_metrics.php של כל אחד בשם בעל האתר.

עד שהאוסף ירוץ לפחות פעמיים (כ-10 הדקות הראשונות אחרי ההתקנה), הדף מציג “הנתונים נאספים” — הגרפים זקוקים לפחות לזוג נקודות סמוכות אחד כדי לחשב מהירויות ואחוזים.

התראות עומס (מקטע “הגדרות” → “התראות עומס”) — בעת חריגה מסף CPU/RAM/דיסק/inodes הפאנל שולח התראה ל-Telegram/Email (אותם ערוצים כמו הדוח היומי — אין צורך להפעיל אותם בנפרד עבור ההתראות), ועוד אחת — כשהמדד חזר לנורמה. אין הצפה חוזרת בזמן שהסף עדיין חורג: ההתראה הבאה תגיע רק אחרי מחזור “חזר לנורמה ← חרג שוב”.

הספים נבדקים על ידי אותו collect_metrics.php בכל הרצה (אחת ל-5 דקות) — אין צורך ב-cron נפרד. המצב “כבר התרענו / עדיין לא” נשמר ב-data/alerts_state.json, הספים — בהגדרות הפאנל.

30. מפת התקפות (GeoIP)

העמוד “מפת התקפות” מזהה את המדינה לפי כתובת IP באמצעות הפקודה geoiplookup. ללא חבילת GeoIP המדינות לא יזוהו והנקודות לא יופיעו על המפה:

sudo apt install geoip-bin geoip-database # בדיקה: geoiplookup 8.8.8.8
אין צורך ב-sudo — הבסיס /usr/share/GeoIP/GeoIP.dat קריא לכולם, והתוצאות נשמרות במטמון ב-tmp/geoip_cache.json. המפה עצמה (Leaflet + אריחי OpenStreetMap) נטענת בדפדפן — נדרש חיבור אינטרנט במחשב שבו פתוח הלוח.

31. חשיפה חיצונית, עדכונים ועדכונים אוטומטיים

שני כרטיסים מובנים בלוח הבקרה שמציגים לא “מופעל/כבוי” של הכלי, אלא את רמת ההגנה האמיתית של השרת. אינם דורשים התקנה ונקראים מקומית ללא sudo.

חשיפה חיצונית — כמה שירותים מאזינים על כל הממשקים (0.0.0.0/[::]) וזמינים מבחוץ. מסומן באדום אם מסדי נתונים או מטמון בולטים החוצה (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — זו פרצה ישירה (−10 לציון האבטחה). מקור: ss -tuln.

אם הכרטיס אדום — סגרו את מסד הנתונים בפני העולם החיצוני: קשרו ל־127.0.0.1 (bind-address בהגדרות MySQL/PostgreSQL, bind 127.0.0.1 ב־Redis) או סגרו את הפורט ב־UFW.
“פורט פתוח” ≠ “נגיש מבחוץ”. שירות שמאזין ל־127.0.0.1 (loopback) גלוי רק לשרת עצמו — מבחוץ אי אפשר להגיע אליו, גם אם הפורט “פתוח”. לכן Postfix בפורט 25 הקשור ל־loopback הוא בטוח: ההגדרה האוטומטית מציבה inet_interfaces = loopback-only (בתוספת smtpd_banner ניטרלי — סוגר את הערת Lynis MAIL-8818 על חשיפת גרסה). הכרטיס “חשיפה חיצונית” סופר כחשיפה החוצה רק את מה שמאזין על 0.0.0.0/[::]; שירותי loopback אינם נכללים.
Lynis MAIL-8818 ידנית (אם התקנתם את הדואר בעצמכם): בקובץ /etc/postfix/main.cf הגדירו smtpd_banner = $myhostname ESMTP (ללא גרסה ומערכת הפעלה) ו־inet_interfaces = loopback-only, ולאחר מכן sudo systemctl restart postfix.

עדכוני אבטחה — כמה תיקוני אבטחה ממתינים להתקנה והאם נדרשת הפעלה מחדש לאחר עדכון הליבה (−5 לציון האבטחה כשקיימים תיקונים). מקור: /usr/lib/update-notifier/apt-check, קובץ /var/run/reboot-required. רשימה מפורטת — בעמוד “עדכוני אבטחה”.

# התקנת עדכונים: sudo apt update && sudo apt upgrade # בדיקה מה מאזין החוצה: ss -tuln | grep -E '0\.0\.0\.0|\[::\]'
כרטיס העדכונים עובד ב־Ubuntu/Debian (update-notifier-common). אם apt-check חסר — המוניטור סופר תיקונים דרך apt-get -s upgrade.

עדכוני אבטחה אוטומטיים (unattended-upgrades) — בעמוד “עדכוני אבטחה” כרטיס נפרד מציג האם ההתקנה האוטומטית של תיקוני אבטחה מופעלת ומתי הופעלה בפעם האחרונה. אין צורך ב־sudo — הסטטוס נקרא דרך apt-config dump.

sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades # הפעלה # בדיקה מה מופעל: apt-config dump | grep Unattended-Upgrade

תחזוקה

32. גיבוי

גיבוי הוא ביטוח החשוב מכול: אובדן נתונים מסוכן מכל פריצה. צריך שני דברים — גיבוי של השרת/האתרים ובנפרד גיבוי של מסד הנתונים של הפאנל (שם המשתמשים, מפתחות WebAuthn, ההגדרות והרישיון).

אפשרות A — HestiaCP: לשונית Backup אצל המשתמש ← לחצן יצירת גיבוי (או לפי לוח זמנים בהגדרות השרת). הגיבוי כולל את האתרים ואת מסדי הנתונים שלהם.

אפשרות B — ידני (cron): דאמפ של מסד הנתונים + ארכיון של תיקיית data/ של הפאנל:

# cron של root‏ (sudo crontab -e) — גיבוי יומי ב-2:30 (הזינו את השמות/הנתיבים שלכם): 30 2 * * * mysqldump -u root MY_DB | gzip > /var/backups/monitor-db-$(date +\%F).sql.gz 40 2 * * * tar czf /var/backups/monitor-data-$(date +\%F).tar.gz -C /path/to/monitor data # מחיקת ארכיונים ישנים מ-14 יום: 0 3 * * * find /var/backups -name 'monitor-*' -mtime +14 -delete
גיבוי על אותו שרת מציל משגיאות, אך לא מאובדן השרת עצמו. העתיקו את הארכיונים לאחסון חיצוני (שרת אחר, S3, rclone לענן). ודאו שהשחזור אכן עובד.

33. עדכון והעברה של הפאנל

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

  • לדרוס (קוד): public/, includes/, assets/, cron/, database/, וכן קובצי .htaccess בשורש (בקר החזית — אין להשאיר את הניתוב מהגרסה הישנה), manifest.json, sw.js;
  • לא לגעת: config.php (נתוני מסד הנתונים), data/ (דוחות), logs/, tmp/ (הפעלות ומטמון).
# לאחר ההעלאה — לאפס את מטמון PHP (אם opcache מופעל): sudo systemctl reload php*-fpm
FileZilla מציג SSH_FX_PERMISSION_DENIEDPermission denied. קבצי הפאנל שייכים ל-www-data (כך הוגדרו בהתקנה), בעוד לקוח ה-SFTP מתחבר עם המשתמש שלכם, שאין לו הרשאת כתיבה. מסירת כל הפאנל ל-www-data “כדי שיעבוד” היא בדיוק מה שמוביל לשגיאה הזו; להלן שלוש דרכים, כל אחת מהן פותרת את הבעיה.
# אפשרות A (מומלצת) — להפריד בעלים: הקוד שלכם, תיקיות העבודה של שרת האינטרנט. # שרת האינטרנט אינו מקבל כלל הרשאת כתיבה לקוד הפאנל: sudo chown -R deploy:www-data /path/to/monitor sudo chown -R www-data:www-data /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo find /path/to/monitor -type d -exec chmod 755 {} \; sudo find /path/to/monitor -type f -exec chmod 644 {} \; sudo chmod 750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs sudo chmod 640 /path/to/monitor/config.php # אפשרות B — ACL מעל הבעלים הנוכחיים (לא מעבירים דבר): sudo apt install -y acl sudo setfacl -R -m u:deploy:rwX /path/to/monitor sudo setfacl -R -d -m u:deploy:rwX /path/to/monitor # אפשרות C — דרך הקבוצה www-data. פשוטה יותר, אבל הרשאת כתיבה לקבצי # הפאנל מקבל גם שרת האינטרנט (עם חולשה ב-PHP אפשר להחליף את הקוד): sudo usermod -aG www-data deploy sudo find /path/to/monitor -type d -exec chmod 2775 {} \; sudo find /path/to/monitor -type f -exec chmod 664 {} \; sudo chmod 640 /path/to/monitor/config.php sudo chmod 2750 /path/to/monitor/data /path/to/monitor/tmp /path/to/monitor/logs
מדוע אפשרות A בטוחה. הפאנל כותב רק לשלוש תיקיות — data/ (דוחות), tmp/ (הפעלות ומטמון), logs/; הן נשארות בבעלות www-data. השאר הוא קוד, ושרת האינטרנט זקוק לו לקריאה בלבד, שאותה מעניקה הקבוצה www-data עם הרשאות 644. יתרון נלווה: עם חולשה ב-PHP כבר לא ניתן לדרוס את קבצי הפאנל. בפאנלים של אירוח (HestiaCP ודומיהם) אפשרות A אינה נחוצה: שם קובצי האתר ממילא שייכים לחשבון שאיתו אתם מתחברים ב-SFTP, ושרת האינטרנט קורא אותם דרך הקבוצה.
מלכודת באפשרות B: כל chmod נוסף על הקבצים מאפס את מסכת ה-ACL, והגישה נעלמת בשקט. אם אחרי “סידור ההרשאות” ההעלאה נתקלת שוב ב-Permission denied — הריצו שוב את שתי הפקודות setfacl.
הביט 2 באפשרות C הוא setgid: קבצים שהועלו ב-SFTP נשארים בקבוצה www-data, אחרת הפאנל לא יוכל לדרוס אותם. אחרי אפשרות C התחברו מחדש ב-FileZilla — הקבוצה החדשה נכנסת לתוקף רק בכניסה חדשה. בדיקה: id deploy (צריכה להופיע הקבוצה www-data) ו-ls -ld /path/to/monitor (drwxrwsr-x — האות s פירושה ש-setgid מוגדר).

העברה לשרת אחר:

  1. בשרת החדש הקימו את האתר + HTTPS (ראו עמוד ההתקנה הידנית).
  2. העתיקו את כל קובצי הפאנל יחד עם config.php, data/.
  3. העבירו את מסד הנתונים: mysqldump בישן ← ייבוא בחדש; עדכנו את נתוני מסד הנתונים ב-config.php.
  4. חזרו על כך בשרת החדש: sudoers, חברות בקבוצה adm, משימות cron.
  5. הרישיון מקושר לדומיין — אם הדומיין זהה, המפתח ימשיך לעבוד.

34. שחזור גישה (אבד המפתח, הסיסמה, חסימת IP)

אם אינך מצליח להתחבר — הכול ניתן לתיקון ישירות במסד הנתונים מהשרת. פתח את מסד הנתונים (השם — מתוך config.php):

sudo mysql MY_DB

אבד מפתח WebAuthn (הגורם השני אינו עובר) — כבה 2FA, התחבר עם סיסמה ורשום מפתח חדש:

UPDATE users SET webauthn_enabled = 0;

שכחת את הסיסמה — הגדר גיבוב חדש (צור אותו בשרת והחלף):

# יצירת גיבוב לסיסמה החדשה: php -r "echo password_hash('NEW_PASSWORD', PASSWORD_BCRYPT), \"\n\";" # במסד הנתונים (הדבק את הגיבוב שהתקבל): # UPDATE users SET password = '$2y$10$...' WHERE username = 'admin';

חסמת את עצמך במסנן IP — בטל את ההגבלה:

UPDATE settings SET value = '0' WHERE name = 'ip_restriction_enabled';
תמיד יש גישה למסד הנתונים: sudo mysql בשרת, או phpMyAdmin / מדור מסד הנתונים בלוח הבקרה של האחסון. לאחר השחזור הפעל מחדש את WebAuthn ואת מסנן ה-IP.

35. כל משימות cron במקום אחד

סיכום המשימות נמצא בcrontab של root בשרת (מתווספות דרך sudo crontab -e). השאירו רק את השורות של הכלים שאתם משתמשים בהם; התאימו את הנתיבים לשרת שלכם.

# cron של המוניטור בשרת (root) — הזינו דרך: sudo crontab -e # 01:30 — סריקת ClamAV בנתיבים מסוכנים (web, home, temp) → כרטיסי “קבצים שנבדקו” ו“סריקה אחרונה” 30 1 * * * /usr/local/bin/clamav-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 02:00 — בדיקת שלמות קבצים של AIDE (נדרש --config מפורש) 0 2 * * * /usr/bin/aide --config /etc/aide/aide.conf --check > /var/log/aide/aide.log 2>&1 # בעת האתחול — לשחזר הרשאות /var/lib/aide (קובץ tmpfiles של החבילה # aide-common.conf מאפס אותן ל-0700, והלוח מפסיק לראות את מסד הנתונים) @reboot chmod 755 /var/lib/aide # 03:00 — ביקורת אבטחה של Lynis 0 3 * * * /usr/local/bin/lynis-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:00 — עדכון רשימת החסימות ipsum (level 1) 0 4 * * * /usr/local/bin/load-ipsum.sh >> /path/to/monitor/logs/cron.log 2>&1 # את סט ipsum בעת האתחול מרים השירות ipsum-load.service (לפני חומת האש, אחרת # UFW לא יראה את הסט ב-before.rules) — לא cron. כאן רק הרענון היומי שלמעלה. # 06:00 — דוח Logwatch 0 6 * * * /usr/local/bin/logwatch_daily.sh >> /path/to/monitor/logs/cron.log 2>&1 # כל 30 דק' — בדיקת דיסקים SMART */30 * * * * /usr/local/bin/smart-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 04:30 — שלמות חבילות debsums 30 4 * * * /usr/local/bin/debsums-scan.sh >> /path/to/monitor/logs/cron.log 2>&1 # 08:00 — דוח מתוזמן לאימייל ולטלגרם 0 8 * * * /usr/local/bin/daily-report-all.sh >> /path/to/monitor/logs/cron.log 2>&1 # כל שעה — רענון רשימות החבילות (לכרטיס “עדכוני אבטחה”) 0 * * * * /usr/bin/apt-get update -qq >/dev/null 2>&1 # כל 5 דק' — צילום מצב משאבים (CPU/RAM/רשת/דיסק) לעמוד “ביצועים” */5 * * * * /usr/local/bin/collect-metrics-all.sh >> /path/to/monitor/logs/cron.log 2>&1
פרטים על כל אחד — בסעיפים המתאימים. משימות הגיבוי (הסעיף הקודם) מתווספות לאותו cron. אחרי העריכות בדקו: sudo crontab -l ושירות cron פעיל.
זמן cron = אזור הזמן של השרת, ולא TIMEZONE מתוך config.php. הקבוע TIMEZONE משפיע רק על PHP (כיצד הלוח מציג תאריכים), אך דמון ה-cron מריץ משימות לפי שעון המערכת של מערכת ההפעלה. אם אזור הזמן של השרת לא תואם לשלכם, הדוח של “08:00” יגיע בזמן אחר. דוגמה: השרת נמצא באזור זמן אחר (Europe/Berlin, UTC+2), ואתם בירושלים (UTC+3) → הדוח של “08:00” יגיע ב-09:00 לפי הזמן שלכם. בדקו ובמידת הצורך התאימו את אזור הזמן של המערכת לשלכם:
# בדיקת אזור הזמן הנוכחי של השרת: timedatectl # הגדרת אזור הזמן שלכם (דוגמה) והפעלה מחדש של cron: sudo timedatectl set-timezone Asia/Jerusalem sudo systemctl restart cron
לאחר מכן השורה 0 8 * * * תופעל ב-08:00 לפי הזמן המקומי. אחרת היה צורך להזיז את ה-cron עצמו, אך במעבר לשעון חורף/קיץ ההיסט שוב יסטה — לכן נכון יותר להגדיר את אזור הזמן של המערכת.
סקריפטים־עוטפים מוכנים. העותקים הפעילים שלהם ודוגמת crontab (crontab.txt) נמצאים בתיקייה system/ ליד הפרויקט, מחוץ ל-public_html. זה לא חלק מהאתר — אין צורך להעלות אותם לשורש האתר; מקמו אותם על השרת בנתיבי המערכת (כמו ב-crontab שלמעלה):
  • lynis-scan.sh/usr/local/bin/ (chmod +x) — מריץ lynis audit system, בזמן הסריקה מציב את הדגל /tmp/lynis-running ומעתיק את lynis-report.dat אל data/lynis/ של הלוח;
  • logwatch_daily.sh/usr/local/bin/ (chmod +x) — יוצר דוח Logwatch יומי (sshd, fail2ban, sudo, postfix) אל data/logwatch/;
  • smart-scan.sh/usr/local/bin/ (chmod +x) — קורא את מצב הדיסקים (smartctl) אל data/disk/;
  • debsums-scan.sh/usr/local/bin/ (chmod +x) — בודק שלמות חבילות (debsums) אל data/debsums/;
  • clamav-scan.sh/usr/local/bin/ (chmod +x) — סריקת אנטי־וירוס של ClamAV בנתיבים מסוכנים (web, home, temp); כותב סיכום אל /var/log/clamav/scan.log, שממנו קורא אותו עמוד ClamAV (שורת 01:30 ב-crontab שלמעלה);
  • load-ipsum.sh/usr/local/bin/ (chmod +x) — מעדכן את סט ה-ipset ipsum (level 1) במקום, בלי לשבור את כללי חומת האש הפעילים (שורת 04:00 ב-crontab למעלה);
  • daily-report-all.sh/usr/local/bin/ (chmod +x) — מריץ את דוח cron/daily_report.php של הלוח (שורת 08:00 ב-crontab שלמעלה);
  • daily_report.php — כבר כלול בלוח (cron/daily_report.php), מופעל דרך daily-report-all.sh, אין צורך להתקין בנפרד;
  • collect-metrics-all.sh/usr/local/bin/ (chmod +x) — מריץ את cron/collect_metrics.php של הלוח (עמוד “ביצועים”, שורת */5 ב-crontab שלמעלה); collect_metrics.php כבר כלול בלוח, אין צורך להתקין בנפרד;
  • crontab.txt (system/cron/) — דוגמת משימות; את השורות הדרושות הזינו דרך sudo crontab -e.
הנתיב לסקריפט ב-crontab חייב להתאים למקום שאליו שמתם אותו.
כיצד להניח סקריפט ב-/usr/local/bin/. אי אפשר לכתוב לשם ישירות מ-FileZilla — התיקייה בבעלות root, ולקוח ה-SFTP יקבל SSH_FX_PERMISSION_DENIED. סדר הפעולות: תחילה העלו את הקובץ ל-/tmp (לשם כולם יכולים לכתוב), ואז העבירו אותו למקומו בפקודה אחת:
# ב-FileZilla: בשדה “אתר מרוחק” הזינו /tmp והעלו לשם את הסקריפט, # לאחר מכן דרך SSH (install מציב מיד בעלים והרשאות, chown/chmod לא נדרשים): sudo install -o root -g root -m 755 /tmp/lynis-scan.sh /usr/local/bin/lynis-scan.sh rm -f /tmp/lynis-scan.sh # בדיקה: הקובץ במקומו, הרשאות rwxr-xr-x, התחביר תקין bash -n /usr/local/bin/lynis-scan.sh && ls -l /usr/local/bin/lynis-scan.sh
אל תתבלבלו בין התיקיות: נדרש /tmp בשורש השרת — לא /var/tmp ולא tmp/ בתוך הלוח עצמו (האחרון בבעלות www-data וסגור בפני המשתמש שלכם). בעץ של FileZilla /tmp הוא ענף ברמה העליונה, ליד var, ולא בתוכו.
התקנתם את השרת באמצעות הגדרה אוטומטית? העוטפים האלה ומשימות ה-cron שלהם כבר מותקנים על ידי הסקריפט (ב-/usr/local/bin/, יומן — /var/log/arciveo-cron.log) — אין צורך לעשות דבר ידנית.
היכן הסקריפטים מחפשים את הלוח. העוטפים ניטרליים לדומיין: הם מוצאים התקנות של הלוח על ידי מעבר על /home/*/web/*/public_html ו-/var/www/*, ומניחים את הדוחות ב-data/ שלהם. אם הלוח נמצא בנתיב אחר — הוסיפו אותו לשורה for app in … בתוך הסקריפטים, אחרת דוחות Lynis/SMART/debsums/Logwatch לא יגיעו ללוח.
cron.log והרשאות גישה. את הקובץ logs/cron.log יוצר ראשון cron של root — הוא יהיה בבעלות root, ולשונית “יומן cron” בלוח לא תוכל לקרוא אותו ולא לנקות אותו. צרו את הקובץ מראש בשם משתמש הרשת (הבעלים של תיקיית האתר; ב-HestiaCP זהו החשבון, למשל admin) — כך cron של root רק יוסיף לו, בלי לשנות את הבעלים:
# צור מראש בשם משתמש הרשת (לפני הוספת שורות cron): sudo -u OWNER touch /path/to/monitor/logs/cron.log # אם cron.log כבר נוצר על ידי cron של root — העבר למשתמש הרשת: sudo chown OWNER:OWNER /path/to/monitor/logs/cron.log sudo chmod 644 /path/to/monitor/logs/cron.log
לבדיקת הבעלים של התיקייה: stat -c %U /path/to/monitor.
ניהול מתוך הלוח. בסעיף “מערכת” יש עמוד “Crontab” — אפשר לצפות ולהוסיף משימות ללא SSH. הלוח עורך רק משימות שנוספו דרכו (בלוק נפרד ב-root-crontab, המסומן בהערות שירות); כל מה שכבר קיים ב-crontab (הרשימה שלמעלה) מוצג שם ברשימת קריאה בלבד “משימות אחרות של השרת” עם כפתור “העתק לעורך” — הוא רק מעביר את התזמון/הפקודה לטופס ההוספה, מבלי לגעת בשורה המקורית. כדי “להעביר” משימה קיימת לניהול הלוח — העתיקו אותה לעורך, שמרו, ולאחר מכן מחקו את השורה הישנה ידנית (sudo crontab -e), אחרת היא תרוץ פעמיים.
הגדרה חד־פעמית בשרת. העמוד זקוק לסקריפט־עוטף מורשה — לא sudo crontab חשוף (זו הייתה הסלמה ישירה ל-root על ידי כל מי שיקבל גישה להפעלת הלוח), אלא סקריפט צר עם שתי פקודות (list/set), הנוגע רק בבלוק שלו בין הערות השירות. התקינו פעם אחת:
sudo install -m 0755 -o root -g root /dev/stdin /usr/local/sbin/arciveo-cron <<'ARCIVEO_CRON_EOF' #!/bin/bash set -euo pipefail BEGIN='# >>> ARCIVEO-CRON-MANAGED (edited from the panel; do not edit by hand) >>>' END='# <<< ARCIVEO-CRON-MANAGED <<<' cmd=${1:-} case "$cmd" in list) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} list" >&2; exit 2; } crontab -l -u root 2>/dev/null || true ;; set) [ "$#" -eq 1 ] || { echo "usage: ${0##*/} set (body on stdin)" >&2; exit 2; } body=$(cat) if grep -qF "$BEGIN" <<<"$body" || grep -qF "$END" <<<"$body"; then echo "invalid body: markers not allowed" >&2; exit 2 fi current=$(crontab -l -u root 2>/dev/null || true) tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT { if grep -qF "$BEGIN" <<<"$current"; then awk -v b="$BEGIN" '{print} $0==b{exit}' <<<"$current" else [ -n "$current" ] && printf '%s\n' "$current" echo "$BEGIN" fi printf '%s\n' "$body" echo "$END" if grep -qF "$END" <<<"$current"; then awk -v e="$END" 'f{print} $0==e{f=1}' <<<"$current" fi } > "$tmp" crontab -u root "$tmp" ;; *) echo "usage: ${0##*/} <list|set>" >&2; exit 2 ;; esac ARCIVEO_CRON_EOF echo "www-data ALL=(ALL) NOPASSWD: /usr/local/sbin/arciveo-cron" | sudo tee -a /etc/sudoers.d/monitor sudo visudo -c
משתמש הרשת עשוי להיות שונה מ-www-data — בדקו תחת איזה משתמש רץ מאגר ה-PHP-FPM של האתר (ps -o user= -C php-fpm), והציבו אותו בשורת sudoers.
הקובץ החדש הועלה בבעלות שגויה — העמוד מחזיר “Access denied.”. אם הקובץ public/crontab_monitor.php הועלה ב-FTP/SFTP תחת משתמש מערכת אחר (למשל root) מזה של שאר קבצי האתר, שרת הרשת לא יוכל לקרוא אותו. השוו את הבעלים וההרשאות לקובץ סמוך והתאימו:
ls -la public/crontab_monitor.php public/ssl_monitor.php sudo chown OWNER:OWNER public/crontab_monitor.php sudo chmod 644 public/crontab_monitor.php

אבחון

36. הכלי מותקן, אך מוצג “לא מותקן”

המוניטור מזהה את הימצאות הכלים באמצעות dpkg-query — מסד החבילות של APT. אם הכלי לא הותקן דרך apt (ידנית, מ-snap או מקוד המקור), dpkg לא רואה אותו.

# בדיקה דרך dpkg: dpkg -l fail2ban | grep '^ii' dpkg -l auditd | grep '^ii' # איתור הנתיב לקובץ הבינארי: which ufw fail2ban-client auditctl # בדיקת sudo מ-www-data: sudo -u www-data sudo fail2ban-client status sudo -u www-data sudo ufw status verbose

37. פתרון תקלות (500, אין נתונים)

שגיאה 500 — בדקו את יומני PHP, nginx והמוניטור עצמו:

tail -50 /var/log/nginx/error.log tail -50 /var/log/php*-fpm.log # יומני המוניטור: tail -50 logs/monitor_$(date +%Y-%m-%d).log # הרשאות לתיקיות: ls -la data/ tmp/ logs/
הלוח על פאנל אירוח (HestiaCP, ISPmanager, cPanel)? שם PHP רץ לא תחת www-data, אלא תחת חשבון המשתמש (למשל admin — הבעלים של תיקיית האתר). את כל כללי sudo וחברות בקבוצות (adm, systemd-journal) צריך להגדיר למשתמש הזה, אחרת המודולים יציגו “לא פעיל / 0” בזמן ששירותים פועלים. לבירור משתמש PHP האמיתי: ps -o user= -C php-fpm | sort -u או הבעלים של תיקיית האתר stat -c '%U' /path/to/monitor. בהמשך בכל הפקודות למטה הציבו אותו במקום www-data. ההתקנה האוטומטית מזהה את משתמש הרשת בעצמה ומגדירה עבורו את sudoers.

הנתונים לא מוצגים — כמעט תמיד הרשאות sudo שלא הוגדרו. בדקו את הפקודה הספציפית בשם משתמש הרשת (החליפו את www-data בשלכם). הדגל -n = ללא סיסמה, כמו ב-PHP — אם מבקש סיסמה, סימן שאין כלל ב-sudoers:

sudo -u www-data sudo -n fail2ban-client status sudo -u www-data sudo -n ufw status verbose sudo -u www-data sudo -n ipset list -t ipsum sudo -u www-data sudo -n /usr/sbin/ausearch -m USER_LOGIN -ts today sudo -u www-data sudo -n /usr/sbin/aa-status sudo -u www-data sudo -n /usr/sbin/psad --Status sudo -u www-data journalctl -u falco --no-pager -n 5
המודול כותב “לא פעיל” / “0”, למרות שהכלי פועל (למשל sudo aa-status בטרמינל מציג פרופילים, ועמוד “AppArmor” — “לא פעיל”). הסיבה: למשתמש הרשת אין הרשאת sudo לפקודה של המודול הזה. בדקו אותה מהרשימה למעלה: אם מבקש סיסמה — הוסיפו את השורה החסרה אל /etc/sudoers.d/monitor (“הגדרת sudo”). פקודות “חדשות” נפוצות: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
אם עמוד ספציפי (Falco, ModSecurity, Auditd, פורטים פתוחים של UFW) ריק — השוו לרשימה בחלק על sudo: כנראה לא הותרו apache2ctl, ausearch, aa-status או ss, או שמשתמש הרשת אינו בקבוצות adm/systemd-journal (משם נקראים יומני fail2ban/auth/modsec ו-journalctl — Falco ואירועי ליבה).

38. הדף ריק, למרות שיש נתונים בשרת

סימפטום: בשרת יש נתונים (נראים דרך shell), אבל הדף מציג “אין נתונים” או סטטוס שגוי — לדוגמה AIDE מציג “לא מאותחל”, למרות שהמסד נוצר.

הסיבה היא open_basedir: פאנלים ואירוחים רבים מגבילים את מאגר PHP-FPM לתיקיית הדומיין, ולכן פונקציות PHP file_exists(), file_get_contents(), filemtime() לנתיבי מערכת (/var/lib/aide, /var/log, /proc…) נחסמות. המוניטור עוקף זאת בכך שהוא קורא נתיבים אלה באמצעות פקודות מערכת רגילות (cat, test, stat).

# האם הקובץ נראה דרך shell (כך המוניטור קורא): sudo -u www-data bash -lc 'test -e /var/lib/aide/aide.db && echo VISIBLE || echo NO' # הערך הנוכחי של open_basedir עבור מאגר הדומיין: grep -ri open_basedir /etc/php/*/fpm/pool.d/ 2>/dev/null
אם shell “רואה” את הקובץ (VISIBLE) אבל הדף לא — זה open_basedir. הפתרון הנכון הוא קריאה באמצעות פקודות מערכת (כבר בוצע עבור AIDE ומוניטור הרשת). אין צורך להרחיב את open_basedir אל /var, /proc וזה גם פחות בטוח.

39. דף ה-SSL אינו פועל

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

# בדיקת תעודה ידנית: echo | openssl s_client -connect monitor.example.com:443 2>/dev/null \ | openssl x509 -noout -dates # בדיקת נגישות: curl -I https://monitor.example.com
את הדומיינים המוניטור לוקח אוטומטית מקובצי התצורה של nginx (/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) ושל Apache (/etc/apache2/sites-enabled/) בתוספת המארח הנוכחי מתוך HTTP_HOST.
זיהוי אוטומטי של תת-דומיינים. תת-הדומיינים מזוהים אוטומטית מיומני Certificate Transparency הציבוריים ונבדקים ברשת — גם אם הם מאוחסנים בשרתים אחרים. אין צורך להוסיף דבר ידנית.

40. נראה רק מסד נתונים אחד מתוך כמה

המוניטור מתחבר ל-MySQL תחת המשתמש מ-config.php, שיש לו גישה רק למסד שלו. MySQL מציג ב-information_schema רק מסדים שיש עליהם הרשאות — ולכן היתר אינם נראים.

כדי שהמוניטור יראה את כל מסדי הנתונים, העניקו למשתמש זה הרשאת קריאה בלבד (פעם אחת כ-root; הזינו את שם המשתמש מ-config.php):

sudo mysql -u root GRANT SELECT, PROCESS, SHOW DATABASES ON *.* TO 'DB_USER'@'localhost'; FLUSH PRIVILEGES; EXIT;
SELECT ON *.* מעניק הרשאת קריאה בלבד — אי אפשר לשנות, למחוק או ליצור דבר, וזה בטוח לצורכי ניטור.
ללא ה-GRANT הזה הלוח רואה רק את המסד שלו — זו אינה שגיאה אלא הגבלת הרשאות. הלוח אינו משתמש כלל ב-sudo mysql: רשימת המסדים מתקבלת דרך חיבור ה-PDO שלו עצמו.

41. PostgreSQL אינו מוצג בעמוד “מסד נתונים”

PostgreSQL דורש הרשאות ברמת המשתמש postgres, שאין למשתמש הרשת של הפאנל. פתיחת sudo psql רחב מתוך PHP אינה בטוחה — במקום זאת הפאנל קורא לעטיפה מצומצמת ללא פרמטרים, שמדפיסה רק את הגרסה, מספר החיבורים ורשימת מסדי הנתונים עם הגדלים. צור אותה:

sudo tee /usr/local/bin/monitor-pgstat >/dev/null <<'EOF' #!/bin/sh # Arciveo Monitor - read-only PostgreSQL version, connections and per-database size sudo -u postgres psql -tAc "SELECT version();" | grep -oE 'PostgreSQL [0-9.]+' echo "---" sudo -u postgres psql -tAc "SELECT count(*) FROM pg_stat_activity;" echo "---" sudo -u postgres psql -tAc "SELECT datname || '|' || pg_size_pretty(pg_database_size(datname)) FROM pg_database WHERE datistemplate = false;" EOF sudo chown root:root /usr/local/bin/monitor-pgstat sudo chmod 755 /usr/local/bin/monitor-pgstat # ב-/etc/sudoers.d/monitor (המשתמש = זה שתחתיו רץ PHP-FPM): # www-data ALL=(ALL) NOPASSWD: /usr/local/bin/monitor-pgstat
אם אינך משתמש ב-PostgreSQL — הסר את השורה monitor-pgstat מ-sudoers (שלב 13 של ההתקנה הידנית) ואל תיצור את הסקריפט עצמו: כרטיס PostgreSQL פשוט יישאר לא פעיל.

42. התראה הופעלה — מה עושים

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

  • מפת מתקפות / הרבה חסימות fail2ban — זה תקין לכל שרת ברשת (בוטים מנסים כל הזמן SSH/אתר). העיקר שהחסימות יעבדו. ודא שכניסה ב-SSH היא רק לפי מפתח (סיסמה מנוטרלת), וש-IP שלך נמצא ב-ignoreip.
  • ModSecurity חסם בקשות — ה-WAF הודף מתקפות על האתר, זו עבודתו. אם התעבורה הלגיטימית שלך נחסמת (זיהוי שגוי) — מצא את rule id בפרטים והוסף חריגה לתצורת ה-CRS.
  • AIDE: קבצים שונו — הצלב את הרשימה מול מה שעשית (עדכון חבילות, עריכת תצורה — תקין). שינוי בינאריות מערכת שלא נגעת בהן — סיבה להישמר. אחרי שינויים לגיטימיים עדכן את מסד AIDE.
  • debsums: בינאריות/ספריות שונו (מחוץ ל-/etc, מחוץ ל-/usr/share) — פוטנציאל להחלפה. הצלב את החבילה: debsums PACKAGE_NAME, ובמקרה של ספק התקן אותה מחדש (apt install --reinstall).
  • ClamAV / maldet: אותרה איום — בדוק את הקובץ בהסגר, אל תפתח אותו. אם זהו web-shell בתיקיית האתר — בודד את השרת וחפש את נקודת הכניסה (תוסף פגיע, דליפת הרשאות).
  • Falco: אירועים קריטיים (הרצת shell במכולה, גישה לקבצים רגישים) — נתח את האירוע: של מי התהליך, מה הריץ אותו. לעיתים קרובות זו פעילות ניהול לגיטימית.
  • חשיפה חיצונית: מסד נתונים/מטמון באדום — סגור מיד: קשר את השירות ל-127.0.0.1 או סגור את הפורט ב-UFW. זהו פרצה אמיתית.
  • SSL עומד לפוג / פג — חדש את התעודה (Let's Encrypt מתחדש לבד; אם לא — בדוק את certbot renew או את ההגדרות בדשבורד).
  • עדכוני אבטחה ממתינים — התקן: sudo apt update && sudo apt upgrade; אחרי עדכון הליבה אתחל את השרת.
סימנים לפריצה אמיתית (תהליכים/משתמשים לא מוכרים, בינאריות ששונו, ספאם יוצא, משימות cron לא מוכרות): נתק את השרת מגישה חיצונית, צור גיבוי לצורך ניתוח, ואם הנתונים קריטיים — הקם שרת נקי מגיבוי מהימן — קשה לנקות rootkit באופן אמין.
Arcivéo - Security Monitor © 2026