ใน CentOS 7 มี FirewallD สำหรับ Config Traffic Filtering Rules เป็น Tool ที่แนะนำให้ใช้จัดการ iptables Rules CentOS 8 ใช้ Framework nftables แทน iptables Packet Filtering Service มาตรฐาน และเวลา Config Firewall Rules ใน firewalld ก็คือกำหนดค่า nftables จริงๆ บทความนี้จะแนะนำวิธีติดตั้งและตั้งค่า firewalld บน Server รัน Linux CentOS 8 (และ CentOS 7) พร้อม Concepts หลักของ Firewall นี้
FirewallD เป็น Firewall Service ใช้ป้องกัน Server จาก Traffic ที่ไม่ต้องการ รองรับ Dynamic Firewall Rule Management (ไม่ต้อง Restart) ทำงานเป็น Interface สำหรับ iptables และ nftables FirewallD ใช้ได้เกือบทุก Linux Distros
Firewalld Basic Concepts: Zones & Rules
ก่อน Install และ Config firewalld จะเรียนรู้ว่า Zones 是อะไร ใช้กำหนด Trust Level ของ Connections ต่างๆ สามารถ Apply Filtering Rules ต่างๆ ให้ firewalld Zones, ตั้ง Active Firewall Options สำหรับ Predefined Services, Protocols หรือ Ports, Port Forwarding และ Rich-rules
Firewalld กรอง Inbound Traffic โดย Zones ขึ้นกับ Rules ที่ Apply ให้ Zone หาก Sender IP Address Match Rules ของ Zone Packet จะส่งผ่าน Zone นั้น หาก IP Address ไม่ Match Zone ใดๆ ที่ Config บน Server Default Zone จะ Process Packet ตอน Install firewalld Default Zone ชื่อ public
Firewalld มี Zones บางตัวที่มี Preconfigured Permissions สำหรับ Services ต่างๆ สามารถใช้ Settings นี้หรือสร้าง Zones เองได้ รายการ Default Zones ที่สร้างตอน Install firewalld (อยู่ใน /usr/lib/firewalld/zones/):
| Zone | คำอธิบาย |
|---|---|
| drop | Trust Level ต่ำสุด บล็อก Inbound Connections ทั้งหมดโดยไม่ตอบสนอง อนุญาตเฉพาะ Outbound |
| block | คล้าย drop แต่ Reject Incoming Requests ด้วย icmp-host-prohibited (IPv4) หรือ icmp6-adm-prohibited (IPv6) |
| public | สำหรับ Public, Untrusted Networks อนุญาต Inbound Connections แบบรายตัว |
| external | External Networks เมื่อ Firewall ใช้เป็น Gateway ใช้สำหรับ Masking NAT เก็บ Internal Network Private แต่เข้าถึงได้ |
| internal | Antonym ของ External Host มี Trust Level พอสมควร เข้าถึง Additional Services ได้มากกว่า |
| dmz | สำหรับ Computers ใน DMZ (Demilitarized Zone) Computers แยกจาก Network อนุญาต Inbound เฉพาะบางอย่าง |
| work | Zone สำหรับ Work Computers (ส่วนใหญ่ Trusted) |
| home | Home Network Trust ส่วนใหญ่ แต่อนุญาต Inbound เฉพาะบางอย่าง |
| trusted | ทุก Computers ใน Network Trusted ตัวเลือกเปิดสุด ต้องใช้อย่างรับผิดชอบ |
Firewalld ใช้ 2 ชุด Rules — Permanent และ Runtime Runtime Rules Active จนกว่า Server Restart โดยค่าเริ่มต้น Rules ที่ Add เข้า firewalld ถือว่า Runtime เพื่อ Add Permanent Rule ต้องใช้ Flag --permanent Rules นี้จะ Apply หลัง Server Restart
วิธีติดตั้ง & Enable FirewallD ใน CentOS
ใน CentOS 7/8 firewalld ติดตั้งโดย Default ระหว่าง OS Installation หากลบ firewalld ไปและต้องการติดตั้งกลับ ใช้ yum/dnf Package Manager มาตรฐาน:
# yum install firewalld -y — on Centos 7
# dnf install firewalld -y — on Centos 8

เพื่อให้ firewalld Daemon Start อัตโนมัติ Add เข้า Startup:
# systemctl enable firewalld
และ Start 它:
# systemctl start firewalld
ตรวจสอบ Service Status:
# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) Docs: man:firewalld(1) Main PID: 13646 (firewalld) CGroup: /system.slice/firewalld.service └─13646 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid systemd[1]: Starting firewalld - dynamic firewall daemon...
หรือตรวจสอบด้วยคำสั่ง:
# firewall-cmd --state
firewall-cmd Command คือ Firewalld Front-end สำหรับ nftables/iptables
# firewall-cmd --state
running
การจัดการ FirewallD Rules
Default FirewallD Rules
ก่อน Config firewalld Rules ควรเช็คว่า Zone ไหนเป็น Default:
# firewall-cmd --get-default-zone

เพิ่ง Install firewalld และยังไม่ Config Default Zone คือ public
Check Active Zone มีแค่ Zone เดียวกัน คือ public:
# firewall-cmd --get-active-zones
public interfaces: eth0
เห็นว่า eth0 Interface ถูก Manage โดย Zone public
แสดงรายการ Network Interfaces ของ CentOS:
# ip link show
or:
# nmcli device status
ดู Rules ของ Active Zones:
# firewall-cmd --list-all
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
ใน Listing นี้เห็นว่า Common Operations เกี่ยวกับ DHCP Client และ SSH ถูกเพิ่มใน Zone
Available Zones
ดูรายการ Zones ทั้งหมด:
# firewall-cmd --get-zones
ได้ List ดังนี้:
block dmz drop external home internal public trusted work
ดู Rules ของ Zone เฉพาะ ใส่ Flag -zone:
# firewall-cmd --zone=home --list-all
home target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client mdns samba-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
ดู Rules ของ All Zones:
# firewall-cmd --list-all-zones
วิธีเปลี่ยน Default Zone
โดย Default Network Interfaces ทั้งหมดอยู่ใน Zone public แต่ย้ายไป Zone ใดๆ ได้ด้วยคำสั่ง:
# firewall-cmd --zone=home --change-interface=eth0
ระบุ Zone ที่ต้องการหลัง Parameter --zone=
เปลี่ยน Default Zone เป็น home:
# firewall-cmd --set-default-zone=home
วิธีเพิ่ม App Rules ใน FirewallD
เพื่อเปิด Port สำหรับ App สามารถ Add Service เป็น Exception ได้ นี่คือวิธีแสดงรายการ Services ที่มี:
# firewall-cmd --get-services

Output จะมี Services เยอะ Detailed Info ของ Service อยู่ใน XML File ไฟล์เหล่านี้อยู่ใน /usr/lib/firewalld/services.
เช่น:
# cd /usr/lib/firewalld/services
# cat smtp.xml
<?xml version="1.0" encoding="utf-8"?> <service> <short>Mail (SMTP)</short> <description>This option allows incoming SMTP mail delivery. If you need to allow remote hosts to connect directly to your machine to deliver mail, enable this option. You do not need to enable this if you collect your mail from your ISP's server by POP3 or IMAP, or if you use a tool such as fetchmail. Note that an improperly configured SMTP server can allow remote machines to use your server to send spam.</description> <port protocol="tcp" port="25"/> </service>
XML File มี Service Description, Protocol และ Port Number ที่จะเปิดใน firewalld

เวลา Add Rules ใช้ Parameter --add-service เพื่อ Allow Firewall Access ไป Service เฉพาะ:
# firewall-cmd --zone=public --add-service=http
# firewall-cmd --zone=public --add-service=https
หลัง Add Rules ตรวจสอบว่า Services เพิ่มใน Zone ที่ระบุแล้ว:
# firewall-cmd --zone=public --list-services
dhcpv6-client http https ssh
หากต้องการทำ Rules Permanent ใช้ Parameter --permanent เวลา Add
ลบ Service จาก Zone:
# firewall-cmd --permanent --zone=public --remove-service=http
# firewall-cmd --zone=public --permanent --list-services
dhcpv6-client https ssh test
หากต้องการ Add Custom Service สร้าง XML File เอง ระบุ Data ได้ Copy จาก Service ใดๆ แล้วแก้ Name, Description และ Port Number
Copy smtp.xml ไป User Services Directory:
# cp /usr/lib/firewalld/services/smtp.xml /etc/firewalld/services
แก้ไข Description ในไฟล์

XML File ต้อง Rename ด้วย (ผมตั้งชื่อ Service test) Restart firewalld และตรวจสอบว่า Service ปรากฏใน List:
# firewall-cmd --get-services
syslog-tls telnet test tftp
ตอนนี้ Add Service ไป Zone ใดๆ ได้:
# firewall-cmd --zone=public --add-service=test --permanent
# firewall-cmd --zone=public --permanent --list-services
dhcpv6-client http https ssh test
หา Service ใน List ไม่เจอ สามารถเปิด Port ที่ต้องการใน firewalld ได้:
# firewall-cmd --zone=public --add-port=77/tcp — เปิด TCP Port 77
# firewall-cmd --zone=public --add-port=77/udp — เปิด UDP Port 77
# firewall-cmd --zone=public --add-port=77-88/udp — เปิด UDP Port Range 77-88
# firewall-cmd --zone=public --list-ports — แสดงรายการ Allowed Ports
Block/Allow ICMP Requests:
# firewall-cmd --zone=public --add-icmp-block=echo-reply
# firewall-cmd --zone=public --remove-icmp-block=echo-reply
ลบ Port ที่เพิ่ม:
# firewall-cmd --zone=public --remove-port=77/udp — ลบ Runtime Rule UDP Port 77
# firewall-cmd --permanent --zone=public --remove-port=77/udp — ลบ Permanent Rule

วิธีสร้าง Zone ใหม่ใน FirewallD
สร้าง Zone เองได้ (ผมจะเรียก our):
# firewall-cmd --permanent --new-zone=our
หลังสร้าง Zone ใหม่ เหมือนสร้าง Service ต้อง Restart firewalld:
# firewall-cmd --reload
# firewall-cmd --get-zones
block dmz drop external home internal our public trusted work
Zone our พร้อมใช้งาน สามารถ Add Services หรือเปิด Ports ได้
Firewalld: วิธี Block IP Addresses & สร้าง Exceptions
สามารถเพิ่ม Trusted IP Addresses เข้า firewalld Exceptions หรือ Block Unwanted IP Addresses
เพิ่ม IP Address (เช่น 8.8.8.8) เข้า Exceptions บน Server ด้วย firewalld:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="8.8.8.8" accept'
Check Zone และตรวจสอบว่า IP Address เพิ่มใน Exceptions ใน rich-rules แล้ว:
# firewall-cmd --zone=public --list-all
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client http https ssh test ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="8.8.8.8" accept
Block IP Address เปลี่ยน accept เป็น reject:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="8.8.4.4" reject'
# firewall-cmd --zone=public --list-all
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client http https ssh test ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="8.8.8.8" accept rule family="ipv4" source address="8.8.4.4" reject
อนุญาต Service รับ Request จาก Specific IP Address เท่านั้น:
#firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="192.168.1.0/24" service name="https" accept'
หากต้องการ Block All Requests ไป Server เร็ว ใช้ Panic Command:
# firewall-cmd --panic-on
ปิด Panic Mode:
# firewall-cmd --panic-off
หรือ Restart Server
Lockdown firewalld Config ไม่ให้ Local Services ด้วย Root Privileges เปลี่ยน Firewall Rules ที่สร้าง:
# firewall-cmd --lockdown-on
ปิด Lockdown Mode:
# firewall-cmd --lockdown-off
การตั้งค่า Port Forwarding ด้วย FirewallD
สร้าง Port Forwarding Rule ใน firewalld ได้ Forward TCP Port 443 ไป 9090:
# firewall-cmd --zone=public --add-forward-port=port=443:proto=tcp:toport=9090 --permanent
ใน Windows Config Port Forwarding ด้วย netsh
ลบ Port Forwarding Rule:
# firewall-cmd --zone=public --remove-forward-port=port=443:proto=tcp:toport=9090