SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-07

วิธีติดตั้ง Fail2ban บน Ubuntu 24.04 ป้องกัน SSH บอท

เรียนรู้วิธีติดตั้ง Fail2ban บน Ubuntu 24.04 เพื่อป้องกันการสุ่มรหัสผ่าน SSH พร้อมวิธีตรวจสอบสถานะด้วย fail2ban-client และวิธีแก้ไขปัญหาหากค่า Total failed ยังคงเป็น 0

การทำงานจริงของ Fail2ban

Fail2ban คือ daemon สำหรับอ่าน log โดยจะคอยตรวจสอบข้อความการยืนยันตัวตนของ SSH และหากพบความล้มเหลวจากที่อยู่ IP เดียวกันหลายครั้งภายในระยะเวลาสั้นๆ โปรแกรมจะรันคำสั่ง firewall เพื่อบล็อกที่อยู่ IP นั้นชั่วคราว นี่คือแนวคิดหลักทั้งหมดของมัน การตั้งค่ามีเพียงประมาณ 30 บรรทัดในไฟล์เดียว และบน Ubuntu 24.04 การติดตั้งทำได้ด้วยคำสั่ง apt เพียงคำสั่งเดียว ซึ่งจะช่วยปกป้องระบบให้คุณทันทีโดยไม่ต้องแก้ไขค่าใดๆ

ต้องทำความเข้าใจให้ชัดเจนว่ามันคืออะไรและไม่ใช่สิ่งใด Fail2ban ไม่ได้ทำหน้าที่ยืนยันตัวตนผู้ใช้ ไม่ได้เข้ารหัสข้อมูลใดๆ และไม่ได้หยุดยั้งความพยายามในการล็อกอินที่มุ่งมั่นเพียงครั้งเดียว แต่จะหยุดยั้งเฉพาะการพยายามซ้ำๆ จากแหล่งที่มาเดิมเท่านั้น มันเป็นเพียงตัวกรองสัญญาณรบกวนและตัวจำกัดอัตราการเข้าถึง ไม่ใช่แม่กุญแจ หน้าที่ของมันคือการทำให้การสแกนพอร์ต 22 ที่เกิดขึ้นอยู่ตลอดเวลาในเบื้องหลังไม่มาสิ้นเปลือง CPU, แบนด์วิดท์ และพื้นที่จัดเก็บ log ของคุณ รวมถึงช่วยชะลอผู้โจมตีที่ต้องใช้ที่อยู่ IP เดียวในการพยายามเข้าถึงระบบ

สิ่งที่ Fail2ban ไม่สามารถทดแทนได้

Fail2ban เป็นปราการชั้นที่ 3 ไม่ใช่ชั้นที่ 1 หากเซิร์ฟเวอร์ของคุณยังยอมรับการล็อกอินด้วยรหัสผ่าน SSH บอทเน็ตที่กระจายตัวอยู่ตามหมายเลข IP นับพันอาจพยายามเดารหัสผ่านต่อไปได้เรื่อยๆ เนื่องจากแต่ละหมายเลข IP จะยังคงอยู่ต่ำกว่าเกณฑ์การแบนที่คุณตั้งไว้และไม่ถูกบล็อก การป้องกันที่แท้จริงสำหรับกรณีนี้คือการใช้การยืนยันตัวตนด้วย key-only authentication ซึ่งทำให้การเดารหัสผ่านเป็นไปไม่ได้ไม่ว่าจะมีการพยายามกี่ครั้งก็ตาม การใช้ Fail2ban ควบคู่ไปกับการยืนยันตัวตนด้วย key-only authentication มีประโยชน์ 2 ประการ คือช่วยลดสัญญาณรบกวนจากการพยายาม brute-force ใน log ของคุณ และช่วยคัดกรองตัวสแกนออกไปตั้งแต่เนิ่นๆ เพื่อไม่ให้พวกมันรบกวนพอร์ตของคุณอย่างต่อเนื่อง ให้มองว่านี่คือการป้องกันเชิงลึก (defence in depth) โดย Fail2ban จะทำงานอยู่เบื้องหลังการยืนยันตัวตนด้วย key และอยู่หลัง firewall เสมอ ไม่ใช่ทำงานอยู่หน้าสิ่งเหล่านี้

ข้อกำหนดเบื้องต้นและความเป็นจริงของ Ubuntu 24.04

คุณจำเป็นต้องมี VPS ที่รัน Ubuntu 24.04 โดยมีสิทธิ์ root หรือ sudo และมีการตั้งค่า SSH ไว้เรียบร้อยแล้ว ซึ่งควรเป็นการยืนยันตัวตนด้วย key Fail2ban เป็นซอฟต์แวร์ที่ประหยัดทรัพยากร โดยใช้ RAM เพียงไม่กี่สิบเมกะไบต์และไม่จำเป็นต้องปรับแต่งขีดจำกัดใดๆ

ส่วนนี้คือสิ่งที่คู่มือเก่าๆ มักให้ข้อมูลผิดพลาด เป็นเวลาหลายปีที่คำแนะนำมาตรฐานคือ "ติดตั้ง Fail2ban แล้วเพิ่ม backend = systemd เพราะ Ubuntu เลิกเขียน /var/log/auth.log แล้ว" คำแนะนำนั้นอธิบายถึงการเปลี่ยนแปลงที่เกิดขึ้นจริง โดย image ของเซิร์ฟเวอร์และระบบคลาวด์สมัยใหม่จะไม่มี rsyslog ทำให้ SSH บันทึก log ลงใน systemd journal เท่านั้นและไฟล์ข้อความดังกล่าวได้หายไปแล้ว แต่บน Ubuntu 24.04 แพ็กเกจ Fail2ban ได้รองรับเรื่องนี้ไว้แล้ว แพ็กเกจจะติดตั้ง /etc/fail2ban/jail.d/defaults-debian.conf ลงไป และไฟล์นั้นเอง ไม่ใช่ค่าเริ่มต้นจากต้นทาง คือสิ่งที่เซิร์ฟเวอร์ของคุณใช้งานจริง:

[DEFAULT]
banaction = nftables
banaction_allports = nftables[type=allports]
backend = systemd

[sshd]
enabled = true

โปรดอ่านไฟล์นั้นอย่างละเอียด เพราะมันจะตอบคำถามสองข้อก่อนที่คุณจะเริ่มแก้ไขสิ่งใด backend = systemd หมายความว่า SSH jail จะอ่านข้อมูลจาก journal ดังนั้นการที่ไม่มี auth.log จึงไม่มีผลใดๆ banaction = nftables หมายความว่าการแบนจะถูกบังคับใช้ผ่าน nftables ซึ่งเป็นไฟร์วอลล์ที่ Ubuntu 24.04 ใช้งานจริง แทนที่จะเป็น iptables แบบเดิม และ [sshd] enabled = true หมายความว่า jail จะทำงานตั้งแต่เริ่มบูตเครื่อง ผลลัพธ์คือ apt install fail2ban มาตรฐานบน Ubuntu 24.04 สามารถป้องกันการทำ SSH brute-force ได้ทันทีที่ติดตั้ง งานส่วนใหญ่ของคุณคือการตรวจสอบการทำงาน ปรับแต่งนโยบาย และตรวจสอบให้แน่ใจว่าคุณจะไม่ล็อกตัวเองออกจากระบบ

กับดักของ auth.log แบบเก่าอาจยังคงสร้างปัญหาใน 3 สถานการณ์ ซึ่งควรทำความเข้าใจไว้: คุณติดตั้ง Fail2ban ด้วย pip แทนที่จะเป็น apt ทำให้ไม่มี defaults-debian.conf; คุณอยู่ใน container ที่ไม่มีสิทธิ์และไม่มี systemd journal ให้อ่าน; หรือคุณทำตามคู่มือเก่าแล้วคัดลอก backend = auto ไปวางใน jail.local ของคุณเอง ซึ่งเป็นการเขียนทับค่าเริ่มต้นที่ทำงานได้ดีอยู่แล้ว ส่วนของโหมดความล้มเหลวจะแสดงให้เห็นว่าแต่ละกรณีมีลักษณะอย่างไร

ขั้นตอนที่ 1: ติดตั้งและตรวจสอบสถานะการแบน

sudo apt update
sudo apt install -y fail2ban

Ubuntu 24.04 มาพร้อมกับ Fail2ban 1.0.2 โดยแพ็กเกจจะดึง python3-systemd มาเป็น dependency หลัก ดังนั้น backend ของ journal จึงมีทุกอย่างที่จำเป็นสำหรับการทำงาน บริการจะเปิดใช้งานและเริ่มทำงานโดยอัตโนมัติ:

sudo systemctl status fail2ban

คุณควรใช้ active (running) จากนั้นให้ตรวจสอบ jail ที่กำลังทำงานอยู่:

sudo fail2ban-client status sshd

บน VPS สาธารณะที่เปิดให้เข้าถึงได้เพียงไม่กี่นาที คุณมักจะเห็นการนับจำนวนความล้มเหลวและที่อยู่ IP ที่ถูกแบนแล้ว เนื่องจากอินเทอร์เน็ตมีการสแกนพอร์ต 22 อยู่ตลอดเวลา นี่คือหลักฐานว่าการตั้งค่าเริ่มต้นทำงานได้จริง จากจุดนี้ไปคือการปรับแต่งให้เหมาะสม ไม่ใช่การสร้างใหม่ทั้งหมดจากศูนย์

ขั้นตอนที่ 2: แก้ไขไฟล์ jail.local ห้ามแก้ไข jail.conf

Fail2ban เก็บค่าเริ่มต้นจากผู้พัฒนาไว้ใน /etc/fail2ban/jail.conf ห้ามแก้ไขไฟล์ดังกล่าว เนื่องจากการ apt upgrade แพ็กเกจอาจเขียนทับไฟล์นั้นได้ และการตั้งค่าของคุณจะหายไปโดยไม่มีการแจ้งเตือน Fail2ban จะอ่านไฟล์ตามลำดับที่กำหนด โดยเริ่มจาก jail.conf ตามด้วยไฟล์ทั้งหมดใน jail.d/ จากนั้นจึงเป็น jail.local โดยค่าสุดท้ายที่อ่านได้จะมีผลบังคับใช้ ไฟล์ .local เป็นไฟล์สำหรับผู้ใช้ ซึ่งการอัปเกรดแพ็กเกจจะไม่ส่งผลกระทบต่อไฟล์นี้ กฎเดียวกันนี้ใช้กับตัวกรอง (filters) โดยไฟล์ *.local จะเขียนทับไฟล์ filter.d/*.conf ที่มาพร้อมกับแพ็กเกจ

ดังนั้น คุณควรเขียนไฟล์ jail.local ขนาดเล็กเพื่อกำหนดค่าเฉพาะส่วนที่คุณต้องการแก้ไขเท่านั้น และปล่อยให้ทั้ง jail.conf และ jail.d/defaults-debian.conf ที่มากับแพ็กเกจคงสภาพเดิมไว้เพื่อใช้เป็นข้อมูลอ้างอิง

ขั้นตอนที่ 3: เขียนไฟล์ /etc/fail2ban/jail.local

sudo nano /etc/fail2ban/jail.local

ให้ใส่เนื้อหาต่อไปนี้ลงไป โดยเปลี่ยนที่อยู่บนบรรทัด ignoreip ให้เป็น IP สาธารณะของคุณเอง:

[DEFAULT]
# Ubuntu 24.04 already sets these two in jail.d/defaults-debian.conf.
# Pinning them here documents the dependency and survives if that
# file is ever removed or changed by an upgrade.
backend   = systemd
banaction = nftables

# Ban for one hour ...
bantime  = 1h
# ... if an address fails ...
maxretry = 5
# ... 5 times within 10 minutes.
findtime = 10m

# Never ban these. PUT YOUR OWN IP HERE.
ignoreip = 127.0.0.1/8 ::1 10.0.0.24

# Longer bans for repeat offenders: 1h, 2h, 4h ... up to a week.
bantime.increment = true
bantime.maxtime   = 1w

[sshd]
enabled = true

ทุกบรรทัดมีความสำคัญดังนี้:

  • bantime, findtime, maxretry คือนโยบายการทำงาน ค่าเริ่มต้นที่มากับซอฟต์แวร์อย่าง bantime กำหนดไว้เพียง 10 นาที ซึ่ง 1 ชั่วโมงเป็นค่าเริ่มต้นที่เหมาะสมกว่า การล้มเหลว 5 ครั้งจากที่อยู่เดียวกันภายใน 10 นาทีจะนำไปสู่การแบน ผู้ใช้งานจริงอาจพิมพ์รหัสผ่านผิด 1 หรือ 2 ครั้ง แต่การผิดพลาด 5 ครั้งใน 10 นาทีมักเป็นฝีมือของสคริปต์
  • ignoreip คือมาตรการป้องกันความปลอดภัยของคุณ ให้ใส่ที่อยู่สาธารณะที่คุณใช้เชื่อมต่อ จาก ที่นั่น เพื่อให้ Fail2ban ไม่ล็อกคุณออกจากเซิร์ฟเวอร์ของตัวเอง หากคุณใช้การเชื่อมต่อจากที่บ้านที่มี IP เปลี่ยนแปลงตลอดเวลา แนะนำให้ใช้วิธี VPN ในตอนท้ายแทนการข้ามบรรทัดนี้ไป
  • bantime.increment = true ทำให้การแบนซ้ำแต่ละครั้งยาวนานขึ้นเรื่อยๆ เริ่มจาก 1 ชั่วโมง, 2 ชั่วโมง, 4 ชั่วโมง ไปจนถึง bantime.maxtime ที่อยู่ที่พยายามโจมตีซ้ำๆ จะถูกล็อกไว้นานขึ้นตามลำดับ

ให้หาที่อยู่สำหรับทำ whitelist จากเครื่องที่คุณใช้ SSH เข้ามา ไม่ใช่จากตัวเซิร์ฟเวอร์:

curl -s ifconfig.me

คุณสามารถสร้าง jail.local ที่ปรับแต่งให้เหมาะกับพอร์ตและนโยบายการแบนของคุณได้ที่นี่ จากนั้นจึงคัดลอกไปวางในไฟล์:

ToolFail2ban jail generator

ขั้นตอนที่ 4: รีสตาร์ทและตรวจสอบว่ามีการอ่าน journal

sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

-t จะทำการทดสอบไฟล์คอนฟิกก่อน ดังนั้นหากมีข้อผิดพลาดในการพิมพ์ใน jail.local ระบบจะแจ้งเตือนทันทีแทนที่จะปล่อยให้ service หยุดทำงาน สถานะของ jail ที่ทำงานปกติจะมีลักษณะดังนี้:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     14
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 1
   |- Total banned:     3
   `- Banned IP list:   10.0.0.66

ตัวเลขที่ยืนยันว่า Fail2ban กำลังอ่านข้อมูลการล็อกอินของคุณจริงๆ คือ Total failed หากตัวเลขนี้มากกว่าศูนย์ หรือเพิ่มขึ้นเมื่อคุณจงใจล็อกอินล้มเหลวจากเครื่องอื่น แสดงว่ามีการอ่าน journal แล้วและคุณทำเสร็จสิ้น หากตัวเลขยังคงเป็น 0 ไม่ว่าคุณจะล็อกอินล้มเหลวกี่ครั้งก็ตาม และคุณมั่นใจว่าไม่ได้ทดสอบจากที่อยู่ IP ใน ignoreip ให้ข้ามไปดูหัวข้อรูปแบบความล้มเหลวด้านล่าง

สังเกตว่าบรรทัด Journal matches ยังคงระบุชื่อ sshd.service อยู่ บน Ubuntu นั้น unit ของ SSH จริงๆ คือ ssh.service แต่ตัวกรองที่มากับโปรแกรมก็จับคู่กับ _COMM=sshd ได้เช่นกัน และ OpenSSH บน 24.04 จะบันทึกความล้มเหลวจากกระบวนการที่ชื่อ sshd ดังนั้นการจับคู่จึงทำงานได้ รายละเอียดนี้จะสำคัญก็ต่อเมื่อคุณใช้ OpenSSH เวอร์ชันใหม่กว่า (9.8 หรือใหม่กว่า ซึ่ง worker ต่อการเชื่อมต่อคือ sshd-session) โดยรูปแบบความล้มเหลวจะครอบคลุมกรณีดังกล่าวไว้แล้ว

ขั้นตอนที่ 5: เฝ้าดูการแบนที่เกิดขึ้นจริง หรือบังคับให้แบนเพื่อทดสอบ

การแบนจริงจะเกิดขึ้นเองภายในไม่กี่นาทีบน VPS สาธารณะทุกเครื่อง หากต้องการเฝ้าดู ให้ใช้คำสั่ง tail เพื่อดู log:

sudo tail -f /var/log/fail2ban.log

ลักษณะของการแบนจะเป็นดังนี้:

2026-07-15 10:31:40,502 fail2ban.filter  [812]: INFO    [sshd] Found 10.0.0.66 - 2026-07-15 10:31:40
2026-07-15 10:31:44,118 fail2ban.actions [812]: NOTICE  [sshd] Ban 10.0.0.66

เพื่อพิสูจน์การทำงานของระบบตั้งแต่ต้นจนจบโดยไม่ต้องรอ ให้ทำการแบนที่อยู่ IP ตัวอย่างด้วยตนเอง (ห้ามแบน IP ของตนเอง):

sudo fail2ban-client set sshd banip 10.0.0.66

ระบบจะแสดงผล 1 และที่อยู่ดังกล่าวจะปรากฏภายใต้ Banned IP list ใน fail2ban-client status sshd จากนั้นให้ยืนยันว่ามีการบล็อกเกิดขึ้นจริงใน firewall สำหรับ Ubuntu 24.04 จะใช้ nftables ไม่ใช่ iptables:

sudo nft list table inet f2b-table

คุณจะเห็น set ที่ชื่อ addr-set-sshd ซึ่งบรรจุ 10.0.0.66 อยู่ และ chain f2b-chain ที่ทำหน้าที่ปฏิเสธทุก source ที่อยู่ใน set นั้น หาก fail2ban-client ระบุว่ามีการแบนที่อยู่ IP แล้ว แต่ไม่ปรากฏข้อมูลใน nft list แสดงว่าการตั้งค่า action การแบนของคุณไม่ตรงกับ firewall ที่ใช้งานอยู่ โปรดดูหมายเหตุเรื่อง nftables/iptables ในส่วนของรูปแบบความล้มเหลว (failure modes)

ขั้นตอนที่ 6: ยกเลิกการแบนตัวเอง และกู้คืนการเข้าถึงหากถูกล็อกเอาต์

หากคุณแบนที่อยู่ IP ที่ไม่ควรแบน รวมถึงที่อยู่ของตัวคุณเอง ให้ลบออกด้วยคำสั่ง:

sudo fail2ban-client set sshd unbanip 10.0.0.66

คำสั่งจะส่งคืนค่า 1 เมื่อดำเนินการสำเร็จ หากต้องการล้างการแบนทั้งหมดในทุก jail ให้ใช้:

sudo fail2ban-client unban --all

อย่าพึ่งพา SSH session ที่เปิดค้างไว้เพื่อช่วยคุณ เนื่องจากกฎการแบนของ nftables จะปฏิเสธทุกแพ็กเก็ตจากที่อยู่ที่ถูกแบนไปยังพอร์ต 22 รวมถึงการเชื่อมต่อที่สร้างไว้แล้วด้วย ดังนั้น session ที่มีอยู่จะค้างทันทีที่การแบนมีผล หากคุณแบนตัวเองและไม่มีรายการ ignoreip คุณจะถูกล็อกเอาต์จนกว่าการแบนจะหมดอายุ ให้กู้คืนผ่านเว็บคอนโซลของผู้ให้บริการ (VNC หรือ serial) ซึ่งไม่ได้ผ่าน SSH จากนั้นให้รอจนครบเวลา bantime หรือรันคำสั่งยกเลิกการแบนจากช่องทางนั้น

ขั้นตอนที่ 7: ทำให้การแบนคงอยู่ถาวรและเพิ่มระดับความรุนแรง

Fail2ban เก็บสถานะการแบนที่ใช้งานอยู่ไว้ในฐานข้อมูล SQLite ขนาดเล็กที่ /var/lib/fail2ban/fail2ban.sqlite3 เพื่อให้การแบนยังคงอยู่แม้จะมีการรีสตาร์ทเซอร์วิสหรือรีบูตเครื่อง คุณจึงไม่สูญเสียรายการที่แบนไป บรรทัด bantime.increment ที่คุณเพิ่มเข้าไปก่อนหน้านี้จะทำให้ผู้กระทำผิดซ้ำได้รับผลกระทบที่รุนแรงขึ้นเรื่อยๆ โดยระยะเวลาการแบนจะเพิ่มขึ้นเป็นสองเท่าจากหนึ่งชั่วโมงไปจนถึงหนึ่งสัปดาห์

สำหรับการกำหนดนโยบาย "สามครั้งออก" (three strikes) ทั่วทั้งระบบเพิ่มเติมจากเดิม Fail2ban มี jail ชื่อ recidive ที่คอยเฝ้าดู /var/log/fail2ban.log ของตัวมันเอง และจะทำการแบนระยะยาวกับที่อยู่ IP ใดก็ตามที่ถูกแบนซ้ำๆ ในทุก jail เนื่องจากตอนนี้ [DEFAULT] ของคุณใช้ backend แบบ systemd คุณจึงต้องกำหนด jail นี้ให้กลับไปอ่านไฟล์ log ที่ออกแบบมาให้มันอ่าน:

[recidive]
enabled  = true
backend  = auto
logpath  = /var/log/fail2ban.log
bantime  = 1w
findtime = 1d
maxretry = 5

การใช้ backend = auto ร่วมกับ logpath ที่ระบุไว้อย่างชัดเจน จะช่วยให้ recidive อ่านค่าจาก fail2ban.log โดยตรง ซึ่งเป็นตำแหน่งที่บรรทัด Ban ที่ระบบใช้ในการนับจำนวนปรากฏอยู่ หากใช้ค่าเริ่มต้นของ systemd ที่คุณตั้งไว้ในระดับ global ระบบจะชี้ไปที่ journal ซึ่งไม่มีข้อมูลดังกล่าวอยู่

ขั้นตอนที่ 8: จับคู่กับการใช้ SSH แบบคีย์เท่านั้น และจะดียิ่งขึ้นหากใช้ VPN

Fail2ban จะทำงานได้เต็มประสิทธิภาพก็ต่อเมื่อใช้งานร่วมกับการยืนยันตัวตนด้วยคีย์เท่านั้น ในไฟล์แบบ drop-in ภายใต้ /etc/ssh/sshd_config.d/ เช่น /etc/ssh/sshd_config.d/00-hardening.conf ให้ตั้งค่าดังนี้:

PasswordAuthentication no
KbdInteractiveAuthentication no

จากนั้นให้ sudo systemctl restart ssh เมื่อปิดการใช้งานรหัสผ่าน การโจมตีแบบ brute force จะไม่สามารถทำได้เลย Fail2ban จึงทำหน้าที่ลดปริมาณ log ที่ไม่จำเป็นและคัดกรองผู้สแกนออกไปตั้งแต่เนิ่นๆ วิธีที่แข็งแกร่งยิ่งกว่าคือการปิด SSH จากอินเทอร์เน็ตสาธารณะโดยสิ้นเชิง: นำ SSH ไปไว้หลัง WireGuard VPN ที่คุณโฮสต์เอง และตั้งค่า firewall ที่พอร์ต 22 ให้ตอบสนองเฉพาะการเชื่อมต่อผ่าน tunnel เท่านั้น ไม่มีใครสามารถ brute-force พอร์ตที่พวกเขาเข้าถึงไม่ได้ และ Fail2ban จะกลายเป็นปราการด่านสุดท้ายแทนที่จะเป็นด่านหน้า

Fail2ban ไม่ได้มีไว้สำหรับ SSH เท่านั้น บริการใดก็ตามที่มีการบันทึก log การเข้าสู่ระบบที่ล้มเหลวสามารถสร้าง jail ขึ้นมาจัดการได้ ไม่ว่าจะเป็น mail server, เว็บไซต์บน Nginx หรือ ตัวจัดการรหัสผ่าน Vaultwarden ที่คุณโฮสต์เอง ซึ่งคุณอาจไม่ต้องการเปิดหน้าเว็บสำหรับล็อกอินทิ้งไว้ให้เสี่ยงต่อการถูกสุ่มรหัสผ่าน เมื่อเว็บแอปพลิเคชันอยู่หลัง เว็บไซต์ Nginx ที่มีใบรับรอง Let's Encrypt คุณสามารถกำหนดให้ Fail2ban filter ตรวจสอบ access log ของแอปนั้นได้ในลักษณะเดียวกับที่ SSH jail ตรวจสอบ journal

รูปแบบความล้มเหลวและข้อความแจ้งเตือนที่พบจริง

"Have not found any log file for sshd jail" และ Fail2ban ไม่ยอมเริ่มทำงาน นี่คือปัญหาเก่าของ auth.log ซึ่งบน Ubuntu 24.04 คุณจะพบปัญหานี้ก็ต่อเมื่อมีการตั้งค่าบางอย่างไปทับค่าเริ่มต้นที่มากับแพ็กเกจ, การติดตั้งแบบ pip ที่ไม่มี defaults-debian.conf, คอนเทนเนอร์ที่ไม่มี journal หรือมี backend = auto ตกค้างที่คุณคัดลอกมาวางใน jail.local ในกรณีที่ใช้ backend แบบไฟล์แต่ไม่มี /var/log/auth.log ตัว jail ของ sshd จะหาไฟล์ log ไม่พบและทำให้ daemon ทั้งหมดหยุดทำงาน fail2ban.log จะแสดงผลดังนี้:

ERROR   Failed during configuration: Have not found any log file for sshd jail

เนื่องจากข้อผิดพลาดนี้เป็นระดับวิกฤต (fatal) บริการจึงไม่เริ่มทำงาน และ fail2ban-client status จะรายงานอาการที่เกิดขึ้นตามมา:

ERROR  Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running?

บรรทัดที่ระบุว่า "socket path" ไม่ได้หมายความว่า Fail2ban เสียหาย แต่หมายความว่ามันไม่เคยเริ่มทำงานเพราะ jail หนึ่งไม่สามารถหาไฟล์ log ของตนเองได้ การตั้งค่า backend = systemd ใน [DEFAULT] ซึ่งแพ็กเกจของ Ubuntu ได้ตั้งค่าไว้ให้คุณแล้ว จะช่วยแก้ไขข้อความทั้งสองนี้ได้พร้อมกัน

Jail ทำงานอยู่แต่ Total failed ไม่เพิ่มขึ้นเลย ตัว daemon ทำงานอยู่และกำลังอ่าน journal แต่ความล้มเหลวที่เกิดขึ้นจริงกลับสะสมอยู่ใน journalctl -u ssh ในขณะที่ตัวนับยังคงอยู่ที่ 0 กฎข้อแรกคือให้ตัดสาเหตุที่ชัดเจนออกก่อน: คุณกำลังทดสอบจากที่อยู่ที่ระบุไว้ใน ignoreip ดังนั้นความล้มเหลวของคุณจึงถูกยกเว้นตามการออกแบบ หากไม่ใช่สาเหตุนี้ แสดงว่าคุณกำลังใช้ OpenSSH รุ่นที่ worker ต่อการเชื่อมต่อเป็นแบบ sshd-session (รุ่น 9.8 ขึ้นไป) ซึ่ง journal _COMM ของมันคือ sshd-session ไม่ใช่ sshd ทำให้การจับคู่ (match) ที่มากับค่าเริ่มต้นทำงานผิดพลาด ให้ขยายขอบเขตการจับคู่ในบล็อก [sshd]:

[sshd]
enabled      = true
backend      = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd + _COMM=sshd-session

จากนั้นให้ restart, ทดสอบล็อกอินให้ล้มเหลวจากที่อยู่ที่ไม่อยู่ใน ignoreip และตรวจสอบว่า Total failed เพิ่มขึ้นแล้ว

คุณแบนตัวเอง: Connection refused คุณลืมใส่ที่อยู่ของตัวเองไว้ใน ignoreip, ทดสอบล็อกอินผิดพลาดสองสามครั้ง และตอนนี้:

ssh: connect to host 10.0.0.10 port 22: Connection refused

การถูกปฏิเสธการเชื่อมต่อแทนที่จะเป็นการรอจนหมดเวลา (timeout) คือผลลัพธ์จากค่าเริ่มต้น reject ของการกระทำใน nftables ที่กำลังทำงานกับคุณ ให้แก้ไขตามขั้นตอนที่ 6: ยกเลิกการแบนจากเซสชันอื่นที่ไม่ได้ถูกแบน หรือจากคอนโซลของผู้ให้บริการ (provider console) เพราะเซสชันที่เปิดค้างไว้จากที่อยู่ที่ถูกแบนจะค้างไปด้วย จากนั้นเพิ่มที่อยู่ของคุณลงใน ignoreip เพื่อป้องกันไม่ให้เกิดเหตุการณ์นี้ซ้ำ

Fail2ban แจ้งว่าที่อยู่ถูกแบนแล้ว แต่ยังคงเชื่อมต่อได้ ตัวนับใน status sshd เพิ่มขึ้น แต่ที่อยู่ดังกล่าวยังคงเข้าถึงพอร์ต 22 ได้ นี่คือปัญหาความไม่เข้ากันระหว่าง ban-action กับ firewall ซึ่งบน Ubuntu 24.04 มักหมายความว่าคุณไปทับค่า banaction = nftables ที่ใช้งานได้ปกติด้วย banaction = iptables-multiport ที่คัดลอกมาจากคู่มือเก่า บนเครื่องที่ไม่มีเลเยอร์ iptables fail2ban.log จะแสดงผลดังนี้:

fail2ban.actions [812]: ERROR  Failed to execute ban jail 'sshd' action 'iptables-multiport'

ให้ลบการตั้งค่าที่ทับไว้นั้นออกและปล่อยให้ action nftables ที่มากับแพ็กเกจทำงานตามปกติ หรือหากคุณจัดการ firewall ผ่าน ufw ทั้งหมดและต้องการให้การแบนแสดงผลในนั้น ให้ตั้งค่า banaction = ufw ใน [DEFAULT] จากนั้น restart และตรวจสอบว่ากฎปรากฏขึ้นด้วย sudo nft list ruleset | grep f2b

Fail2ban ไม่เริ่มทำงานหลังจากแก้ไข jail.local การพิมพ์ผิด, หัวข้อที่เกินมา หรือค่าเวลาที่ไม่ถูกต้อง ทำให้บริการปฏิเสธที่จะเริ่มทำงาน ให้สั่งให้ Fail2ban ตรวจสอบการตั้งค่าก่อนที่จะเริ่มรันจริง:

sudo fail2ban-client -t

มันจะระบุชื่อไฟล์และ jail ที่มีปัญหา เช่น Errors in jail 'sshd'. Skipping... เพื่อให้คุณแก้ไขที่ต้นเหตุแทนการเดาสุ่ม

FAQ

การติดตั้ง Fail2ban แบบมาตรฐานบน Ubuntu 24.04 สามารถบล็อกการโจมตี SSH ได้จริงหรือไม่?

ได้ แพ็กเกจนี้มาพร้อมกับ /etc/fail2ban/jail.d/defaults-debian.conf ซึ่งจะเปิดใช้งาน jail ที่ชื่อ sshd โดยมีการตั้งค่า backend = systemd เพื่อให้ระบบอ่านข้อมูลจาก systemd journal แทนการใช้ไฟล์ /var/log/auth.log ที่ไม่มีอยู่จริง และตั้งค่า banaction = nftables เพื่อให้การบล็อกมีผลผ่านไฟร์วอลล์หลักของ Ubuntu ดังนั้นการติดตั้ง apt install fail2ban เพียงอย่างเดียวก็สามารถปกป้อง SSH ได้ตั้งแต่เริ่มบูตเครื่องครั้งแรก คุณสามารถตรวจสอบสถานะได้ด้วยคำสั่ง sudo fail2ban-client status sshd และดูค่า Total failed ว่าต้องไม่เป็นศูนย์

ทำไม Fail2ban ถึงไม่บล็อกอะไรเลยบนเซิร์ฟเวอร์ของฉัน?

ให้ตรวจสอบสาเหตุที่พบบ่อย 3 ประการตามลำดับ คุณอาจกำลังทดสอบจาก IP address ที่อยู่ใน ignoreip ซึ่งถูกยกเว้นไว้โดยการออกแบบ หรือคุณอาจไปเขียนทับค่าเริ่มต้นที่ใช้งานได้ปกติด้วยการคัดลอก backend = auto ไปวางใน jail.local จากคู่มือเก่า ซึ่งจะทำให้การอ่าน journal ล้มเหลวบนอิมเมจที่ไม่มีไฟล์ auth.log หรือคุณอาจกำลังใช้งานอยู่ภายในคอนเทนเนอร์ที่ไม่มี systemd journal ให้ตรวจสอบค่า Total failed ใน fail2ban-client status sshd หากค่านี้ไม่เพิ่มขึ้นเลยในขณะที่ journalctl -u ssh แสดงให้เห็นว่ามีการล็อกอินล้มเหลวเกิดขึ้นจริง แสดงว่า jail กำลังอ่านข้อมูลจากแหล่งที่ผิด

ฉันจะปลดบล็อก IP address ของตัวเองได้อย่างไร?

ให้รันคำสั่ง sudo fail2ban-client set sshd unbanip YOUR.IP.HERE ซึ่งจะส่งค่า 1 กลับมาหากสำเร็จ หรือใช้คำสั่ง sudo fail2ban-client unban --all เพื่อล้างการบล็อกทั้งหมด หากคุณถูกล็อกออกจาก SSH ให้ใช้เว็บคอนโซลหรือ VNC คอนโซลของผู้ให้บริการเพื่อรันคำสั่งเดียวกัน เนื่องจากการบล็อกจะปฏิเสธทุกแพ็กเก็ตจาก IP ของคุณที่ส่งไปยังพอร์ต 22 ทำให้แม้แต่เซสชันที่เปิดค้างไว้ก็จะหยุดทำงาน จากนั้นให้เพิ่ม IP address ของคุณลงใน ignoreip เพื่อป้องกันไม่ให้เกิดเหตุการณ์นี้ซ้ำอีก

jail.conf และ jail.local แตกต่างกันอย่างไร?

jail.conf เก็บค่าเริ่มต้นจากผู้พัฒนา Fail2ban และจะถูกเขียนทับทุกครั้งที่มีการอัปเกรดแพ็กเกจ ดังนั้นการแก้ไขไฟล์นี้จะทำให้ข้อมูลสูญหายในที่สุด แพ็กเกจของ Debian/Ubuntu จะซ้อนทับการตั้งค่าของตนเองผ่าน jail.d/defaults-debian.conf โดยการเปลี่ยนแปลงที่คุณต้องการทำควรอยู่ใน jail.local ซึ่งระบบจะอ่านเป็นลำดับสุดท้ายและมีลำดับความสำคัญสูงสุด อีกทั้งการอัปเกรดจะไม่ส่งผลกระทบต่อไฟล์นี้ ให้เก็บ jail.conf ไว้เป็นไฟล์อ้างอิงแบบอ่านอย่างเดียวเท่านั้น

Fail2ban สามารถใช้แทนการยืนยันตัวตน SSH ด้วยกุญแจ (key-based) ได้หรือไม่?

ไม่ได้ Fail2ban ทำหน้าที่จำกัดอัตราการล็อกอินล้มเหลวซ้ำๆ จาก IP เดียวเท่านั้น แต่ไม่สามารถป้องกันการเดารหัสผ่านแบบช้าๆ และกระจาย IP ได้ ซึ่งแต่ละ IP จะยังคงอยู่ต่ำกว่าเกณฑ์ที่กำหนด การยืนยันตัวตนด้วยกุญแจเท่านั้น (PasswordAuthentication no) จะทำให้การเดารหัสผ่านเป็นไปไม่ได้โดยสิ้นเชิง และ Fail2ban จะช่วยลดสัญญาณรบกวนใน log และคัดกรองตัวสแกนออกไปได้เร็วขึ้น คุณควรใช้งานทั้งสองอย่างร่วมกัน และหากเป็นไปได้ควรจำกัดการเข้าถึง SSH จากอินเทอร์เน็ตสาธารณะโดยตรง