CrowdSec: กันบอตและการโจมตีด้วยข้อมูลจากชุมชนบน Linux

ติดตั้ง CrowdSec บน Linux Server เลือก collection สำหรับ SSH และ Nginx ติดตั้ง firewall bouncer ตั้ง allowlist จัดการ decision ด้วย cscli และเทียบกับ Fail2ban

โดย ทีมงาน THAI DATA CLOUD อ่าน 13 นาที

แชร์FacebookXLINELinkedIn
CrowdSec — CrowdSec: กันบอตและการโจมตีด้วยข้อมูลจากชุมชนบน Linux
CrowdSec: กันบอตและการโจมตีด้วยข้อมูลจากชุมชนบน Linux

คำตอบสั้น ๆ: ติดตั้ง CrowdSec บน Linux Server เลือก collection สำหรับ SSH และ Nginx ติดตั้ง firewall bouncer ตั้ง allowlist จัดการ decision ด้วย cscli และเทียบกับ Fail2ban

คู่มือนี้อธิบาย CrowdSec ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย

CrowdSec คือระบบป้องกันการโจมตีแบบโอเพนซอร์สที่อ่านล็อกของบริการบนเครื่อง เช่น SSH และ Nginx แล้วจับพฤติกรรมอันตรายอย่างการเดารหัสผ่านหรือการสแกนหาช่องโหว่ เมื่อพบจะสร้างคำตัดสิน (decision) ให้บล็อก IP นั้น และส่งให้ตัวบังคับใช้ที่เรียกว่า Remediation Component หรือ bouncer ไปบล็อกที่ไฟร์วอลล์ จุดที่ต่างจากเครื่องมือรุ่นเก่าคือ CrowdSec แชร์สัญญาณการโจมตีกับชุมชนผู้ใช้ และรับรายการ IP อันตรายกลับมาเป็น Community Blocklist ทำให้บล็อกผู้โจมตีบางรายได้ก่อนที่เขาจะมาถึงเครื่องคุณ

คู่มือนี้เหมาะกับผู้ดูแล Linux Server ที่เปิด SSH หรือเว็บสู่อินเทอร์เน็ต และต้องการลดบอตที่เดารหัสผ่านและสแกนเว็บ เมื่อทำครบ คุณจะติดตั้ง Security Engine เลือก collection ให้ตรงกับบริการ ติดตั้ง firewall bouncer ตั้ง allowlist กันตัวเองถูกบล็อก จัดการ decision ด้วย cscli และรู้ว่าควรใช้ CrowdSec แทนหรือคู่กับ Fail2ban

สิ่งที่ต้องเตรียม

  • Ubuntu, Debian, AlmaLinux หรือ Rocky Linux ที่มีสิทธิ์ root หรือ sudo
  • รายการบริการที่เปิดสู่อินเทอร์เน็ตและตำแหน่งล็อกของแต่ละบริการ เช่น /var/log/nginx/access.log
  • IP สาธารณะของสำนักงานและเครื่องผู้ดูแล สำหรับใส่ allowlist ก่อนเปิดการบล็อก
  • ทางเข้าสำรองอย่าง Console ผ่าน Web UI เผื่อ IP ของคุณถูกบล็อกระหว่างทดสอบ
  • ตรวจว่าไม่มีบริการอื่นใช้พอร์ต 127.0.0.1:8080 และ 6060 ซึ่ง CrowdSec ใช้เป็นค่าเริ่มต้น ด้วย sudo ss -ltnp | grep -E ':8080|:6060'
แผนภาพ CrowdSec อ่านล็อก SSH และ Nginx ผ่าน Security Engine ส่ง decision ไป Local API ให้ firewall bouncer บล็อก และแลกข้อมูลกับ Central API
Security Engine ตรวจจับอย่างเดียว การบล็อกจริงเกิดที่ bouncer ซึ่งดึง decision จาก Local API

ขั้นตอนที่ 1: ติดตั้ง CrowdSec Security Engine

เพิ่มคลังแพ็กเกจของ CrowdSec ด้วยสคริปต์ทางการ แล้วติดตั้งแพ็กเกจหลัก เอกสารของ CrowdSec เตือนว่าแพ็กเกจรุ่น 1.4.6 ที่คลังของ Ubuntu บางรุ่นให้มานั้นเก่าเกินไป จึงต้องตรวจว่าติดตั้งจากคลังของ CrowdSec จริง

curl -s https://install.crowdsec.net | sudo sh

# Ubuntu / Debian
apt-cache policy crowdsec
sudo apt install crowdsec

# AlmaLinux / Rocky Linux
sudo dnf install crowdsec

ตรวจว่า Candidate ของ apt-cache policy มาจาก packagecloud.io และเวอร์ชันสูงกว่า 1.4.6 ตัวติดตั้งจะตรวจบริการที่มีในเครื่องและติดตั้ง collection ที่ตรงกันให้อัตโนมัติ เช่น crowdsecurity/linux และ crowdsecurity/sshd ขั้นตอนทั้งหมดอยู่ในเอกสาร Install CrowdSec on Linux

ณ จุดนี้ CrowdSec จับการโจมตีได้แล้ว แต่ ยังไม่บล็อกอะไร เพราะ Security Engine ทำหน้าที่ตรวจจับอย่างเดียว การบล็อกเป็นหน้าที่ของ bouncer ในขั้นตอนที่ 4

ขั้นตอนที่ 2: เลือก collection ให้ตรงกับบริการ

collection คือชุดของ parser ที่อ่านล็อกและ scenario ที่ตัดสินว่าพฤติกรรมใดเป็นการโจมตี ดูชุดที่ติดตั้งแล้ว และเพิ่มของ Nginx ถ้าเครื่องเป็นเว็บเซิร์ฟเวอร์

sudo cscli collections list
sudo cscli collections install crowdsecurity/nginx
sudo systemctl reload crowdsec

collection ของ Nginx ดึง scenario สำหรับเว็บทั่วไปมาด้วย เช่น การสแกนหาไฟล์ผู้ดูแลหรือการไล่เปิด URL จำนวนมาก ถ้าเป็นเว็บ WordPress ให้เพิ่ม crowdsecurity/wordpress ด้วย ค้นชุดอื่นได้ด้วย sudo cscli collections list -a

ขั้นตอนที่ 3: ตรวจว่า CrowdSec อ่านล็อกได้จริง

ไฟล์ที่ CrowdSec อ่าน (acquisition) อยู่ใน /etc/crowdsec/acquis.yaml และโฟลเดอร์ /etc/crowdsec/acquis.d/ ถ้าตัวติดตั้งไม่พบล็อกของบริการใด ให้สร้างไฟล์เพิ่มเอง เช่น /etc/crowdsec/acquis.d/nginx.yaml

filenames:
  - /var/log/nginx/access.log
  - /var/log/nginx/error.log
labels:
  type: nginx

บนเครื่องที่ไม่มี /var/log/auth.log เพราะเก็บล็อกใน journald อย่างเดียว ให้อ่าน SSH จาก journal แทน โดยสร้าง /etc/crowdsec/acquis.d/sshd-journal.yaml (บน AlmaLinux ชื่อหน่วยคือ sshd.service)

source: journalctl
journalctl_filter:
  - "_SYSTEMD_UNIT=ssh.service"
labels:
  type: syslog

รีสตาร์ตด้วย sudo systemctl restart crowdsec แล้วดูตาราง Acquisition Metrics ใน sudo cscli metrics แต่ละแหล่งต้องมีตัวเลข Lines read และ Lines parsed เพิ่มขึ้น ถ้า Lines parsed เป็นศูนย์ทั้งที่ Lines read เพิ่ม แปลว่าป้ายชื่อ type ไม่ตรงกับ parser ที่ติดตั้งไว้

ขั้นตอนที่ 4: ติดตั้ง firewall bouncer

firewall bouncer ดึง decision จาก Local API ของ CrowdSec แล้วใส่ IP ลงชุดกฎของไฟร์วอลล์ในเครื่อง เลือกแบบที่ตรงกับไฟร์วอลล์ที่ใช้ บน Ubuntu และ Debian รุ่นใหม่แนะนำแบบ nftables

# Ubuntu / Debian
sudo apt install crowdsec-firewall-bouncer-nftables

# AlmaLinux / Rocky Linux
sudo dnf install crowdsec-firewall-bouncer-iptables

sudo cscli bouncers list
sudo systemctl status crowdsec-firewall-bouncer --no-pager

ตัวติดตั้งลงทะเบียน bouncer กับ Local API ให้เอง cscli bouncers list ต้องแสดงชื่อ bouncer พร้อมเวลาดึงข้อมูลล่าสุด ถ้าบริการเริ่มไม่ได้และล็อกบอกว่าเชื่อมต่อ API ไม่ได้ ให้สร้างคีย์ใหม่ด้วย sudo cscli bouncers add firewall-bouncer นำคีย์ที่ได้ไปใส่ในบรรทัด api_key ของ /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml แล้วรีสตาร์ตบริการ ถ้าเครื่องใช้ UFW หรือ firewalld อยู่ด้วย bouncer จะทำงานคู่กันได้ ไม่ต้องปิดไฟร์วอลล์เดิม

ผลคำสั่ง cscli ของ CrowdSec เพิ่ม decision ทดสอบ แสดงรายการ decision จาก ssh-bf และการทดสอบ แล้วลบออก พร้อมตาราง nftables ของ bouncer
decision ที่ระบบสร้างเองมีที่มาเป็น crowdsec ส่วนที่เพิ่มด้วยมือมีที่มาเป็น cscli

ขั้นตอนที่ 5: ตั้ง allowlist และทดสอบการบล็อก

ก่อนปล่อยให้ระบบบล็อกจริง ให้ใส่ IP ที่ไว้ใจใน allowlist ซึ่งมีตั้งแต่ CrowdSec 1.6.8 ขึ้นไป การเปลี่ยนแปลงมีผลทันทีโดยไม่ต้องรีสตาร์ต

sudo cscli allowlists create office -d "office and admin IPs"
sudo cscli allowlists add office 198.51.100.25
sudo cscli allowlists add office 203.0.113.0/28
sudo cscli allowlists inspect office

ทดสอบการบล็อกด้วย IP ที่คุณควบคุมได้แต่ไม่อยู่ใน allowlist เช่น IP ของมือถือที่ใช้ 4G แล้วลองเชื่อมต่อจากเครื่องนั้น การเชื่อมต่อควรค้างจนหมดเวลา เพราะ bouncer ทิ้งแพ็กเก็ตเงียบ ๆ

sudo cscli decisions add --ip 192.0.2.50 --duration 10m --reason "manual test"
sudo cscli decisions list
sudo cscli decisions delete --ip 192.0.2.50
sudo cscli alerts list

decision ที่ระบบสร้างเองมีอายุ 4 ชั่วโมงเป็นค่าเริ่มต้น กำหนดใน /etc/crowdsec/profiles.yaml ถ้าต้องการให้ผู้ที่กลับมาโจมตีซ้ำถูกบล็อกนานขึ้นทุกครั้ง ให้เปิดบรรทัด duration_expr ที่ถูกคอมเมนต์ไว้ในไฟล์นั้น แล้วรีสตาร์ตบริการ

ขั้นตอนที่ 6: เชื่อมต่อ CrowdSec Console และ Community Blocklist

สมัครบัญชีที่ app.crowdsec.net แล้วนำคีย์ลงทะเบียนมาใช้กับเครื่อง จากนั้นกดยอมรับเครื่องในหน้า Console และรีสตาร์ตบริการ

sudo cscli console enroll <ENROLLMENT_KEY>
sudo systemctl restart crowdsec
sudo cscli decisions list -a --origin CAPI | head -15

ตัวเลือก -a ทำให้แสดง decision ที่มาจาก Central API ด้วย ซึ่งปกติจะถูกซ่อนไว้ เครื่องที่ส่งสัญญาณการโจมตีกลับไปสม่ำเสมอจะได้รับ Community Blocklist ส่วนเครื่องที่ไม่ค่อยส่งสัญญาณจะได้ Community Blocklist (Lite) ซึ่งเล็กกว่า สัญญาณจะถูกนับเฉพาะเมื่อใช้ scenario จาก Hub ที่ไม่ได้แก้ไข รายการที่ได้รับปรับตามประเภทการโจมตีที่เครื่องนั้นรายงาน ก่อนเปิดใช้ ให้ตรวจนโยบายขององค์กรเรื่องการส่งข้อมูลออกนอกระบบ แล้วตัดสินใจร่วมกับผู้รับผิดชอบด้านความปลอดภัย

ดูแลให้ parser และ scenario เป็นรุ่นล่าสุดด้วย sudo cscli hub update && sudo cscli hub upgrade เป็นประจำ หรือตั้งเป็นงานอัตโนมัติด้วย systemd Timer

เช็กลิสต์หลังติดตั้ง CrowdSec ตรวจการอ่านล็อก สถานะ bouncer allowlist พอร์ต 8080 และการทำงานร่วมกับ Fail2ban
อ่านล็อกได้ bouncer ดึงข้อมูลได้ และ IP ของทีมอยู่ใน allowlist คือสามเรื่องที่ต้องผ่านก่อน

CrowdSec กับ Fail2ban ควรใช้อะไร

ทั้งสองตัวแก้ปัญหาเดียวกัน คืออ่านล็อกแล้วบล็อก IP ที่ทำตัวอันตราย Fail2ban เหมาะกับเครื่องเดี่ยวที่ต้องการเครื่องมือเรียบง่ายที่ทีมคุ้นเคย ดูวิธีตั้งได้ใน คู่มือป้องกันการเดารหัสผ่าน SSH ด้วย Fail2ban ส่วน CrowdSec เหมาะเมื่อมีหลายเครื่องที่ต้องใช้ decision ร่วมกัน ต้องการ scenario สำหรับเว็บที่ดูแลโดยชุมชน หรืออยากได้ Community Blocklist ถ้าจะเปลี่ยนจาก Fail2ban ให้ปิด jail ของบริการเดียวกันก่อน เพื่อไม่ให้สองระบบบล็อกซ้อนกันจนไล่หาสาเหตุยาก

ตารางเปรียบเทียบ CrowdSec กับ Fail2ban ทั้งวิธีตรวจจับ วิธีบล็อก ข้อมูลจากชุมชน การใช้หลายเครื่อง และความคุ้นเคยของทีม
เครื่องเดี่ยวที่ทีมคุ้นกับ Fail2ban ใช้ต่อได้ หลายเครื่องหรือต้องการข้อมูลจากชุมชนเลือก CrowdSec

ปัญหาที่พบบ่อยเกี่ยวกับ CrowdSec

CrowdSec เริ่มไม่ได้และล็อกขึ้น address already in use ทำอย่างไร?

มีบริการอื่นใช้พอร์ต 8080 อยู่ เปลี่ยน listen_uri ในส่วน api.server ของ /etc/crowdsec/config.yaml เป็นพอร์ตอื่น เช่น 127.0.0.1:8081 แล้วแก้ url ใน /etc/crowdsec/local_api_credentials.yaml และ api_url ในไฟล์ของ bouncer ให้ตรงกัน จากนั้นรีสตาร์ตทั้ง crowdsec และ bouncer

IP ของตัวเองถูก CrowdSec บล็อก ปลดอย่างไร?

เข้าเครื่องผ่าน Console หรือจาก IP อื่น รัน sudo cscli decisions delete --ip ตามด้วย IP ของคุณ แล้วเพิ่ม IP นั้นใน allowlist ตามขั้นตอนที่ 5 เพื่อไม่ให้เกิดซ้ำ

ติดตั้งแล้วแต่ cscli decisions list ว่างตลอด แปลว่าไม่ทำงานหรือไม่?

ไม่จำเป็น เครื่องที่จำกัด SSH ด้วย Security Group อยู่แล้วอาจไม่มีการโจมตีให้จับ ตรวจ cscli metrics ว่าอ่านล็อกได้ และดู cscli alerts list ถ้ามีล็อกเข้าแต่ไม่เคยมี alert ให้ทดสอบด้วยการล็อกอินผิดหลายครั้งจาก IP ทดสอบที่ไม่อยู่ใน allowlist

CrowdSec ป้องกันเว็บจาก SQL Injection ได้ด้วยหรือไม่?

firewall bouncer บล็อกตาม IP หลังจากตรวจพบพฤติกรรมแล้ว ไม่ได้ตรวจเนื้อหาของแต่ละคำขอ ถ้าต้องการตรวจคำขอแบบ WAF ให้ใช้ bouncer สำหรับ Nginx ร่วมกับ AppSec component ของ CrowdSec และยังต้องอัปเดตเว็บแอปและปลั๊กอินเสมอ

ถ้าต้องการให้ทีมงานช่วยติดตั้ง CrowdSec ปรับ scenario ให้เหมาะกับเว็บของคุณ หรือดูแลการป้องกันหลายเครื่องจากศูนย์กลาง ติดต่อทีมงาน THAI DATA CLOUD ได้ และดูรายละเอียดบริการได้ที่หน้า Managed Security Services

อ่านเพิ่มเติมเกี่ยวกับ CrowdSec

แชร์FacebookXLINELinkedIn

มีคำถามเรื่องบริการ? ติดต่อทีมงาน