Firewalld บน CentOS/RHEL

Firewalld เป็น Firewall Manager ที่มาพร้อมกับ RHEL, CentOS, Rocky Linux, Fedora และ distributions ตระกูล Red Hat ทั้งหมด แตกต่างจาก iptables และ UFW ตรงที่ Firewalld ใช้แนวคิด Zones เพื่อจัดกลุ่ม Network Interface และกำหนด Trust Level โดยไม่ต้องเขียน Rules ทีละบรรทัด ทำให้เหมาะสำหรับ Server ที่มีหลาย Network Interface หรือต้องการเปลี่ยน Trust Level ตาม Network ที่เชื่อมต่ออยู่

บทความนี้อธิบายการใช้งาน Firewalld ตั้งแต่การจัดการ Zones, การเพิ่มและลบ Services และ Ports, การตั้งค่า Rich Rules สำหรับ Rule ที่ซับซ้อน, การทำ Port Forwarding รวมถึงการตรวจสอบสถานะและ Log

แนวคิด Zones ใน Firewalld

# Firewalld จัดการ Firewall ผ่าน Zones
# แต่ละ Zone กำหนดระดับ Trust และ Rules ที่ใช้กับ Network Interface นั้น

# Zones มาตรฐาน (เรียงจาก Trust น้อยที่สุดไปมากที่สุด):
# drop     — ทิ้ง Packet ทั้งหมด ไม่ตอบกลับ
# block    — ปฏิเสธ Packet พร้อมส่ง ICMP Error กลับ
# public   — Default Zone สำหรับ Public Network — อนุญาตเฉพาะ ssh และ dhcpv6-client
# external — สำหรับ External Network ที่ใช้ NAT Masquerade
# dmz      — สำหรับ DMZ — อนุญาต ssh เท่านั้น
# work     — สำหรับ Work Network — อนุญาต ssh, ipp-client, dhcpv6-client
# home     — สำหรับ Home Network — อนุญาต ssh, mdns, ipp-client, samba-client, dhcpv6-client
# internal — เหมือน home แต่ใช้กับ Internal Network
# trusted  — อนุญาต Connection ทั้งหมด (Trust สูงสุด)

# ดู Zone ทั้งหมด
sudo firewall-cmd --get-zones

# ดู Default Zone
sudo firewall-cmd --get-default-zone

# ดู Active Zones (Zones ที่มี Interface หรือ Source ผูกอยู่)
sudo firewall-cmd --get-active-zones

ติดตั้งและตรวจสอบสถานะ

# ติดตั้ง (มาพร้อมกับ RHEL/Rocky แล้ว แต่ถ้าไม่มี)
sudo dnf install firewalld

# เริ่มและเปิดใช้งาน Firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld

# ตรวจสอบสถานะ
sudo systemctl status firewalld
sudo firewall-cmd --state

# ดู Configuration ทั้งหมดของ Default Zone
sudo firewall-cmd --list-all

# ดู Configuration ของ Zone เฉพาะ
sudo firewall-cmd --zone=public --list-all
sudo firewall-cmd --zone=trusted --list-all

เพิ่ม Services และ Ports

Firewalld มี Predefined Services ที่รู้จัก Port และ Protocol ของ Application ต่าง ๆ ทำให้ไม่ต้องจำ Port Number

# ดู Services ที่มีทั้งหมด
sudo firewall-cmd --get-services

# เพิ่ม Service แบบ Runtime (หายหลัง Reload/Restart)
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
sudo firewall-cmd --add-service=ssh

# เพิ่ม Service แบบถาวร (--permanent)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# เพิ่ม Port โดยตรง
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8000-8100/tcp
sudo firewall-cmd --permanent --add-port=53/udp

# เพิ่มใน Zone เฉพาะ
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=internal --add-service=mysql

# ลบ Service หรือ Port
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --permanent --remove-port=8080/tcp

# โหลดการตั้งค่าถาวรให้มีผล
sudo firewall-cmd --reload

# ตรวจสอบ
sudo firewall-cmd --list-all

จัดการ Zones และ Interfaces

# เปลี่ยน Default Zone
sudo firewall-cmd --set-default-zone=public

# ผูก Network Interface กับ Zone
sudo firewall-cmd --permanent --zone=public --add-interface=eth0
sudo firewall-cmd --permanent --zone=internal --add-interface=eth1

# ผูก Source IP กับ Zone
sudo firewall-cmd --permanent --zone=trusted --add-source=10.0.0.0/8
sudo firewall-cmd --permanent --zone=block --add-source=198.51.100.0/24

# ดู Zone ที่ Interface ผูกอยู่
sudo firewall-cmd --get-zone-of-interface=eth0

# ดู Zone ที่ Source IP ผูกอยู่
sudo firewall-cmd --get-zone-of-source=10.0.0.0/8

# ย้าย Interface ไปยัง Zone อื่น
sudo firewall-cmd --permanent --zone=dmz --change-interface=eth0

sudo firewall-cmd --reload

Rich Rules — Rules ที่ซับซ้อนกว่า Service/Port

Rich Rules ใช้เมื่อต้องการ Rule ที่ละเอียดกว่า Service/Port ปกติ เช่น จำกัดจาก Source IP เฉพาะ หรือเพิ่ม Logging

# อนุญาต SSH จาก IP เฉพาะ
sudo firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4"
  source address="203.0.113.5"
  service name="ssh"
  accept'

# บล็อก IP เฉพาะ
sudo firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4"
  source address="198.51.100.0/24"
  drop'

# Rate Limit SSH (5 connections ต่อนาที)
sudo firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4"
  service name="ssh"
  limit value="5/m"
  accept'

# อนุญาต Port พร้อม Log
sudo firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4"
  port port="3306" protocol="tcp"
  source address="10.0.0.0/8"
  log prefix="MySQL-ACCEPT: " level="info"
  accept'

# ดู Rich Rules ที่มีอยู่
sudo firewall-cmd --list-rich-rules

# ลบ Rich Rule
sudo firewall-cmd --permanent --remove-rich-rule='
  rule family="ipv4"
  source address="198.51.100.0/24"
  drop'

sudo firewall-cmd --reload

Port Forwarding

# Forward Port ภายใน Server เดียวกัน
# Port 80 → Port 8080 บน localhost
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080

# Forward ไปยัง Server อื่น
# Port 80 → 10.0.0.5:80
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=80:toaddr=10.0.0.5

# เปิด IP Masquerade (จำเป็นสำหรับ Forward ข้าม Server)
sudo firewall-cmd --permanent --add-masquerade

# ดู Forward Ports ที่ตั้งค่าไว้
sudo firewall-cmd --list-forward-ports

sudo firewall-cmd --reload

Custom Services

# สร้าง Custom Service Definition
sudo tee /etc/firewalld/services/myapp.xml <<'EOF'
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>MyApp</short>
  <description>My Custom Application on port 8080</description>
  <port protocol="tcp" port="8080"/>
</service>
EOF

# โหลด Services ใหม่
sudo firewall-cmd --reload

# ใช้ Custom Service
sudo firewall-cmd --permanent --add-service=myapp
sudo firewall-cmd --reload

# ดูรายละเอียด Custom Service
sudo firewall-cmd --info-service=myapp

Logging และตรวจสอบ

# เปิด Logging สำหรับ Denied Packets
sudo firewall-cmd --set-log-denied=all     # all, unicast, broadcast, multicast, off
sudo firewall-cmd --set-log-denied=unicast # บันทึกเฉพาะ Unicast (แนะนำ)

# ดูระดับ Log ปัจจุบัน
sudo firewall-cmd --get-log-denied

# ดู Log ใน journald
sudo journalctl -f | grep "FINAL_REJECT\|REJECT\|DROP"
sudo journalctl -k | grep "_KERNEL\|firewall" | tail -20

# Debug Mode — ดู Rules จริงของ iptables ที่ Firewalld สร้าง
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v

# ตรวจสอบว่า Port เปิดหรือไม่
sudo firewall-cmd --query-service=http
sudo firewall-cmd --query-port=8080/tcp

# ดูสถานะทั้งหมดทุก Zone
sudo firewall-cmd --list-all-zones

Runtime vs Permanent

# Firewalld มีสองโหมดการตั้งค่า:
# Runtime   — มีผลทันที แต่หายเมื่อ firewall-cmd --reload หรือ Reboot
# Permanent — บันทึกถาวร แต่ต้อง --reload เพื่อให้มีผล

# เพิ่ม Runtime เท่านั้น (ทดสอบ):
sudo firewall-cmd --add-service=http

# เพิ่ม Permanent (ใช้งานจริง):
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload

# เพิ่มทั้ง Runtime และ Permanent พร้อมกัน:
sudo firewall-cmd --add-service=http
sudo firewall-cmd --permanent --add-service=http

# Sync Runtime → Permanent (บันทึก Runtime ปัจจุบันเป็นถาวร):
sudo firewall-cmd --runtime-to-permanent

# ดู Configuration ของ Runtime
sudo firewall-cmd --list-all

# ดู Configuration ของ Permanent
sudo firewall-cmd --permanent --list-all

ตัวอย่างการตั้งค่า Web Server

#!/bin/bash
# ตั้งค่า Firewalld สำหรับ Web Server บน Rocky Linux

# ตรวจสอบว่า Firewalld ทำงานอยู่
sudo systemctl is-active firewalld || sudo systemctl start firewalld

# ตั้ง Default Zone เป็น public
sudo firewall-cmd --set-default-zone=public

# เพิ่ม Services สำหรับ Web
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# SSH จาก IP เฉพาะเท่านั้น (แทนที่ Default ssh service)
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4"
  source address="203.0.113.5/32"
  service name="ssh"
  accept'

# MySQL เฉพาะจาก Internal Network
sudo firewall-cmd --permanent --zone=public --add-rich-rule='
  rule family="ipv4"
  source address="10.0.0.0/8"
  port port="3306" protocol="tcp"
  accept'

# เปิด Log สำหรับ Denied Packets
sudo firewall-cmd --set-log-denied=unicast

# โหลดการตั้งค่า
sudo firewall-cmd --reload

# ตรวจสอบ
sudo firewall-cmd --list-all

สรุป

Firewalld ใช้แนวคิด Zones เพื่อจัดกลุ่ม Network Interface และกำหนด Trust Level ทำให้ยืดหยุ่นกว่า iptables แบบดั้งเดิมบน Server ที่มีหลาย Interface การเพิ่ม Rules ที่แนะนำคือใช้ --permanent แล้วตามด้วย --reload เพื่อให้มีผลทันทีและคงอยู่หลัง Reboot Rich Rules ใช้สำหรับ Rules ที่ต้องการ Source IP, Logging หรือ Rate Limiting การตรวจสอบสถานะด้วย firewall-cmd --list-all ควรทำทุกครั้งหลังตั้งค่า

แนะนำบริการ DE

Firewalld เป็น Firewall มาตรฐานบน RHEL และ Rocky Linux ซึ่งต้องการสิทธิ์ Root ในการตั้งค่า Cloud VPS ของ DE ให้ Root Access เต็มรูปแบบ รองรับทั้ง Ubuntu (UFW) และ Rocky Linux (Firewalld) สามารถเลือก OS ที่ต้องการตอน Provision และตั้งค่า Firewall ได้อย่างอิสระ

หากต้องการโฮสต์เว็บไซต์โดยมีระบบ Security จัดการอัตโนมัติ Cloud Hosting ของ DE มีระบบป้องกัน DDoS และ Firewall พร้อมใช้งานโดยไม่ต้องตั้งค่า Firewalld เอง