เซิร์ฟเวอร์ถูกตั้งค่าครั้งเดียวแล้วก็อยู่ของมันต่อไปเอง หนึ่งเดือนให้หลัง แพ็กเกจบางส่วนรออัปเกรด ใบรับรองขยับเข้ามาเหลืออีกสามสัปดาห์จะหมดอายุ หลังการติดตั้งอะไรบางอย่างที่ไม่เกี่ยวข้องก็มีบรรทัดเกินโผล่เข้ามาในค่าตั้งของ SSH และ jail ที่ควรเฝ้าการเข้าสู่ระบบก็หยุดไปโดยไม่มีใครรู้ ไม่มีอะไรในนี้ส่งเสียงร้อง ทุกอย่างเพียงแต่เงียบ ๆ เลิกเป็นจริง

ด้านล่างคือสิบสองสิ่งที่ควรตรวจอย่างสม่ำเสมอ พร้อมคำสั่ง การเดินหนึ่งรอบใช้เวลาราวสิบห้านาที ลำดับไล่จากสิ่งที่คนเข้ามาทางนั้นไปหาสิ่งที่พังได้เอง

SSH: ห้าบรรทัด

สิ่งที่ต้องดูไม่ใช่ไฟล์ แต่เป็นค่าตั้งที่มีผลจริง ซึ่งประกอบขึ้นจาก /etc/ssh/sshd_config ทั้งไดเรกทอรี sshd_config.d และค่าปริยายของตัวคอมไพล์

sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|permitemptypasswords|maxauthtries|x11forwarding'

สิ่งที่เราอยากเห็น: permitrootlogin no, passwordauthentication no, permitemptypasswords no, maxauthtries ราว 3–4 และ x11forwarding no สามอย่างแรกคือประตู สองอย่างหลังคือบานพับของมัน ได้แก่เพดานจำนวนครั้งที่พยายามต่อหนึ่งการเชื่อมต่อ และการส่งต่อกราฟิกที่เซิร์ฟเวอร์ไม่ได้ใช้ประโยชน์เลย

ข้อสงวนสองข้อ ทั้งคู่เป็นวิธีง่าย ๆ ที่จะล็อกตัวเองไว้ข้างนอก ข้อแรก: อย่าปิดการเข้าสู่ระบบด้วยรหัสผ่านและการเข้าสู่ระบบด้วย root ก่อนยืนยันว่ากุญแจของคุณใช้งานได้ ในเซสชันแยกต่างหากและไม่ปิดเซสชันปัจจุบัน ถ้าคุณกำลังอ่านสิ่งนี้ขณะเชื่อมต่อในฐานะ root ด้วยรหัสผ่าน สองบรรทัดนั้นจะล็อกคุณเองไว้ข้างนอก

ข้อสอง: ลำดับของไฟล์ OpenSSH ใช้ค่าของพารามิเตอร์ที่พบ เป็นอันแรก และไฟล์ใน sshd_config.d ถูกอ่านตามลำดับอักษร อิมเมจบนคลาวด์มักทิ้ง 50-cloud-init.conf ไว้ที่นั่น และมันจะเอาชนะไฟล์ของคุณถ้าคุณตั้งชื่อไว้ทำนอง 90-hardening.conf ค่าตั้งของคุณควรอยู่ใต้หมายเลขที่น้อยกว่า — 00- หรือ 10- และผลลัพธ์ตรวจด้วย sshd -T ไม่ใช่ด้วยการอ่านไฟล์

ไฟร์วอลล์: หนึ่งการตรวจ

sudo ufw status verbose

ตรงนี้ควรจำไว้ว่าผลลัพธ์แสดง เจตนา ไม่ใช่ผล กฎหนึ่งอาจอยู่ในรายการโดยไม่ได้ปิดอะไรเลย: ตัว UFW เองถูกปิด พอร์ตถูกให้บริการโดยสิ่งที่ Docker เผยแพร่ (มันเขียนกฎของตัวเองลง iptables ใต้ UFW) หรือทราฟฟิกเข้าถึงเซิร์ฟเวอร์ทางอื่น จึงคุ้มที่จะเทียบรายการกฎกับสิ่งที่ฟังออกไปข้างนอกจริง ๆ:

sudo ss -tulpn | grep -v '127.0.0.1\|::1'

fail2ban: สองการตรวจ

แค่บริการทำงานอยู่ยังไม่พอ ต้องมี jail ที่ใช้การได้สำหรับ SSH ด้วย

sudo fail2ban-client status
sudo fail2ban-client status sshd

ปัญหาที่พบบ่อยที่สุดตรงนี้คือ jail ที่เงียบ บน Debian 12 และ Ubuntu รุ่นใหม่ ๆ อาจไม่มี /var/log/auth.log เลย เพราะไม่ได้ติดตั้ง rsyslog และบันทึกอยู่แค่ใน journald เท่านั้น jail ที่ใช้ logpath มาตรฐานจะเริ่มทำงาน รายงานตัวว่าทำงานอยู่ และไม่เคยแบนใครเลย แก้ได้ด้วยการชี้ไปที่เจอร์นัลของ systemd:

printf '[sshd]\nenabled = true\nbackend = systemd\n' | sudo tee /etc/fail2ban/jail.d/sshd-systemd.local
sudo systemctl restart fail2ban

สัญญาณที่จับได้โดยไม่ต้องรื้อค่าตั้ง: ใน fail2ban-client status sshd บรรทัด «Currently failed» และ «Total failed» ค้างอยู่ที่ศูนย์ ทั้งที่ในเจอร์นัลมีการเข้าสู่ระบบที่ล้มเหลวอยู่ชัดเจน

การอัปเดต: สามการตรวจ

แยกกัน: มีแพ็กเกจรออยู่ทั้งหมดกี่ตัว ในจำนวนนั้นเป็นเรื่องความปลอดภัยกี่ตัว และระบบขอให้รีสตาร์ตหลังอัปเดตเคอร์เนลหรือไม่

sudo apt update
apt list --upgradable 2>/dev/null | grep -c -- '-security'
ls /var/run/reboot-required 2>/dev/null && echo 'ต้องรีสตาร์ต'

การตรวจข้อที่สามคือการอัปเดตความปลอดภัยอัตโนมัติเปิดอยู่หรือไม่ เพื่อไม่ให้สองข้อแรกกลายเป็นพิธีกรรมประจำเดือน:

systemctl status unattended-upgrades --no-pager
cat /etc/apt/apt.conf.d/20auto-upgrades

ในไฟล์นั้นควรมีเลข 1 อยู่ทั้งสองบรรทัด ถ้าไม่มีแพ็กเกจ: sudo apt install unattended-upgrades && sudo dpkg-reconfigure -plow unattended-upgrades

ใบรับรอง: หนึ่งการตรวจ

ใบรับรองของ Let's Encrypt มีอายุเก้าสิบวัน และการต่ออายุมักทำงานเองไปจนถึงวันที่มันหยุดทำงานพอดี สิ่งที่ต้องดูไม่ใช่แผงของผู้รับจดทะเบียน แต่เป็นสิ่งที่เซิร์ฟเวอร์ให้บริการจริง:

echo | openssl s_client -connect localhost:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
sudo certbot renew --dry-run

คำสั่งแรกให้วันหมดอายุของใบรับรองที่ให้บริการสำหรับชื่อนั้น คำสั่งที่สองยืนยันว่าการต่ออายุจะผ่าน โดยไม่ต้องรอกำหนดจริง คุ้มที่จะไล่ดูทุกชื่อที่เซิร์ฟเวอร์ให้บริการ ไม่ใช่แค่โดเมนหลัก เพราะที่มักลืมคือซับโดเมนที่เพิ่มเข้ามาทีหลัง

ดิสก์: หนึ่งการตรวจ

df -h
df -i

สองคำสั่ง เพราะพื้นที่กับระเบียนของไฟล์หมดแยกจากกัน บนเซิร์ฟเวอร์ส่วนใหญ่อย่างหลังชนเพดานก่อน ไฟล์เล็ก ๆ นับล้านในเซสชัน PHP หรือในแคชของแอปพลิเคชันทำให้ IUse% ขึ้นไปถึง 100 ทั้งที่ยังเหลือพื้นที่เป็นกิกะไบต์ ทั้งสองกรณีเรามีบทความแยกต่างหาก

รายการนี้มีปัญหาอะไร

รายการนี้ถูกต้อง แต่มันมีคุณสมบัติหนึ่ง คือต้องมีใครสักคนจำมันได้ สิบห้านาทีต่อสัปดาห์ไม่มาก ตราบใดที่เซิร์ฟเวอร์มีเครื่องเดียวและตราบใดที่ยังมีเหตุให้ทำ พอผ่านไปสองเดือนที่สงบ การเดินตรวจก็ถูกข้าม และข่าวว่า jail หยุดทำงานก็มาถึงจากล็อกของคนอื่น

เราจึงรวบสิบสองการตรวจนี้ไว้ในแผงฟรีแยกต่างหาก — Arcivéo FREE ติดตั้งด้วยคำสั่งเดียว ทำงานบนเซิร์ฟเวอร์ของคุณเอง ไม่ส่งอะไรมาให้เรา และไม่ต้องลงทะเบียน ตัวเก็บข้อมูลทำงานจาก cron ทุกห้านาทีและเขียนสิ่งเดียวกันลงฐานข้อมูลในเครื่อง: การเข้าสู่ระบบ SSH และการเชื่อมต่อที่ถูกปฏิเสธ สถานะของ UFW และ fail2ban การอัปเดตความปลอดภัยที่รออยู่ กำหนดของใบรับรอง และพื้นที่ดิสก์ ประวัติย้อนหลังเจ็ดวัน อินเทอร์เฟซมี 34 ภาษา ราคาเป็นศูนย์ รวมถึงบนเซิร์ฟเวอร์ที่ใช้ทำงาน สัญญาอนุญาตให้ติดตั้งแผงนี้บนเครื่องของคุณเอง รวมถึงเครื่องของบริษัท และไม่อนุญาตให้ขายต่อหรือเปิดเป็นบริการสำหรับเซิร์ฟเวอร์ของคนอื่น

สแตกของรุ่นฟรีนั้นเรียบง่าย: มันติดตั้งและเปิดใช้ UFW กับ fail2ban แล้วจากนั้นก็แสดงสถานะ ModSecurity, Suricata, AIDE และโมดูลอื่น ๆ ไม่ได้อยู่ในนั้น พวกนั้นเป็นของรุ่นเสียเงิน แต่สำหรับการเลิกแบกรอบตรวจรายสัปดาห์ไว้ในหัว เท่านี้ก็พอ ข้อมูลเดียวกันบนแผงเต็มหน้าตาเป็นอย่างไร — ดูได้จากหน้าเดโมด้านล่าง