מסנן Fail2ban עבור OpenVPN Access Server: real_ip ו-jails
ה-Access Server כותב פורמט לוג משלו, ולכן מסננים סטנדרטיים לא מוצאים דבר. עגנו על real_ip, פצלו את ה-jails לפי משטח ובדקו שהכתובת אינה פרוקסי.
העתקתם OpenVPN jail מפוסט קהילתי, הפעלתם מחדש את fail2ban, ואף כתובת לא נחסמת לעולם. הסיבה היא כמעט תמיד פורמט הלוג: ה-Access Server אינו כותב את שורות כשל האימות שמסנן סטנדרטי מצפה להן. לפני שנוגעים במסנן, ודאו שהרשומות בכלל קיימות, כי תבנית לא יכולה להתאים למה שהשירות מעולם לא רשם.
זהו ה-runbook שאני עוקב אחריו במארח Access Server: לאשר את צורת הרשומה, לכתוב ביטוי מעוגן אחד, לבדוק אותו מול הלוג האמיתי, ואז לפצל את ה-jails לפי המשטח שמותקף ולוודא שהחסימה מגיעה לחומת האש.
ודאו שרשומת הכשל קיימת
ה-Access Server כותב את שורותיו המובנות אל /var/log/openvpnas.log, וכתובת הלקוח נמצאת בשדה real_ip בתוך מרכאות ולא בתחילת שורת syslog. חפשו התחברות כושלת שאתם יודעים שהתרחשה לפני שכותבים תבנית כלשהי:
grep -i 'LOG ERR' /var/log/openvpnas.log | tail -20אם לא מופיע דבר, רמת הלוג היא החשוד הבא. ל-Access Server יש מתג ניפוי שגיאות של מסד הנתונים של הלוג ב-/usr/local/openvpn_as/etc/as.conf (DEBUG_LOGDB=1), ו-יש להפעיל מחדש את השירות לאחר שינוי שלו. התייחסו למתג הזה כהגדרת אבחון שיש להוריד בחזרה ברגע שיש לכם תבנית, ולא כתצורה קבועה.
בזמן שאתם בקובץ, שימו לב אילו משטחים כותבים אליו. כשלים בפורטל הלקוח, בממשק הניהול ובאימות המנהרה נוחתים באותו קובץ עם סמנים שונים, והפרט הזה קובע מאוחר יותר את פריסת ה-jails.
עגנו מסנן אחד על real_ip
שמרו על הביטוי צר. מסנן שתובע כל שורה שמכילה כתובת IP יחסום אנשים בגלל ניתוקים רגילים, ובשרת עמוס הסימפטום היחיד הוא שמשתמשים מתלוננים שננעלו בחוץ כי סגרו מחשב נייד. תבעו את רשומת השגיאה ולכדו את הכתובת שבתוך המרכאות:
# /etc/fail2ban/filter.d/openvpnaccess.local
[Definition]
failregex = ^ .*LOG ERR.*"real_ip": "<HOST>".*
ignoreregex =הרווח המוביל אינו קוסמטי. ה-Access Server מכניס את רשומותיו פנימה, ועגינה עליו מונעת מהתבנית לתבוע גם שורות ששירותים לא קשורים כותבים לאותו קובץ. אם לרשומות שלכם יש במקום זאת חותמת זמן מובילה, התאימו את הקידומת הזו, אבל עגנו על משהו שבאמת קיים בכל רשומה שאתם מתכוונים לתבוע.
כשאתם צריכים דיוק לפי משטח, צמצמו עוד בכך שתדרשו את סמן המשטח (WEB_CLIENT, WEB_ADMIN או VPN) באותה שורה. מסנן אחד עם שלוש תבניות קל יותר לביקורת משלושה מסננים שנבדלים במילה אחת.
בדקו את הביטוי לפני הפעלת jail
לעולם אל תפעילו מסנן שלא הרצתם מול לוג הייצור. הבדיקה המתועדת מעבירה את המסנן פעמיים, פעם אחת לטעינה ופעם אחת ליישום, ודוח השורות שהוחמצו הוא החלק ששווה לקרוא:
fail2ban-regex --print-all-missed /var/log/openvpnas.log \
/etc/fail2ban/filter.d/openvpnaccess.local \
/etc/fail2ban/filter.d/openvpnaccess.local > missed.txtהשוו את מספר ההתאמות לכשלים שאימתתם בשלב הראשון. אפס התאמות משמעותו שהתבנית שגויה; התאמות בשורות שאינן כשלי אימות משמען שהיא רחבה מדי. קראו את missed.txt עד שתוכלו להסביר כל שורה שבחרתם לא לתבוע.
עשו את הבדיקה הזו על עותק אם הלוג גדול, והריצו אותה שוב לאחר כל שדרוג של Access Server. פורמט הלוג הוא הממשק שמולו אתם מתאימים, והוא אינו API יציב.
פצלו את ה-jails לפי משטח, לא לפי דמון
Access Server אחד מציג כמה משטחי אימות: ממשקי ווב של לקוח ושל ניהול בפורט 943/tcp, והמנהרה בפורט 1194/udp או 443/tcp ברוב הפריסות. jail אחד שמכסה את כולם מאפשר לניסיונות ניחוש במנהרה לחסום כתובת שהיא גם נתיב הניהול שלכם, והוא מסתיר איזה משטח באמת מותקף. תנו לכל משטח jail משלו עם הפורט והספים שלו:
# /etc/fail2ban/jail.d/openvpnaccess.local
[openvpnas-web-client]
enabled = true
port = 943
protocol = tcp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 3
findtime = 10m
bantime = 1h
[openvpnas-tunnel]
enabled = true
port = 443
protocol = udp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 5
findtime = 10m
bantime = 1hהתחילו במונים קטנים ובחסימה קצרה, והעלו אותם לאחר שצפיתם בשבוע של תעבורה אמיתית. סף נדיב על כתובת משרד משותפת מעניש כל משתמש מאחורי NAT אחד, וחסימה אגרסיבית על משטח המנהרה מנתקת לקוחות לגיטימיים שפרטי ההזדהות השמורים שלהם פגו במהלך הלילה.
אמתו את החסימה, את ה-backend ואת הנזק הנלווה
לאחר הפעלה מחדש, פלט הסטטוס הוא האישור המהיר ביותר שה-jail קיים וסופר:
fail2ban-client status
fail2ban-client status openvpnas-tunnelלאחר מכן אמתו שהחסימה מגיעה לחומת האש שאתם באמת מפעילים, כי jail שהוגדר ל-backend שאיש אינו אוכף אינו מגן על דבר. עם פעולת iptables הכתובות מופיעות בשרשרת הקרויה על שם ה-jail (f2b-openvpnas-tunnel); עם פעולת nftables הן נופלות לקבוצה בטבלה של fail2ban עצמו. בדקו את זו שהמארח שלכם משתמש בה במקום להניח.
שני בדיקות נלוות חשובות מהחסימה עצמה. ראשית, אמתו ש-real_ip הוא כתובת הלקוח ולא מאזן עומסים או פרוקסי הפוך; מאחורי פרוקסי כל חסימה נופלת על הפרוקסי וגוררת איתה את כל השירות. שנית, כתבו את נוהל ביטול החסימה, כי הכתובת שחוצה את הסף ב-02:00 שייכת בדרך כלל למהנדס התורן: fail2ban-client set openvpnas-tunnel unbanip 203.0.113.24.
שמרו על הגבול בזמן הכיול. Fail2ban הוא מגביל קצב על משטח אימות אחד, לא שכבת בקרת גישה. הוא אינו מחליף MFA, הגבלות לפי חשבון או החזקת ממשק הניהול מחוץ לאינטרנט הציבורי, ול-Access Server יש הגדרות autoban משלו ששווה לבדוק לפני שעורמים שני מגבילי קצב על אותו פורט.