ใช้ nftables จัดการ Firewall บน Linux VPS
nftables คือ Linux firewall framework รุ่นใหม่ที่มาแทนที่ iptables, ip6tables, arptables และ ebtables ทั้งหมดในตัวเดียว ตั้งแต่ kernel 3.13 เป็นต้นมา nftables ถูกรวมอยู่ใน kernel แล้ว และดิสทริบิวชันอย่าง Debian 11+, Ubuntu 20.10+, RHEL 8+ ก็ย้ายมาใช้ nftables เป็น default firewall backend เรียบร้อย syntax ที่อ่านง่ายกว่า ประสิทธิภาพที่ดีกว่า และความสามารถ atomic ruleset update คือเหตุผลหลักที่ควรรู้จักและใช้งาน nftables บน VPS ของคุณ
ทำไมต้องเปลี่ยนมาใช้ nftables
ก่อนตัดสินใจ ลองเปรียบเทียบ nftables กับ iptables:
| คุณสมบัติ | iptables | nftables |
|---|---|---|
| IPv4/IPv6 | ต้องใช้คำสั่งแยก (iptables / ip6tables) | จัดการในคำสั่งเดียว |
| Syntax | ซับซ้อน ตัวเลือกเยอะ | อ่านง่าย กระชับกว่า |
| Atomic update | ไม่รองรับ (flush แล้ว load ใหม่ทีละ rule) | รองรับ (load ทั้ง ruleset พร้อมกัน) |
| Sets/Maps | ต้องใช้ ipset แยก | built-in, รองรับหลาย type |
| Performance | linear match | hash/map lookup เร็วกว่าสำหรับ rule เยอะ |
ติดตั้ง nftables
บน Debian/Ubuntu nftables มักติดตั้งมาพร้อมกับระบบแล้ว แต่ถ้ายังไม่มีให้ติดตั้ง:
# Debian / Ubuntu
sudo apt update && sudo apt install -y nftables
# RHEL / CentOS / AlmaLinux / Rocky Linux
sudo dnf install -y nftables
# เปิดใช้งาน nftables service
sudo systemctl enable --now nftables
# ตรวจสอบเวอร์ชัน
nft --version
แนวคิดพื้นฐานของ nftables
nftables จัดระเบียบ rules ในลำดับชั้น ดังนี้:
- Table — container หลัก กำหนด address family เช่น
inet(IPv4+IPv6),ip,ip6 - Chain — กลุ่ม rules ภายใน table กำหนด hook (input/output/forward) และ policy
- Rule — เงื่อนไข match + action (accept/drop/reject/log)
- Set — กลุ่ม IP/port ที่ใช้ใน rule ซ้ำๆ เช่น allowed IPs, blocked ports
สร้าง Ruleset พื้นฐานสำหรับ VPS
เปิด file configuration หลัก:
sudo nano /etc/nftables.conf
แทนที่เนื้อหาทั้งหมดด้วย ruleset ต่อไปนี้:
#!/usr/sbin/nft -f
# ล้าง ruleset เดิมทั้งหมด
flush ruleset
# สร้าง table inet สำหรับ IPv4 + IPv6
table inet filter {
# Set สำหรับ IP ที่บล็อก (เพิ่มได้ในภายหลัง)
set blocklist {
type ipv4_addr
flags dynamic, timeout
timeout 1h
}
chain input {
type filter hook input priority 0; policy drop;
# อนุญาต loopback interface
iif lo accept
# อนุญาต established/related connections
ct state established,related accept
# drop invalid packets
ct state invalid drop
# อนุญาต ICMP (ping)
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# อนุญาต SSH (port 22)
tcp dport 22 accept
# อนุญาต HTTP และ HTTPS
tcp dport { 80, 443 } accept
# drop IP ที่อยู่ใน blocklist
ip saddr @blocklist drop
# log และ drop ที่เหลือ
log prefix "[nftables-drop] " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
# โหลด configuration
sudo nft -f /etc/nftables.conf
# ดู ruleset ที่โหลดแล้ว
sudo nft list ruleset
เพิ่ม/ลบ Rule แบบ Runtime
คุณสามารถแก้ไข rule ขณะระบบทำงานโดยไม่ต้องแก้ไฟล์ config ก่อน:
# เพิ่ม rule อนุญาต port 8080
sudo nft add rule inet filter input tcp dport 8080 accept
# เพิ่ม rule บล็อก IP เฉพาะ
sudo nft add rule inet filter input ip saddr 1.2.3.4 drop
# เพิ่ม IP เข้า blocklist set
sudo nft add element inet filter blocklist { 203.0.113.10 }
# ดู chains ทั้งหมด
sudo nft list chains
# ดู rule ใน input chain พร้อมหมายเลข handle
sudo nft list chain inet filter input
# ลบ rule ด้วย handle number (เช่น handle 8)
sudo nft delete rule inet filter input handle 8
/etc/nftables.conf ด้วยคำสั่ง sudo nft list ruleset > /etc/nftables.conf เพื่อให้มีผลหลัง rebootRate Limiting เพื่อป้องกัน Brute Force SSH
# เพิ่มใน chain input ก่อน rule "tcp dport 22 accept"
# จำกัดการเชื่อมต่อ SSH ไม่เกิน 3 ครั้งต่อนาที ต่อ IP
tcp dport 22 ct state new limit rate 3/minute accept
tcp dport 22 ct state new drop
หรือสร้าง chain แยกสำหรับ rate limiting:
chain ssh_guard {
ct state new limit rate over 5/minute drop
accept
}
# ใน input chain
tcp dport 22 jump ssh_guard
บันทึกและ Backup Configuration
# บันทึก ruleset ปัจจุบันลงไฟล์
sudo nft list ruleset | sudo tee /etc/nftables.conf
# สำรอง config ก่อนแก้ไข
sudo cp /etc/nftables.conf /etc/nftables.conf.bak.$(date +%Y%m%d)
# Reload config จากไฟล์ (atomic — ไม่มี downtime)
sudo nft -f /etc/nftables.conf
# ตรวจสอบ syntax โดยไม่ apply
sudo nft -c -f /etc/nftables.conf
ตรวจสอบว่า nftables ทำงานถูกต้อง
# ตรวจสอบ service status
sudo systemctl status nftables
# ดู ruleset ทั้งหมดที่ active
sudo nft list ruleset
# ดูสถิติ packet/byte counter ต่อ rule
sudo nft list ruleset -a
# ตรวจสอบว่า rule บล็อก port ที่กำหนดจริง
sudo nft list chain inet filter input
# ทดสอบ connection จากภายนอก
nc -zv YOUR_VPS_IP 22 # ควร open
nc -zv YOUR_VPS_IP 8888 # ควร refuse/timeout (ไม่ได้ allow)
sudo nft monitor เพื่อดู rule changes แบบ real-time ขณะที่มีการแก้ไข — มีประโยชน์มากตอน debug session เพราะเห็นทุก event ที่เกิดขึ้นแก้ปัญหาที่พบบ่อย
Error: "Error: Could not process rule: Table already exists"
เกิดขึ้นเมื่อ load config ซ้ำโดยไม่มี flush ruleset ตอนต้นไฟล์ หรือ table ชื่อเดียวกันถูกสร้างซ้ำ
# วิธีแก้ 1: ใส่ flush ruleset บรรทัดแรกของ config
flush ruleset
# วิธีแก้ 2: flush manual ก่อน load
sudo nft flush ruleset
sudo nft -f /etc/nftables.conf
Error: "Error: syntax error, unexpected identifier" ใน config file
เกิดจาก syntax ผิดพลาด เช่น ลืม semicolon, วงเล็บไม่ครบ หรือ keyword ผิด
# ตรวจสอบ syntax โดยไม่ apply จริง
sudo nft -c -f /etc/nftables.conf
# ดู error message ที่บอก line number และ position
# แก้ไข config แล้วลองใหม่
SSH หลุดทันทีหลัง apply rules ใหม่
เกิดเมื่อ policy drop และไม่มี rule allow SSH ก่อน apply หรือ rule allow SSH อยู่หลัง drop rule อื่น
# ทดสอบ syntax ก่อนเสมอ
sudo nft -c -f /tmp/new-rules.conf
# ใช้ at(1) เพื่อ rollback อัตโนมัติถ้าขาด session
# (run ก่อน apply)
echo "nft flush ruleset && nft -f /etc/nftables.conf.bak" | at now + 5 minutes
sudo nft -f /tmp/new-rules.conf
Error: "Operation not permitted" เมื่อรัน nft โดยไม่มี sudo
nftables ต้องการสิทธิ์ root ในการแก้ไข kernel firewall tables
# รันด้วย sudo เสมอ
sudo nft list ruleset
sudo nft add rule ...
# หรือ switch เป็น root ชั่วคราว
sudo -i
nft list ruleset
Rules หายหลัง reboot
เกิดเมื่อ nftables service ไม่ได้ enable หรือ config ไม่ได้บันทึกลงไฟล์ที่ถูกต้อง
# ตรวจสอบว่า service enabled
sudo systemctl is-enabled nftables
# เปิดใช้งานถ้าไม่ได้ enabled
sudo systemctl enable nftables
# บันทึก ruleset ปัจจุบันลงไฟล์ config หลัก
sudo nft list ruleset | sudo tee /etc/nftables.conf
# ทดสอบ restart service
sudo systemctl restart nftables
sudo nft list ruleset
คำถามที่พบบ่อย
nftables กับ iptables ใช้พร้อมกันได้ไหม?
ไม่ควรใช้พร้อมกัน เพราะทั้งสองใช้ Linux Netfilter framework เหมือนกัน rules จากทั้งสองอาจ conflict หรือซ้ำซ้อน ควรเลือกใช้อย่างใดอย่างหนึ่ง ถ้าจะ migrate จาก iptables ให้ใช้เครื่องมือ iptables-restore-translate แปลง rules เดิมเป็น nftables syntax ก่อนแล้ว disable iptables ทั้งหมด
UFW ใช้ nftables เป็น backend ได้ไหม?
ในดิสทริบิวชันใหม่ๆ UFW สามารถใช้ nftables เป็น backend ได้ แต่ถ้าเลือกใช้ nftables โดยตรงจะได้ flexibility มากกว่า เช่น การสร้าง sets, maps, และ stateful rules ที่ซับซ้อน UFW เหมาะกับ use case ง่ายๆ ส่วน nftables โดยตรงเหมาะกับผู้ที่ต้องการควบคุมทุกอย่างด้วยตัวเอง
วิธีดูว่า packet ถูก drop หรือ accept ด้วย rule ไหน?
ใช้ log statement ใน nftables เพื่อบันทึก packet ก่อน drop หรือ accept จากนั้นดู log ใน journalctl หรือ /var/log/syslog
# เพิ่ม log ก่อน drop
log prefix "[nft-drop] " flags all drop
# ดู log
sudo journalctl -k | grep nft-drop
sudo dmesg | grep nft-drop