Hướng dẫn cấu hình firewalld trên Rocky và AlmaLinux
Hướng dẫn thiết lập firewalld cơ bản cho VPS Rocky hoặc AlmaLinux. Cách mở cổng SSH, web, đóng cổng và sử dụng flag --permanent để lưu cấu hình sau khi khởi động lại hệ thống.
firewalld là gì và tại sao Rocky và AlmaLinux lại cài đặt sẵn nó
firewalld là trình quản lý tường lửa được cài đặt mặc định trên Rocky Linux, AlmaLinux và các bản phân phối xây dựng lại từ Red Hat Enterprise Linux (RHEL). Cả hai bản phân phối này đều kế thừa mặc định đó thay vì tự chọn, điều này dễ hiểu hơn khi bạn biết cách Rocky và AlmaLinux xây dựng lại công việc của Red Hat sau khi CentOS thay đổi định hướng. Bản thân nó không trực tiếp kiểm tra gói tin. Nó lưu trữ cấu hình và chuyển đổi cấu hình đó thành các quy tắc nftables. Một lệnh duy nhất, firewall-cmd, cho phép chỉnh sửa cấu hình trong khi server vẫn đang chạy. Không có gì trong hướng dẫn này thay đổi giữa hai bản phân phối, vì những điểm khác biệt thực sự giữa Rocky và AlmaLinux nằm ở cam kết tương thích và phạm vi CPU được hỗ trợ, chứ không phải tường lửa.
Nếu bạn đã biết cách ufw hoạt động trên Ubuntu VPS, bạn đã nắm được công việc này. firewalld bổ sung hai khái niệm mà ufw không có. Thứ nhất là zones: một chính sách được đặt tên để phân loại các gói tin. Thứ hai là sự phân tách giữa các quy tắc đang chạy (live) và quy tắc đã lưu (saved), đây chính là flag --permanent và là nguồn gốc gây nhầm lẫn lớn nhất trong công cụ này.
Mọi nội dung dưới đây là các lệnh bạn chạy trên server của chính mình. Hãy kiểm tra mọi thay đổi từ một máy khác, vì một quy tắc trông có vẻ đúng trên máy chủ vẫn có thể sai khi truy cập từ Internet.
Mở SSH trước khi thực hiện bất kỳ thao tác nào khác
Hầu hết các bản cài đặt Rocky và AlmaLinux đều đã có sẵn firewalld và đang chạy, cấu hình mặc định cho phép SSH. Một số image tối giản trên cloud có thể đã lược bỏ nó. Hãy kiểm tra thay vì mặc định là nó đã có.
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --statefirewall-cmd --state in ra running. Nếu service bị dừng, mọi lệnh firewall-cmd khác đều trả về FirewallD is not running và thoát với mã lỗi khác 0. Đây là việc đầu tiên cần kiểm tra khi một lệnh dường như không có tác dụng gì cả.
Bây giờ hãy đọc các quy tắc hiện đang được cho phép.
sudo firewall-cmd --list-allKết quả thực tế sẽ có thêm vài dòng nữa. Đây là những dòng quan trọng:
public (active)
target: default
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
rich rules:ssh trong dòng services: là lý do session của bạn vẫn hoạt động. Nếu nó bị thiếu, hãy thêm vào trước khi bạn chạm vào bất cứ thứ gì khác, vì khởi động firewall mà không có quy tắc SSH sẽ ngắt session và bạn không thể truy cập lại được nữa.
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadtarget: default nghĩa là một gói tin không khớp với bất kỳ quy tắc nào sẽ bị từ chối với phản hồi ICMP (internet control message protocol) host-prohibited, vì vậy client khi truy cập vào cổng đóng sẽ nhận được No route to host ngay lập tức. Thiết lập target thành DROP sẽ khiến server im lặng, và các trình quét sẽ phải đợi cho đến khi timeout.
sudo firewall-cmd --permanent --zone=public --set-target=DROP
sudo firewall-cmd --reloadHãy cân nhắc kỹ trước khi chạy lệnh đó: DROP cũng khiến server không phản hồi ping, do đó hệ thống giám sát của bạn cũng sẽ mất kết nối.
Tại sao rule của tôi bị mất? Flag --permanent
firewalld duy trì hai cấu hình cùng lúc. Cấu hình runtime là những gì kernel đang thực thi ngay lúc này. Cấu hình permanent là những gì nằm trong /etc/firewalld/zones/public.xml và sẽ được khôi phục sau khi reload hoặc reboot.
Một lệnh không có --permanent chỉ thay đổi runtime. Nó có hiệu lực ngay lập tức nhưng sẽ mất đi sau lần reload hoặc boot tiếp theo. Một lệnh có --permanent sẽ ghi vào file và không thay đổi bất cứ thứ gì đang chạy, vì vậy cổng vẫn đóng cho đến khi bạn thực hiện reload. Cả hai hành vi này đều không phải là lỗi. Cả hai đều gây bất ngờ cho người dùng vì lệnh vẫn in ra success trong cả hai trường hợp.
Hãy luôn viết cả cặp lệnh này.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reloadBạn có thể đọc cả hai cấu hình, đây là cách nhanh nhất để biết bạn đã mắc lỗi nào trong hai lỗi trên.
sudo firewall-cmd --list-services
sudo firewall-cmd --permanent --list-servicesLệnh đầu tiên in ra tập hợp đang chạy. Lệnh thứ hai in ra tập hợp đã lưu. Nếu tập hợp đang chạy chứa một service mà tập hợp đã lưu không có, rule đó sẽ mất sau lần reload tới. Nếu tập hợp đã lưu chứa một service mà tập hợp đang chạy không có, bạn đã quên reload. sudo firewall-cmd --runtime-to-permanent sao chép mọi thứ từ runtime vào file permanent, rất hữu ích sau một phiên thử nghiệm.
--reload giữ lại trạng thái connection tracking, vì vậy phiên SSH của bạn vẫn duy trì được. --complete-reload tải lại cả các kernel module và làm mất trạng thái đó, thường sẽ ngắt mọi kết nối đang mở bao gồm cả kết nối của bạn. Hãy sử dụng lệnh reload thông thường.
Một lưới an toàn đã được tích hợp sẵn. Một runtime rule có thể tự hết hạn.
sudo firewall-cmd --add-service=http --timeout=5mRule đó sẽ tự xóa sau năm phút. Nó không thể kết hợp với --permanent, và đó chính là mục đích: nó tồn tại để kiểm tra một thay đổi mà bạn chưa chắc chắn. Lưới an toàn cũ hơn thì tốt hơn. Hãy luôn mở một phiên SSH thứ hai trong khi bạn chỉnh sửa các rule và đừng đóng nó cho đến khi một lần đăng nhập mới chứng minh rằng các rule mới đã hoạt động.
Các zone, và lý do tại sao chỉ zone mặc định mới quan trọng trên VPS
Một zone là tập hợp các quyền hạn được đặt tên kèm theo mức độ tin cậy. firewalld đưa mọi gói tin đến vào đúng một zone. Nó khớp địa chỉ nguồn của gói tin với danh sách sources: của từng zone trước. Nếu không có gì khớp, nó sử dụng zone mà interface nhận gói tin được gán vào. Nếu interface không được gán vào zone nào, gói tin sẽ đi vào zone mặc định.
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zonesTrên một VPS chỉ có một network interface, câu trả lời đầu tiên hầu như luôn là public, và đó là zone duy nhất bạn sẽ sử dụng. firewall-cmd khi không có đối số --zone= sẽ tác động lên zone mặc định, đó là lý do tại sao mọi lệnh ngắn trong hướng dẫn này đều hoạt động mà không cần chỉ định tên zone.
Đây là lỗi khiến bạn mất cả buổi chiều. Nếu interface được gán vào một zone khác, các rule của bạn sẽ nằm trong public trong khi lưu lượng truy cập lại được xử lý ở nơi khác, vì vậy những gì bạn thêm vào không có tác dụng và hệ thống cũng không cảnh báo bạn. --get-active-zones hiển thị việc gán này:
public
interfaces: eth0Nếu interface xuất hiện dưới một tên zone khác, hãy viết rule của bạn vào đó bằng --zone=, hoặc chuyển interface sang zone khác.
sudo firewall-cmd --permanent --zone=public --change-interface=eth0
sudo firewall-cmd --reloadNetworkManager quản lý các interface trên Rocky và AlmaLinux, và nó sẽ thiết lập lại zone khi kết nối được khởi tạo. Hãy cấu hình zone ở đó để việc reboot không làm mất các thay đổi của bạn. Lấy tên kết nối từ lệnh đầu tiên, vì nó hiếm khi trùng với tên thiết bị.
sudo nmcli connection show
sudo nmcli connection modify "System eth0" connection.zone publicKhớp theo nguồn (source) có độ ưu tiên cao hơn khớp theo interface, đây là cách một địa chỉ nhận được chính sách khác biệt. Zone trusted có sẵn sẽ chấp nhận mọi thứ.
sudo firewall-cmd --permanent --zone=trusted --add-source=203.0.113.10/32
sudo firewall-cmd --reloadHãy cẩn thận với zone đó. Nó mở mọi cổng trên server cho địa chỉ đó, bao gồm cả database mà bạn nghĩ là riêng tư. Hãy sử dụng rich rule khi bạn chỉ muốn mở một cổng, thay vì cho phép toàn bộ một host.
Service trong firewalld là gì?
Một service là một tập hợp các cổng được đặt tên, được đóng gói dưới dạng file XML. --add-service=https mở cổng 443/tcp vì /usr/lib/firewalld/services/https.xml định nghĩa ý nghĩa của https.
sudo firewall-cmd --get-services
sudo firewall-cmd --info-service=https--info-service in ra các cổng ẩn sau tên gọi đó:
https
ports: 443/tcpHãy sử dụng tên gọi khi nó tồn tại. Nó giúp cấu hình dễ đọc hơn trong --list-all sáu tháng sau, và các gói phần mềm như Cockpit sẽ tự cài đặt file service riêng của chúng. Hãy sử dụng --add-port cho bất kỳ thứ gì chưa có định nghĩa.
Điểm cần lưu ý: service ssh chỉ có nghĩa là 22/tcp và không gì khác. Nếu bạn đã chuyển SSH sang một cổng khác trong quá trình tăng cường bảo mật truy cập SSH trên máy chủ, thì --add-service=ssh sẽ không mở cổng mà bạn thực sự đang sử dụng.
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reloadTrên bản cài đặt lại RHEL, có một lớp khóa thứ hai trên cánh cửa đó. SELinux (Security-Enhanced Linux) gắn nhãn các số cổng, và sshd không được phép bind vào một cổng nằm ngoài các nhãn của nó. Khi đó, nó sẽ từ chối khởi động và log sẽ hiển thị error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.. Hãy gắn nhãn cho cổng trước.
sudo dnf install -y policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp 2222Làm thế nào để xem những gì đang mở ngay lúc này?
sudo firewall-cmd --list-all
sudo firewall-cmd --list-rich-rules
sudo nft list table inet firewalld | head -n 40Hai lệnh đầu báo cáo những gì firewalld ghi nhận. Lệnh thứ ba đọc các quy tắc mà kernel thực sự đang áp dụng trong bảng mà firewalld quản lý. Chúng phải khớp với nhau.
Không có gì trong số đó là bằng chứng xác thực. Hãy kiểm tra từ một máy khác:
nc -zv 203.0.113.20 443Đừng chạy kiểm tra trên chính máy chủ đó. firewalld chấp nhận mọi kết nối đến giao diện loopback, vì vậy curl http://localhost:8080 sẽ thành công bất kể quy tắc của bạn là gì. Kiểm tra đó chỉ cho biết dịch vụ đang hoạt động. Nó không cho bạn biết gì về firewall cả.
Cho phép cổng web
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-servicesLệnh cuối cùng bây giờ sẽ liệt kê http https cùng với các mục đã có trước đó. Nếu trang web vẫn không phản hồi, vấn đề có thể không nằm ở firewall. Một rule chỉ cho phép gói tin đi qua. Một tiến trình vẫn phải đang lắng nghe trên cổng đó.
sudo ss -tlnpMột socket hiển thị là 0.0.0.0:443 hoặc *:443 chấp nhận kết nối từ bất kỳ địa chỉ nào. Một socket hiển thị là 127.0.0.1:443 chỉ phản hồi trên loopback, và không có rule firewall nào có thể làm cho nó truy cập được từ bên ngoài. Các cổng và socket đang lắng nghe trên Linux giải thích chi tiết hơn về sự khác biệt này.
Làm thế nào để đóng lại một cổng?
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reloadQuy tắc --permanent cũng áp dụng ở đây, và nó gây ra hậu quả nghiêm trọng hơn theo chiều này. Nếu bạn chỉ xóa service khỏi runtime, cổng sẽ trông như đã đóng, nhưng lần reload hoặc reboot tiếp theo sẽ mở lại nó từ file cấu hình đã lưu. Đây là một lỗ hổng bạn sẽ không nhận ra, vì lệnh kiểm tra bạn chạy trước đó đã báo thành công.
Việc xóa một thứ chưa từng tồn tại sẽ in ra Warning: NOT_ENABLED: http và vẫn thoát với mã 0. Thêm cùng một thứ hai lần sẽ in ra Warning: ALREADY_ENABLED: http. Cả hai đều an toàn. Sai chính tả tên service lại là chuyện khác: Error: INVALID_SERVICE nghĩa là firewalld không có định nghĩa nào với tên đó và không có thay đổi nào được thực hiện.
Nếu --list-all của bạn hiển thị cockpit và bạn không sử dụng giao diện web Cockpit trên cổng 9090, hãy xóa nó đi. Mỗi cổng mở là một service mà bạn phải duy trì bản vá, và với những service bạn quyết định giữ lại, dnf-automatic có thể cài đặt các bản cập nhật bảo mật theo lịch trình để công việc đó không phụ thuộc vào việc bạn có nhớ hay không. Tuy nhiên, cài đặt bản vá không giống với việc áp dụng nó, và needs-restarting sẽ cho biết những service nào vẫn đang sử dụng các thư viện cũ sau khi các bản cập nhật đó được cài đặt.
Giới hạn một cổng cho một địa chỉ nguồn
Rich rules là dạng cấu hình mở rộng, dùng khi tên service thông thường không thể diễn đạt yêu cầu của bạn. Việc giới hạn SSH cho một địa chỉ văn phòng cần hai lệnh, và lệnh thứ hai thường bị người dùng bỏ quên.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept'
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reloadMột zone là tập hợp các quyền, không phải danh sách đánh số dừng lại ở kết quả khớp đầu tiên. Rich rule thêm một lệnh chấp nhận (accept) cho một địa chỉ cụ thể. Nó không từ chối ai cả. Khi ssh vẫn nằm trong dòng services:, toàn bộ internet vẫn truy cập được cổng 22 và rich rule không thay đổi bất cứ điều gì bạn có thể đo lường. Hãy xóa mục cho phép rộng rãi đó, nếu không mục giới hạn chỉ mang tính hình thức.
Đối với cổng không có tên service, hãy chỉ định trực tiếp cổng đó.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" port port="5432" protocol="tcp" accept'Để drop lưu lượng từ một mạng gây nhiễu và lưu lại log, hãy đặt phần tử log trước hành động, đây là thứ tự mà ngôn ngữ rich rule yêu cầu.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" log prefix="fw-drop " level="info" limit value="3/m" drop'
sudo firewall-cmd --reload
sudo journalctl -k -g fw-dropGiá trị limit giúp ngăn chặn tình trạng tràn gói tin làm đầy journal. Trước khi khóa SSH vào một địa chỉ duy nhất, hãy đảm bảo địa chỉ đó ổn định. Kết nối tại nhà với IP thay đổi sẽ khóa quyền truy cập của bạn ngay khi IP đó đổi, vì vậy hãy kiểm tra và đảm bảo quyền truy cập console từ nhà cung cấp của bạn đã hoạt động trước.
Các lệnh ufw và lệnh tương đương trong firewall-cmd
Cùng một tác vụ, công cụ khác nhau. Mỗi dòng --permanent cần một sudo firewall-cmd --reload đi kèm, đây là điều duy nhất mà một danh sách như thế này không thể hiển thị cho bạn.
sudo ufw enabletrở thànhsudo systemctl enable --now firewalldsudo ufw disabletrở thànhsudo systemctl disable --now firewalldsudo ufw status verbosetrở thànhsudo firewall-cmd --list-allsudo ufw allow OpenSSHtrở thànhsudo firewall-cmd --permanent --add-service=sshsudo ufw allow 443/tcptrở thànhsudo firewall-cmd --permanent --add-port=443/tcpsudo ufw delete allow 443/tcptrở thànhsudo firewall-cmd --permanent --remove-port=443/tcpsudo ufw allow from 203.0.113.10 to any port 22trở thành quy tắc rich rule như đã hiển thị ở trênsudo ufw reloadtrở thànhsudo firewall-cmd --reloadsudo ufw default deny incomingvốn dĩ là cách hoạt động của zonepublic, và--set-target=DROPlà phiên bản im lặng của nósudo ufw logging ontrở thànhsudo firewall-cmd --set-log-denied=all
Có một điểm khác biệt cần nêu rõ. ufw duy trì một danh sách được đánh số và bạn có thể chèn một quy tắc vào vị trí số 1. firewalld không có số thứ tự quy tắc, vì vậy khái niệm "đặt quy tắc này lên đầu" không tồn tại ở đây. Khi hai mục trong firewalld có vẻ mâu thuẫn nhau, quy tắc accept rộng hơn sẽ thắng, vì không có gì trong tập hợp này thực hiện lệnh deny. Bạn phải tự mình xóa bỏ mục nhập rộng đó.
Tại sao container Docker của tôi vẫn truy cập được dù firewall có vẻ đã đóng?
Vì cổng container được publish không bao giờ đi qua phần firewall mà zone của bạn kiểm soát. docker run -d -p 8080:80 nginx ra lệnh cho Docker tự ghi các quy tắc NAT (network address translation) và forwarding của riêng nó. Một gói tin đến cổng 8080 sẽ được viết lại và định tuyến đến container, vì vậy nó được chuyển tiếp (forward) thay vì được gửi đến host. Các dòng services: và ports: trong zone của bạn chỉ quản lý các gói tin gửi đến host. Các quy tắc của Docker quản lý đường dẫn chuyển tiếp và chúng chấp nhận các gói tin này.
Kết quả là một máy chủ mà tại đó sudo firewall-cmd --list-all không hiển thị cổng 8080 nhưng nc -zv 203.0.113.20 8080 từ máy khác vẫn kết nối được. Hãy xem Docker đã cài đặt những gì:
sudo iptables -t nat -L DOCKER -nCách khắc phục nằm ở flag publish. Hãy bind cổng vào loopback và đặt một reverse proxy ở phía trước nó.
docker run -d -p 127.0.0.1:8080:80 nginxContainer giờ đây chỉ phản hồi curl http://127.0.0.1:8080 trên máy chủ và không phản hồi từ bên ngoài. Người dùng Ubuntu cũng gặp rào cản tương tự, được mô tả tại tại sao các container Docker publish cổng trực tiếp vượt qua ufw. Podman chạy dưới quyền root, vốn có sẵn trong các repository cơ bản của Rocky và AlmaLinux, cũng publish cổng với cách tiếp cận NAT tương tự, vì vậy hãy kiểm tra từ một máy khác thay vì tin tưởng vào danh sách zone. Sự chồng chéo đó cũng là lý do cài đặt Docker Engine trên các bản phân phối này cần một vài bước mà hướng dẫn cho Ubuntu không bao giờ đề cập, bắt đầu từ việc Podman đã chiếm quyền sử dụng lệnh docker.
Đảm bảo firewall hoạt động sau khi reboot và các lỗi thường gặp
sudo systemctl is-enabled firewalld
sudo systemctl status firewalldenabled và active (running) là những lệnh bạn cần. Một firewall đang chạy nhưng chưa được enable chỉ bảo vệ bạn cho đến lần reboot đầu tiên. Việc kiểm tra này phải nằm trong danh sách các bước bạn thực hiện trong mười phút đầu tiên trên một VPS mới, ngay cạnh việc thiết lập SSH keys và cập nhật hệ thống.
Các lệnh nftables thô và firewalld không thể dùng chung. firewalld quản lý một table tên là inet firewalld. sudo nft flush ruleset sẽ xóa table này, khiến máy chủ mở toàn bộ cổng, và firewall-cmd --list-all vẫn hiển thị cấu hình bạn mong muốn, vì firewalld báo cáo những gì nó tin là đúng thay vì những gì kernel thực sự đang áp dụng. sudo firewall-cmd --reload sẽ cài đặt lại các quy tắc. Hãy viết quy tắc bằng firewall-cmd để chúng tự động khôi phục sau khi reload.
Hai trình quản lý firewall trên cùng một máy chủ. Việc cài đặt ufw hoặc iptables-services bên cạnh firewalld sẽ tạo ra hai chương trình cùng ghi quy tắc mà không biết về nhau, và kết quả phụ thuộc vào việc service nào khởi động sau cùng. Hãy chọn một. Trên Rocky và AlmaLinux, firewalld là lựa chọn được hỗ trợ bởi bản phân phối.
Firewall của nhà cung cấp phía trước máy chủ. Nhiều bảng điều khiển VPS có một firewall mạng riêng biệt. Nếu --list-all hiển thị cổng đang mở mà kết nối từ bên ngoài vẫn thất bại, hãy kiểm tra bảng điều khiển trước khi thay đổi bất cứ thứ gì trên máy chủ. Điều này cũng đúng theo chiều ngược lại: một quy tắc mở trên bảng điều khiển sẽ vô tác dụng nếu firewalld từ chối gói tin.
Chạy firewall-cmd mà không có sudo. Mọi thay đổi đều cần quyền root. Nếu không có quyền này, yêu cầu sẽ bị từ chối bởi kiểm tra xác thực và không có gì được sửa đổi, điều này trông giống như lệnh bị bỏ qua.
Sáu lệnh sau đây bao quát hầu hết các công việc hàng ngày: --list-all để đọc trạng thái, --permanent --add-service hoặc --add-port để mở cổng, --permanent --remove-service để đóng cổng, --reload để áp dụng file đã lưu, và --runtime-to-permanent sau khi thử nghiệm xong. Zone mặc định là public, flag cần dùng là --permanent, và cách kiểm tra chính xác nhất là thực hiện từ một máy khác.
FAQ
Tại sao rule firewalld của tôi biến mất sau khi reboot?
Rule đó chỉ được áp dụng vào cấu hình runtime. sudo firewall-cmd --add-service=http có hiệu lực ngay lập tức nhưng sẽ bị xóa khi reload hoặc reboot, vì cấu hình đã lưu trong /etc/firewalld/zones/public.xml không hề thay đổi. Hãy thêm --permanent rồi chạy sudo firewall-cmd --reload. Để giữ lại các rule bạn đã thêm thủ công, hãy chạy sudo firewall-cmd --runtime-to-permanent, lệnh này sẽ sao chép cấu hình đang chạy vào file cấu hình cố định.
Tại sao không có gì thay đổi sau khi tôi thêm rule với --permanent?
Vì --permanent chỉ ghi vào file và không tác động đến firewall đang chạy. Cổng vẫn đóng cho đến khi sudo firewall-cmd --reload nạp cấu hình đã lưu vào kernel. Hãy so sánh sudo firewall-cmd --list-services với sudo firewall-cmd --permanent --list-services: nếu danh sách đã lưu có entry mà danh sách đang chạy không có, nghĩa là bạn đang thiếu bước reload.
Tôi nên dùng --add-service hay --add-port?
Hãy dùng --add-service khi đã có tên dịch vụ cho ứng dụng bạn chạy. Nó thể hiện mục đích rõ ràng và sudo firewall-cmd --info-service=https sẽ hiển thị chính xác các cổng mà tên dịch vụ đó bao gồm. Hãy dùng --add-port khi không có định nghĩa nào cho dịch vụ của bạn, hoặc khi nó nghe trên một cổng không tiêu chuẩn. Dịch vụ ssh chỉ có nghĩa là 22/tcp, vì vậy nếu SSH chuyển sang 2222 thì cần --add-port=2222/tcp kèm theo một SELinux label cho cổng đó.
Tại sao container Docker vẫn truy cập được trong khi firewall-cmd báo cổng đã đóng?
Một cổng được publish sẽ bị ghi đè bởi các rule NAT của Docker và chuyển tiếp trực tiếp vào container, nên gói tin không bao giờ được gửi đến host, trong khi danh sách service và port của zone chỉ áp dụng cho các gói tin gửi đến host. Container phản hồi từ internet trong khi --list-all không hiển thị gì cả. Hãy publish ra loopback bằng docker run -d -p 127.0.0.1:8080:80 nginx và đặt một reverse proxy ở phía trước.
Tôi có thể cài ufw trên Rocky Linux thay vì firewalld không?
Hai trình quản lý firewall trên cùng một server sẽ ghi đè rule của nhau mà không biết về nhau, và bộ rule nào tồn tại phụ thuộc vào việc service nào khởi động sau cùng. firewalld là công cụ được hỗ trợ trên Rocky Linux và AlmaLinux, nó đã được cài sẵn và điều khiển cùng một backend nftables mà ufw sẽ sử dụng. Chỉ cần học cách dùng default zone và flag --permanent là bạn đã nắm được toàn bộ công cụ này.