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

การเริ่มต้นที่ไม่ทำให้คุณติดอยู่ข้างนอก

ลำดับของคำสั่งสำคัญ อนุญาต SSH ก่อน แล้วค่อยเปิดใช้งาน:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw enable

ufw enable ก่อนอนุญาต SSH จะตัดเซสชันของคุณเอง และหลังจากนั้นก็เหลือแค่คอนโซลของผู้ให้บริการ ถ้าเซิร์ฟเวอร์ตั้งค่าไว้แล้วและคุณไม่แน่ใจ ให้เปิดการเชื่อมต่อที่สองทิ้งไว้ — มันรอดพ้นการแก้ไขที่ผิดพลาด

ดูสถานะแบบละเอียด แบบสั้นซ่อนนโยบายเริ่มต้นไว้:

sudo ufw status verbose

ความผิดพลาดที่หนึ่ง: มีกฎอยู่และพอร์ตเปิดให้ทั้งโลก

บรรทัดที่พบบ่อยที่สุดในไฟล์ตั้งค่าของคนอื่น:

sudo ufw allow 3306

นั่นคือวิธีที่ MySQL ถูกเปิด «เพื่อให้เชื่อมต่อจากบ้านได้» — และเปิดให้ทั้งอินเทอร์เน็ต มีสองรูปแบบที่ถูกต้อง และทั้งคู่ดีกว่า:

sudo ufw allow from 203.0.113.25 to any port 3306

หรือที่น่าเชื่อถือกว่าคืออย่าปล่อยให้บริการออกไปข้างนอกเลย: bind-address = 127.0.0.1 ในไฟล์ตั้งค่าของ MySQL และเข้าถึงจากภายนอกผ่านอุโมงค์ SSH ไฟร์วอลล์คือแนวที่สอง แนวแรกคือการที่บริการไม่รับฟังบนที่อยู่สาธารณะ กฎใน UFW อาจถูกลบโดยบังเอิญ ในขณะที่ bind-address ไม่เปลี่ยนเอง

ความผิดพลาดที่สอง: IPv6

กฎอย่าง ufw allow from 203.0.113.25 ใช้กับ IPv4 เท่านั้น ถ้าเซิร์ฟเวอร์มีที่อยู่ IPv6 — และ VPS ส่วนใหญ่มีและเปิดใช้งานอยู่ — บริการก็ยังเข้าถึงได้ผ่านมัน ผู้ให้บริการแจกที่อยู่มา คุณจำมันไม่ได้ แต่ตัวสแกนจำได้

ตรวจว่าการกรอง v6 เปิดอยู่หรือไม่ (IPV6=yes ใน /etc/default/ufw) และบริการไม่ได้รับฟังบน :: โดยไม่จำเป็น:

ss -tulpn | grep ':::'

กฎที่ระบุที่อยู่อย่างชัดเจนต้องเขียนแยกกันสำหรับโปรโตคอลแต่ละเวอร์ชัน

ความผิดพลาดที่สาม: Docker

ข้อที่น่าหงุดหงิดที่สุด Docker เผยแพร่พอร์ตโดยเพิ่มกฎของตัวเองลงในเชน iptables ก่อนกฎที่ UFW เขียน ผลคือคอนเทนเนอร์ที่รันด้วย -p 5432:5432 เข้าถึงได้จากอินเทอร์เน็ตแม้ UFW จะรายงาน Status: active และนโยบาย deny incoming ไฟร์วอลล์ไม่ได้พัง — เพียงแต่ไม่เคยถึงตาของมัน

การรักษาไม่ได้อยู่ที่ UFW แต่อยู่ที่วิธีเผยแพร่พอร์ต:

ports:
  - "127.0.0.1:5432:5432"

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

ลำดับของกฎ

UFW ใช้กฎแรกที่ตรงกันแล้วหยุดตรงนั้น ดังนั้นการปฏิเสธที่เพิ่มหลังการอนุญาตจะไม่ทำงาน: มันไม่เคยถึงตา ดูหมายเลขแล้วแทรกตรงที่ต้องการ:

sudo ufw status numbered
sudo ufw insert 1 deny from 198.51.100.0/24
sudo ufw delete 7

กฎถูกลบตามหมายเลข แต่หมายเลขจะเลื่อนหลังการลบทุกครั้ง — ลบทีละข้อแล้วอ่านรายการใหม่

การตรวจจากภายนอก

คำสั่งท้องถิ่นแสดงสิ่งที่ตั้งค่าไว้ ผลลัพธ์จริงเห็นได้จากเครื่องอื่นเท่านั้น:

nmap -Pn -p- 203.0.113.25
nc -zv 203.0.113.25 3306

เซิร์ฟเวอร์เครื่องอื่นหรือคอมพิวเตอร์ที่บ้านของคุณก็ใช้ได้ นี่คือการตรวจเดียวที่ไม่โกหก และควรรันหลังการปรับแต่งครั้งสำคัญทุกครั้ง — โดยเฉพาะหลังติดตั้งสิ่งที่ «ตั้งค่าเครือข่ายเอง»: Docker แผงควบคุม VPN

ล็อก

โดยค่าเริ่มต้น UFW แทบไม่เขียนอะไรเลย เปิดใช้งานด้วย:

sudo ufw logging low

รายการจะไปที่ /var/log/ufw.log — แต่เฉพาะเมื่อมี rsyslog อยู่ในระบบ บน Debian 12 และ Ubuntu 24.04 อาจไม่มี และทุกอย่างจะไปที่เจอร์นัลของ systemd แทน:

sudo journalctl -k | grep -i '\[UFW'

/var/log/ufw.log ที่ว่างเปล่าไม่ได้บอกอะไรในตัวมันเอง — ให้ดูที่เจอร์นัลก่อน

ควรคาดหวังอะไรจากไฟร์วอลล์

UFW ปิดสิ่งที่ไม่ควรเข้าถึงได้ มันไม่ตรวจเนื้อหาของคำขอที่มาถึงสิ่งที่เปิดอยู่: พอร์ต 443 เปิดให้ทุกคน และอะไรก็ตามที่มาถึงเว็บไซต์ก็มาถึงโดยไม่มีอะไรขวาง นั่นเป็นงานของเครื่องมืออื่น — WAF ที่ระดับแอปพลิเคชัน IDS ที่ระดับทราฟฟิก งานของไฟร์วอลล์นั้นถ่อมตัวกว่าและสำคัญกว่า: ให้รายการพอร์ตที่เปิดตรงกับสิ่งที่คุณเชื่อเกี่ยวกับมัน รายการนั้นพร้อมกฎที่ใช้งานอยู่บนหน้าเดียวเป็นอย่างไร — ดูได้ที่เดโมด้านล่าง