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

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

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

หน้าที่การทำงานของ Fail2ban

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

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

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

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

สิ่งที่ต้องเตรียม และความเป็นจริงของ Ubuntu 24.04

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

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

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

[sshd]
enabled = true

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

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

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

sudo apt update
sudo apt install -y fail2ban

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

sudo systemctl status fail2ban

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

sudo fail2ban-client status sshd

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

Step 2: แก้ไข jail.local ห้ามแก้ไข jail.conf

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

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

Step 3: เขียนไฟล์ /etc/fail2ban/jail.local

sudo nano /etc/fail2ban/jail.local

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

ตรวจสอบที่อยู่ IP ที่ต้องการทำ Whitelist จากเครื่องที่คุณใช้ SSH ออกไป ไม่ใช่จากเครื่อง server:

curl -s ifconfig.me

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

ToolFail2ban jail generator

Step 4: Restart and verify it is reading the 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 กำลังอ่านข้อมูลการ login ของคุณคือ Total failed หากค่ามากกว่าศูนย์ หรือตัวเลขเพิ่มขึ้นเมื่อคุณทดสอบ login ผิดพลาดจากเครื่องอื่น แสดงว่าระบบกำลังอ่าน journal และการตั้งค่าเสร็จสมบูรณ์ หากค่าคงที่อยู่ที่ 0 ไม่ว่าจะลอง login ผิดพลาดกี่ครั้งก็ตาม — และคุณมั่นใจว่าไม่ได้ทดสอบจาก address ใน ignoreip — ให้ไปดูที่หัวข้อปัญหาที่อาจเกิดขึ้นด้านล่าง

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

Step 5: Watch a real ban land, or force one to test

การแบนจริงจะเกิดขึ้นเองภายในไม่กี่นาทีบน 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

หากต้องการทดสอบระบบทั้งหมดโดยไม่ต้องรอ ให้ทำการแบน address ของเอกสารด้วยตนเอง — ห้ามแบน address ของตนเองโดยเด็ดขาด:

sudo fail2ban-client set sshd banip 10.0.0.66

ระบบจะแสดงผล 1 และ address จะปรากฏภายใต้ 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 ที่ทำการ reject ทุก source ใน set นั้น หาก fail2ban-client ระบุว่า address ถูกแบนแต่ไม่มีข้อมูลปรากฏใน nft list แสดงว่าคำสั่งแบนไม่ตรงกับ firewall ที่ใช้งาน — โปรดดูหมายเหตุเกี่ยวกับ nftables/iptables ในส่วน failure modes

Step 6: การยกเลิกการแบนตนเอง และการกู้คืนระบบหากถูกล็อกเอาต์

หากคุณเผลอแบน IP ที่ไม่ควรแบน เช่น IP ของตนเอง ให้ดำเนินการลบออกดังนี้:

sudo fail2ban-client set sshd unbanip 10.0.0.66

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

sudo fail2ban-client unban --all

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

Step 7: Make bans persist and escalate

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

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

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

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

Step 8: ใช้งานร่วมกับ SSH แบบใช้เฉพาะ key และการใช้ VPN เพื่อความปลอดภัยที่ดียิ่งขึ้น

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

PasswordAuthentication no
KbdInteractiveAuthentication no

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

Fail2ban ไม่ได้ใช้สำหรับ SSH เท่านั้น บริการใดก็ตามที่มีการบันทึก log เมื่อมีการ login ล้มเหลวสามารถนำมาสร้าง jail ได้ เช่น mail server, nginx site หรือ self-hosted Vaultwarden password manager ที่คุณไม่ต้องการเปิดหน้าเว็บ login ทิ้งไว้ให้เสี่ยงต่อการถูก credential stuffing เมื่อ web app ทำงานอยู่หลัง nginx site ที่มี Let's Encrypt certificate ให้ตั้งค่า 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, การใช้งานใน container ที่ไม่มี journal, หรือมี backend = auto ที่ค้างอยู่ใน jail.local หากใช้ backend แบบไฟล์ที่ไม่มี /var/log/auth.log ตัว sshd jail จะหาไฟล์ 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 ขั้นแรกให้ตรวจสอบสาเหตุที่ชัดเจนก่อน: คุณกำลังทดสอบจาก address ที่ระบุไว้ใน ignoreip ดังนั้นความผิดพลาดของคุณจึงถูกยกเว้นตามการออกแบบ หากไม่ใช่สาเหตุนี้ แสดงว่าคุณกำลังใช้ OpenSSH build ที่ worker ต่อการเชื่อมต่อคือ sshd-session (9.8 และใหม่กว่า) ซึ่ง journal _COMM คือ sshd-session ไม่ใช่ sshd ทำให้การ match แบบที่แถมมานั้นหาไม่พบ ให้ขยายขอบเขตการ match ใน block [sshd]:

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

ทำการ restart, ทดสอบ login ผิดพลาดโดยตั้งใจจาก address ที่ไม่ได้อยู่ใน ignoreip และตรวจสอบว่า Total failed เพิ่มขึ้นในที่สุด

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

ssh: connect to host 10.0.0.10 port 22: Connection refused

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

Fail2ban ระบุว่า address ถูกแบน แต่ยังสามารถเชื่อมต่อได้ ตัวนับใน status sshd เพิ่มขึ้น แต่ address นั้นยังคงเข้าถึง port 22 ได้ นี่คือความไม่สอดคล้องกันระหว่าง ban-action และ firewall และบน Ubuntu 24.04 มักหมายความว่าคุณได้ตั้งค่า banaction = nftables ทับด้วย banaction = iptables-multiport ที่คัดลอกมาจากคู่มือเก่า ในระบบที่ไม่มี iptables layer 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 ข้อผิดพลาดจากการพิมพ์ เช่น heading ที่เกินมา หรือค่าเวลาที่ไม่ถูกต้อง ทำให้บริการไม่สามารถเริ่มทำงานได้ ให้สั่งให้ Fail2ban ตรวจสอบ config ก่อนเริ่มทำงาน:

sudo fail2ban-client -t

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

FAQ

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

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

ทำไม Fail2ban ถึงไม่ทำการ ban อะไรเลยในเครื่องของฉัน?

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

ฉันจะยกเลิกการ ban IP ของตัวเองได้อย่างไร?

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

ความแตกต่างระหว่าง jail.conf และ jail.local คืออะไร?

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

Fail2ban สามารถใช้แทนการยืนยันตัวตน SSH แบบใช้ key ได้หรือไม่?

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