firewalld là phần mềm quản lý tường lửa có sẵn cho nhiều bản phân phối Linux, hoạt động như một lớp giao diện cho hệ thống lọc gói tin nftables hoặc iptables trong nhân Linux.
Trong hướng dẫn này, bạn sẽ tìm hiểu cách thiết lập tường lửa firewalld cho máy chủ Rocky Linux 8 của mình, và nắm bắt những nguyên tắc cơ bản về quản lý tường lửa với công cụ quản trị firewall-cmd.
Yêu Cầu
Để hoàn thành hướng dẫn này, bạn cần một máy chủ chạy Rocky Linux 8. Bạn nên đăng nhập vào máy chủ dưới tài khoản người dùng thường (non-root) có quyền sudo. Để thiết lập, tham khảo hướng dẫn: Tìm hiểu cách cài đặt máy chủ ban đầu với Rocky Linux 8
Bước 1 — Xem Lại Các Khái Niệm Cốt Lõi Trong firewalld
Trước khi xem cách sử dụng tiện ích firewall-cmd để quản lý cấu hình tường lửa, bạn nên làm quen với một vài khái niệm mà công cụ này giới thiệu.
Zones
Trình nền (daemon) của firewalld quản lý tập hợp các quy tắc thông qua các thực thể gọi là zone. Zone là các nhóm quy tắc xác định lưu lượng nào được phép dựa trên mức độ tin cậy của bạn với mạng. Các giao diện mạng (network interface) được gán cho một zone để chỉ định cách tường lửa xử lý lưu lượng.
Đối với máy tính có thể thường xuyên di chuyển giữa các mạng (như laptop), kiểu linh hoạt này mang đến phương pháp hiệu quả để thay đổi quy tắc tùy thuộc vào môi trường mạng. Bạn có thể có quy tắc nghiêm ngặt chặn hầu hết lưu lượng khi ở mạng WiFi công cộng, nhưng lại cho phép nhiều lưu lượng hơn khi kết nối với mạng gia đình.
Với máy chủ, zone thường không quan trọng bằng, vì môi trường mạng hiếm khi (hoặc không bao giờ) thay đổi.
Dù môi trường mạng của bạn có thay đổi hay không, việc hiểu ý tưởng chung đằng sau mỗi zone được định nghĩa sẵn trong firewalld vẫn hữu ích. Các zone mặc định của firewalld, theo thứ tự từ ít tin cậy nhất đến đáng tin cậy nhất:
- drop: Mức độ tin cậy thấp nhất. Tất cả kết nối đến bị loại bỏ mà không gửi phản hồi, chỉ có kết nối đi mới khả dụng.
- block: Tương tự như trên, nhưng thay vì loại bỏ kết nối, các yêu cầu đến sẽ bị từ chối với thông báo
icmp-host-prohibitedhoặcicmp6-adm-prohibited. - public: Đại diện cho mạng công cộng, không tin cậy. Bạn không tin tưởng các máy tính khác nhưng có thể cho phép một số kết nối đến dựa trên từng trường hợp cụ thể.
- external: Mạng bên ngoài, dành cho trường hợp bạn dùng tường lửa như cổng (gateway). Nó được cấu hình để NAT masquerading, giữ mạng nội bộ của bạn riêng tư nhưng vẫn truy cập được.
- internal: Là phía còn lại của external, dùng cho mạng nội bộ của gateway. Các máy tính trong mạng nội bộ được tin cậy khá nhiều, và có thể mở thêm dịch vụ.
- dmz: Dành cho máy tính đặt trong DMZ (các máy tính bị cô lập, không có quyền truy cập phần còn lại của mạng). Chỉ một số kết nối đến nhất định được cho phép.
- work: Dùng cho máy làm việc. Tin tưởng hầu hết máy tính trong mạng. Có thể cho phép thêm vài dịch vụ.
- home: Môi trường gia đình. Thường giả định bạn tin tưởng phần lớn máy tính khác, và do đó chấp nhận thêm một số dịch vụ.
- trusted: Tin tưởng tất cả máy trong mạng. Mức độ mở nhất trong các tùy chọn, nên dùng cẩn thận.
Để sử dụng tường lửa, bạn có thể tạo quy tắc và điều chỉnh thuộc tính của zone, sau đó gán các giao diện mạng cho zone thích hợp.
Rule Permanence
Trong firewalld, quy tắc có thể áp dụng cho bộ quy tắc đang chạy (runtime) hoặc được thiết lập vĩnh viễn (permanent). Khi thêm hoặc sửa quy tắc, mặc định chỉ tường lửa đang chạy được cập nhật. Sau lần khởi động lại hoặc reload dịch vụ firewalld, chỉ các quy tắc permanent mới được giữ lại.
Hầu hết các thao tác với firewall-cmd đều có thể kèm cờ –permanent để chỉ ra rằng thay đổi nên áp dụng cho cấu hình permanent. Ngoài ra, tường lửa đang chạy có thể được lưu vào cấu hình permanent bằng lệnh: firewall-cmd --runtime-to-permanent
Việc tách biệt cấu hình runtime và permanent có nghĩa bạn có thể an toàn thử nghiệm quy tắc trên tường lửa đang hoạt động, rồi reload để quay lại nếu có sự cố.
Bước 2 — Cài Đặt và Kích Hoạt firewalld
firewalld được cài mặc định trên một số bản phân phối Linux, bao gồm nhiều triển khai Rocky Linux. Tuy nhiên, có thể bạn cần tự cài firewalld. Dùng dnf của Rocky để cài:
sudo dnf install firewalld -y
Sau khi cài xong, bạn cần kích hoạt dịch vụ bằng systemctl. Lưu ý rằng việc kích hoạt firewalld sẽ khiến dịch vụ khởi động cùng hệ thống. Tốt nhất là bạn nên tạo quy tắc tường lửa và thử nghiệm trong khi vẫn đăng nhập SSH, để tránh rủi ro mất kết nối.
sudo systemctl enable firewalld sudo systemctl start firewalld
Điều này cho biết tường lửa đã khởi động và chạy với cấu hình mặc định. Trước khi tùy chỉnh thêm, bạn nên làm quen với môi trường mặc định và các quy tắc sẵn có của firewalld.
Khám Phá Mặc Định (Exploring the Defaults)
Bạn có thể xem zone nào hiện được chọn làm mặc định bằng cách: firewall-cmd --get-default-zone
firewall-cmd --get-default-zone
Output
Vì bạn chưa đưa cho firewalld bất kỳ lệnh nào để thay đổi khỏi vùng mặc định, và không có giao diện (interface) nào được cấu hình để liên kết với vùng khác, nên vùng này cũng sẽ là vùng duy nhất đang hoạt động (vùng đang kiểm soát lưu lượng cho các giao diện của chúng ta). Bạn có thể xác minh điều đó bằng cách chạy lệnh: firewall-cmd --get-active-zones
firewall-cmd --get-active-zones
Output
Dưới đây, bạn có thể thấy máy chủ ví dụ của bạn có hai giao diện mạng (eth0 và eth1) đang được tường lửa kiểm soát. Cả hai giao diện này hiện được quản lý dựa trên các quy tắc được định nghĩa cho vùng public.
Bạn có thể in ra các quy tắc gắn liền với cấu hình vùng mặc định bằng cách sử dụng: firewall-cmd --list-all
sudo firewall-cmd --list-all
Output
Từ output này, bạn thấy zone này vừa là zone mặc định, vừa là zone đang hoạt động, và rằng hai giao diện eth0 và eth1 được gán cho zone này. Từ dòng services:, bạn thấy zone này cho phép lưu lượng cho dịch vụ DHCP client (cấp địa chỉ IP), SSH (quản trị từ xa) và Cockpit (bảng điều khiển web).
Khám Phá Các Zone Khác (Exploring Alternative Zones)
Bạn cũng có thể tìm hiểu thông tin về các zone khác.
Để liệt kê danh sách zone khả dụng, chạy:
firewall-cmd --get-zones
Output
Bạn có thể xem cấu hình chi tiết gắn với một zone bằng cách thêm tham số --zone= vào lệnh --list-all. Ví dụ:
sudo firewall-cmd --zone=home --list-all
Output
Bạn có thể xuất toàn bộ định nghĩa zone bằng tùy chọn --list-all-zones. Tiếp theo, bạn sẽ học cách gán zone cho giao diện mạng.
Bước 3 — Chọn Zone Cho Giao Diện (Selecting Zones for your Interfaces)
Trừ khi bạn cấu hình khác, mỗi giao diện mạng sẽ thuộc zone mặc định khi tường lửa khởi động.
Thay Đổi Zone Của Một Giao Diện (Changing the Zone of an Interface)
Bạn có thể di chuyển một giao diện sang zone khác trong một phiên làm việc bằng cách dùng tham số --zone= cùng với --change-interface=. Như mọi lệnh thay đổi tường lửa, bạn cần dùng sudo.
Ví dụ, bạn có thể chuyển giao diện eth0 sang zone home:
sudo firewall-cmd --zone=home --change-interface=eth0
Output
Lưu ý: Mỗi khi di chuyển giao diện sang zone mới, bạn đang thay đổi các dịch vụ sẽ hoạt động. Trong ví dụ này, bạn di chuyển sang zone
home(zone này cho phép SSH), nên kết nối của bạn không bị cắt. Một số zone khác không bật SSH mặc định, chuyển sang những zone đó có thể khiến bạn bị mất kết nối và không đăng nhập lại được máy chủ.
Bạn có thể xác nhận thành công bằng cách kiểm tra zone đang hoạt động:
firewall-cmd --get-active-zones
Output
Điều Chỉnh Zone Mặc Định (Adjusting the Default Zone)
Nếu tất cả giao diện của bạn có thể được quản lý tốt bởi một zone đã có, bạn nên đặt zone đó làm mặc định. Bạn có thể thay đổi zone mặc định với tham số --set-default-zone=. Lệnh này ngay lập tức thay đổi bất kỳ giao diện nào đang dùng zone mặc định:
sudo firewall-cmd --set-default-zone=home
Output
Bước 4 — Thiết Lập Quy Tắc Cho Ứng Dụng (Setting Rules for your Applications)
Hãy xem qua các cách định nghĩa ngoại lệ tường lửa.
Thêm Một Dịch Vụ Vào Zone (Adding a Service to your Zones)
Cách trực quan nhất là thêm dịch vụ hoặc cổng bạn cần vào zone bạn đang sử dụng. Bạn có thể lấy danh sách dịch vụ khả dụng bằng tham số --get-services:
Output
RH-Satellite-6 amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git grafana gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tftp-client tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
Lưu ý: Bạn có thể tìm thêm chi tiết về mỗi dịch vụ trong file .xml tương ứng bên trong thư mục /usr/lib/firewalld/services. Ví dụ, dịch vụ SSH được định nghĩa như sau:
<?xml version="1.0" encoding="utf-8"?> <service> <short>SSH</short> <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description> <port protocol="tcp" port="22"/> </service>
Bạn có thể bật một dịch vụ cho một zone bằng tham số --add-service=. Lệnh này sẽ tác động đến zone mặc định, hoặc zone được chỉ định bằng --zone=. Mặc định, lệnh chỉ chỉnh sửa tường lửa đang chạy và không tồn tại sau khi khởi động lại hoặc dịch vụ tường lửa được reload. Bạn có thể chỉnh sửa cấu hình permanent bằng cờ --permanent.
Ví dụ, nếu bạn chạy máy chủ web với lưu lượng HTTP thông thường, bạn có thể tạm thời cho phép lưu lượng này trên các giao diện thuộc zone public:
sudo firewall-cmd --zone=public --add-service=http
Bạn có thể bỏ --zone= nếu muốn thay đổi zone mặc định. Bạn có thể xác nhận hoạt động thành công bằng --list-all hoặc --list-services:
sudo firewall-cmd --zone=public --list-services
Output
Sau khi kiểm tra mọi thứ hoạt động đúng, bạn có thể sửa cấu hình permanent để dịch vụ vẫn khả dụng sau khi khởi động lại. Bạn có thể làm như sau:
sudo firewall-cmd --zone=public --add-service=http --permanent
Output
Hoặc bạn có thể dùng:
sudo firewall-cmd --runtime-to-permanent
Lưu ý rằng lệnh --runtime-to-permanent sẽ lưu tất cả thay đổi hiện tại của tường lửa vào cấu hình permanent. Hãy cẩn thận với tùy chọn này.
Dù bạn chọn cách nào, bạn có thể xác nhận bằng cách thêm cờ --permanent vào lệnh --list-services. Nhớ rằng bất kỳ thao tác --permanent nào cũng cần sudo:
sudo firewall-cmd --zone=public --list-services --permanent
Output
sudo firewall-cmd --zone=public --add-service=https sudo firewall-cmd --zone=public --add-service=https --permanent
Những dịch vụ có sẵn cùng firewalld bao phủ nhiều ứng dụng phổ biến. Tuy nhiên, đôi khi chúng không đáp ứng nhu cầu cụ thể của bạn.
Trong tình huống này, bạn có hai lựa chọn.
Mở Cổng Cho Zone (Opening a Port for your Zones)
Cách đơn giản nhất để hỗ trợ ứng dụng riêng là mở các cổng mà ứng dụng sử dụng trong zone phù hợp. Bạn chỉ định số cổng (hoặc dải cổng) và giao thức liên quan (TCP hoặc UDP).
Ví dụ, nếu ứng dụng của bạn chạy trên cổng 5000 và sử dụng TCP, bạn có thể tạm thời thêm cổng này vào zone public:
sudo firewall-cmd --zone=public --add-port=5000/tcp
Output
success
Kiểm tra bằng:
sudo firewall-cmd --zone=public --list-ports
Output
Bạn cũng có thể mở một dải cổng bằng cách phân tách cổng bắt đầu và cổng kết thúc bằng dấu gạch ngang. Ví dụ, nếu ứng dụng dùng các cổng UDP từ 4990 đến 4999:
sudo firewall-cmd --zone=public --add-port=4990-4999/udp
Sau khi thử nghiệm, bạn có thể thêm các cổng này vào cấu hình permanent. Dùng sudo firewall-cmd --runtime-to-permanent, hoặc chạy lại các lệnh kèm --permanent:
sudo firewall-cmd --zone=public --permanent --add-port=5000/tcp sudo firewall-cmd --zone=public --permanent --add-port=4990-4999/udp sudo firewall-cmd --zone=public --permanent --list-ports
Output
Định Nghĩa Một Dịch Vụ (Defining a Service)
Việc mở cổng cho zone là cách tiếp cận đơn giản, nhưng đôi khi khó quản lý khi bạn có nhiều cổng và muốn biết chúng dùng cho dịch vụ nào. Nếu bạn gỡ bỏ một dịch vụ trên máy chủ, bạn có thể gặp khó khăn khi xác định cổng nào đã mở là còn cần thiết. Để tránh tình huống này, bạn có thể định nghĩa một dịch vụ mới.
Dịch vụ là một tập hợp các cổng với tên và mô tả đi kèm. Quản lý tường lửa bằng dịch vụ thường dễ duy trì hơn so với quản lý cổng, nhưng cần cấu hình ban đầu. Bạn có thể bắt đầu bằng cách sao chép một script sẵn có trong /usr/lib/firewalld/services sang thư mục /etc/firewalld/services, nơi tường lửa tìm các định nghĩa không chuẩn.
Ví dụ, bạn sao chép định nghĩa dịch vụ SSH sang một file mới để dùng làm ví dụ:
sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/example.xml
Tên dịch vụ trong danh sách firewall sẽ là tên file trừ phần mở rộng .xml.
Mở file bằng trình soạn thảo (vi, nano, …):
sudo vi /etc/firewalld/services/example.xml
Lúc đầu, file chứa nội dung định nghĩa SSH đã sao chép:
<?xml version="1.0" encoding="utf-8"?> <service> <short>SSH</short> <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description> <port protocol="tcp" port="22"/> </service>
Phần lớn nội dung trong tệp cấu hình này thực chất chỉ là siêu dữ liệu (metadata). Bạn nên thay đổi tên ngắn (short name) cho dịch vụ trong thẻ <short>. Đây là tên dễ đọc dành cho dịch vụ của bạn. Bạn cũng nên thêm một mô tả (description) để có thêm thông tin nếu sau này cần kiểm tra (audit) dịch vụ. Phần cấu hình duy nhất mà bạn thực sự cần thực hiện để ảnh hưởng đến chức năng của dịch vụ chính là khai báo cổng (port). Ở đó, bạn xác định số cổng và giao thức (protocol) cần mở. Bạn có thể chỉ định nhiều thẻ <port/> nếu cần.
<?xml version="1.0" encoding="utf-8"?> <service> <short>Example Service</short> <description>This is just an example service. It probably shouldn't be used on a real system.</description> <port protocol="tcp" port="7777"/> <port protocol="udp" port="8888"/> </service>
Lưu và đóng file.
Reload tường lửa để có thể sử dụng dịch vụ mới:
sudo firewall-cmd --reload
Bây giờ, bạn thấy nó nằm trong danh sách dịch vụ khả dụng:
firewall-cmd --get-services
Output
Bạn có thể dùng dịch vụ này trong các zone như bình thường.
Bước 5 — Tạo Zone Riêng (Creating Your Own Zones)
sudo firewall-cmd --permanent --new-zone=publicweb sudo firewall-cmd --permanent --new-zone=privateDNS
Bạn có thể xác nhận chúng có trong cấu hình permanent:
sudo firewall-cmd --permanent --get-zones
Output
Reload tường lửa để đưa hai zone này vào cấu hình runtime:
sudo firewall-cmd --reload firewall-cmd --get-zones
Output
Bây giờ, bạn có thể bắt đầu gán dịch vụ và cổng cho zone. Thông thường, nên điều chỉnh tường lửa runtime trước, rồi lưu thay đổi vào permanent sau khi thử nghiệm. Ví dụ, với zone publicweb, bạn có thể thêm dịch vụ SSH, HTTP, và HTTPS:
sudo firewall-cmd --zone=publicweb --add-service=ssh sudo firewall-cmd --zone=publicweb --add-service=http sudo firewall-cmd --zone=publicweb --add-service=https sudo firewall-cmd --zone=publicweb --list-all
Output
Sau đó, bạn thêm dịch vụ DNS vào zone privateDNS:
sudo firewall-cmd --zone=privateDNS --add-service=dns sudo firewall-cmd --zone=privateDNS --list-all
Output
Bạn có thể chuyển giao diện sang hai zone mới để thử nghiệm:
sudo firewall-cmd --zone=publicweb --change-interface=eth0 sudo firewall-cmd --zone=privateDNS --change-interface=eth1
Tại thời điểm này, bạn có thể kiểm tra cấu hình. Nếu mọi thứ hoạt động, bạn nên lưu quy tắc vào cấu hình permanent. Bạn có thể chạy lại lệnh với cờ --permanent, hoặc dùng:
sudo firewall-cmd --runtime-to-permanent
Sau khi áp dụng quy tắc vĩnh viễn, reload tường lửa để kiểm tra:
sudo firewall-cmd --reload
Kiểm tra zone hoạt động:
firewall-cmd --get-active-zones
Output
sudo firewall-cmd --zone=publicweb --list-services
Output
sudo firewall-cmd --zone=privateDNS --list-services
Output
Bạn đã thiết lập thành công các zone riêng! Để đặt một trong các zone này làm mặc định cho các giao diện khác, nhớ dùng tham số --set-default-zone=:
sudo firewall-cmd --set-default-zone=publicweb
Kết Luận
Bây giờ, bạn đã nắm được cách quản trị dịch vụ firewalld trên hệ thống Rocky Linux để sử dụng hằng ngày.
Dịch vụ firewalld cho phép bạn cấu hình quy tắc và bộ quy tắc (rulesets) có tính duy trì cao, đồng thời xem xét môi trường mạng của bạn. Nó giúp bạn chuyển đổi linh hoạt giữa các chính sách tường lửa nhờ việc sử dụng các zone. Hiểu biết cơ bản về hệ thống này sẽ cho phép bạn tận dụng tối đa sự linh hoạt và sức mạnh mà công cụ này cung cấp.
Để biết thêm thông tin về firewalld, hãy xem tài liệu chính thức: firewalld documentation.

