Rocky Linux 및 AlmaLinux firewalld 설정 방법
Rocky Linux와 AlmaLinux에서 firewalld를 사용하여 SSH 포트를 열고 웹 서비스를 허용하는 방법을 설명합니다. --permanent 플래그 사용 시 주의사항과 영역 개념을 정리하여 재부팅 후에도 방화벽 설정이 안전하게 유지되도록 돕습니다.
firewalld란 무엇이며, 왜 Rocky와 AlmaLinux가 이를 기본으로 제공하는가
firewalld는 Rocky Linux, AlmaLinux 및 기타 Red Hat Enterprise Linux(RHEL) 리빌드 배포판에 기본으로 설치되는 방화벽 관리자입니다. 이 도구는 직접 패킷을 검사하지 않습니다. 저장된 설정을 유지하고 해당 설정을 nftables 규칙으로 변환합니다. 서버가 온라인 상태일 때 firewall-cmd 명령을 사용하면 설정을 편집할 수 있습니다.
Ubuntu VPS에서 ufw가 작동하는 방식을 이미 알고 있다면, 이 도구의 역할도 이해할 수 있습니다. firewalld는 ufw에는 없는 두 가지 개념을 추가합니다. 첫 번째는 영역(zones)으로, 패킷이 분류되는 명명된 정책입니다. 두 번째는 실시간 규칙과 저장된 규칙의 분리이며, 이는 --permanent 플래그와 관련이 있고 이 도구에서 가장 혼란을 일으키는 원인입니다.
아래의 모든 내용은 서버에서 직접 실행하는 명령어입니다. 서버 내부에서 올바르게 보이는 규칙이라도 인터넷에서는 잘못 작동할 수 있으므로, 모든 변경 사항은 다른 기기에서 테스트하십시오.
다른 작업을 시작하기 전에 SSH를 먼저 여십시오
대부분의 Rocky 및 AlmaLinux 설치 환경에는 firewalld가 이미 설치되어 실행 중이며, 기본 설정은 SSH를 허용합니다. 일부 최소화된 클라우드 이미지에서는 이 설정이 제거되어 있을 수 있습니다. 무조건 가정하지 말고 확인하십시오.
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --statefirewall-cmd --state은 running을 출력합니다. 서비스가 중지된 상태라면 다른 모든 firewall-cmd 호출은 FirewallD is not running을 반환하며 0이 아닌 종료 코드로 종료됩니다. 명령어가 아무런 반응을 보이지 않을 때 가장 먼저 확인해야 할 사항입니다.
이제 현재 허용된 설정을 읽어 보십시오.
sudo firewall-cmd --list-all실제 출력에는 몇 줄이 더 포함됩니다. 다음은 중요한 항목입니다.
public (active)
target: default
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
rich rules:services: 라인에 있는 ssh 덕분에 현재 세션이 유지되는 것입니다. 만약 이 항목이 없다면 다른 설정을 변경하기 전에 먼저 추가하십시오. SSH 규칙 없이 방화벽을 시작하면 세션이 즉시 끊기며 다시 접속할 수 없게 됩니다.
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reloadtarget: default은 일치하는 규칙이 없는 패킷이 ICMP(internet control message protocol) host-prohibited 응답과 함께 거부됨을 의미합니다. 따라서 닫힌 포트에 접근하는 클라이언트는 즉시 No route to host을 확인하게 됩니다. 대상을 DROP로 설정하면 서버가 아무런 응답을 하지 않게 되며, 스캐너는 타임아웃이 발생할 때까지 대기하게 됩니다.
sudo firewall-cmd --permanent --zone=public --set-target=DROP
sudo firewall-cmd --reload해당 설정을 적용하기 전에 비용을 고려하십시오. DROP를 설정하면 서버가 ping에 응답하지 않게 되므로, 사용 중인 모니터링 시스템도 응답을 받지 못하게 됩니다.
규칙이 사라진 이유는 무엇인가? --permanent 플래그
firewalld는 두 가지 설정을 동시에 유지합니다. 런타임 설정은 현재 커널이 즉시 적용하고 있는 설정입니다. 영구 설정은 /etc/firewalld/zones/public.xml에 저장되며, 리로드나 재부팅 후에 다시 불러와지는 설정입니다.
--permanent 없이 실행한 명령어는 런타임 설정만 변경합니다. 즉시 적용되지만, 다음 리로드나 부팅 시 사라집니다. --permanent을 포함한 명령어는 파일을 기록할 뿐 현재 실행 중인 설정은 변경하지 않으므로, 리로드하기 전까지는 포트가 닫힌 상태로 유지됩니다. 두 동작 모두 버그가 아닙니다. 다만 명령어 실행 시 두 경우 모두 success를 출력하기 때문에 사용자가 혼란을 겪곤 합니다.
항상 두 가지를 함께 작성하십시오.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload두 설정을 모두 읽어보면 어떤 실수를 했는지 가장 빠르게 확인할 수 있습니다.
sudo firewall-cmd --list-services
sudo firewall-cmd --permanent --list-services첫 번째 명령어는 현재 적용된 설정을 출력합니다. 두 번째 명령어는 저장된 설정을 출력합니다. 현재 설정에는 서비스가 포함되어 있는데 저장된 설정에는 없다면, 리로드 시 해당 규칙은 사라집니다. 반대로 저장된 설정에는 있는데 현재 설정에는 없다면, 리로드를 수행하지 않은 것입니다. sudo firewall-cmd --runtime-to-permanent는 현재 적용된 모든 설정을 저장된 파일로 복사하며, 실험적인 작업을 마친 후 유용하게 사용할 수 있습니다.
--reload은 연결 추적 상태를 유지하므로 SSH 세션이 끊기지 않습니다. --complete-reload은 커널 모듈까지 다시 불러오며 상태를 초기화하므로, 일반적으로 사용자의 세션을 포함한 모든 열린 연결이 종료됩니다. 일반적인 리로드를 사용하십시오.
내장된 안전장치가 하나 있습니다. 런타임 규칙은 스스로 만료될 수 있습니다.
sudo firewall-cmd --add-service=http --timeout=5m이 규칙은 5분 후에 스스로 제거됩니다. 이 명령어는 --permanent과 함께 사용할 수 없으며, 바로 그 점이 핵심입니다. 확실하지 않은 변경 사항을 테스트하기 위해 존재하기 때문입니다. 더 오래된 안전장치가 더 효과적입니다. 규칙을 수정하는 동안 두 번째 SSH 세션을 열어두고, 새로 로그인하여 변경된 규칙이 정상 작동하는지 확인하기 전까지는 기존 세션을 닫지 마십시오.
존(Zone)과 VPS에서 기본 존만 중요한 이유
존은 신뢰 수준이 부여된 권한의 명명된 집합입니다. firewalld는 모든 수신 패킷을 정확히 하나의 존에 할당합니다. 먼저 패킷의 소스 주소를 각 존의 sources: 목록과 대조합니다. 일치하는 항목이 없으면 수신 인터페이스가 바인딩된 존을 사용합니다. 인터페이스가 어떤 존에도 바인딩되어 있지 않으면 패킷은 기본 존으로 전달됩니다.
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zones네트워크 인터페이스가 하나인 VPS에서 첫 번째 응답은 거의 항상 public이며, 이것이 여러분이 사용할 유일한 존입니다. firewall-cmd에 --zone= 인수를 지정하지 않으면 기본 존에 적용되므로, 이 가이드의 모든 짧은 명령어가 존 이름을 명시하지 않아도 작동하는 것입니다.
오후 시간을 낭비하게 만드는 실패 사례는 다음과 같습니다. 인터페이스가 다른 존에 바인딩되어 있으면, 트래픽은 다른 곳에서 처리되는데 규칙은 public에 추가됩니다. 따라서 추가한 규칙은 아무런 효과가 없으며 경고 메시지도 출력되지 않습니다. --get-active-zones 명령어로 바인딩 상태를 확인할 수 있습니다.
public
interfaces: eth0인터페이스가 다른 존 이름 아래에 표시된다면, --zone=를 사용하여 해당 존에 규칙을 작성하거나 인터페이스를 이동하십시오.
sudo firewall-cmd --permanent --zone=public --change-interface=eth0
sudo firewall-cmd --reloadRocky 및 AlmaLinux에서는 NetworkManager가 인터페이스를 관리하며, 연결이 활성화될 때 존 설정을 다시 적용합니다. 재부팅 시 설정이 초기화되지 않도록 NetworkManager에서도 존을 설정하십시오. 첫 번째 명령어에서 연결 이름을 확인하십시오. 연결 이름은 장치 이름과 다른 경우가 많습니다.
sudo nmcli connection show
sudo nmcli connection modify "System eth0" connection.zone public소스 매칭은 인터페이스 매칭보다 우선하며, 이를 통해 특정 주소에 다른 정책을 적용할 수 있습니다. 내장된 trusted 존은 모든 트래픽을 허용합니다.
sudo firewall-cmd --permanent --zone=trusted --add-source=203.0.113.10/32
sudo firewall-cmd --reload이 존을 사용할 때는 주의하십시오. 해당 주소에 대해 데이터베이스를 포함한 서버의 모든 포트를 개방하게 됩니다. 특정 호스트가 아닌 특정 포트만 허용하려면 rich rule을 사용하십시오.
firewalld 서비스란 무엇입니까?
서비스는 XML 파일로 제공되는 포트의 명명된 묶음입니다. --add-service=https은 443/tcp를 개방하는데, 이는 /usr/lib/firewalld/services/https.xml이 https의 의미를 정의하기 때문입니다.
sudo firewall-cmd --get-services
sudo firewall-cmd --info-service=https--info-service은 해당 이름 뒤에 숨겨진 포트를 출력합니다.
https
ports: 443/tcp이름이 존재하는 경우 해당 이름을 사용하십시오. 6개월 뒤에 --list-all을 다시 보더라도 명확하게 읽히며, Cockpit과 같은 패키지는 자체 서비스 파일을 설치합니다. 정의가 없는 항목에는 --add-port를 사용하십시오.
주의할 점은 다음과 같습니다. ssh 서비스는 22/tcp만을 의미합니다. 만약 서버의 SSH 접근 강화 과정에서 SSH 포트를 다른 번호로 변경했다면, --add-service=ssh는 실제로 사용하는 포트를 개방하지 않습니다.
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reloadRHEL을 재구축할 때는 해당 문에 두 번째 잠금 장치가 있습니다. SELinux(Security-Enhanced Linux)는 포트 번호에 레이블을 지정하며, sshd는 자신의 레이블 범위를 벗어난 포트에 바인딩할 수 없습니다. 이 경우 서비스는 시작을 거부하며 로그에는 error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.이 기록됩니다. 먼저 포트에 레이블을 지정하십시오.
sudo dnf install -y policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp 2222현재 열려 있는 포트를 확인하려면 어떻게 해야 합니까?
sudo firewall-cmd --list-all
sudo firewall-cmd --list-rich-rules
sudo nft list table inet firewalld | head -n 40처음 두 명령은 firewalld가 인식하고 있는 상태를 보고합니다. 세 번째 명령은 firewalld가 소유한 테이블 내에서 커널이 실제로 적용 중인 규칙을 읽습니다. 이 결과들은 서로 일치해야 합니다.
위의 결과만으로는 충분한 증거가 되지 않습니다. 다른 머신에서 테스트를 수행하십시오:
nc -zv 203.0.113.20 443테스트를 서버 자체에서 실행하지 마십시오. firewalld는 루프백 인터페이스로 들어오는 모든 트래픽을 허용하므로, 규칙 설정과 관계없이 curl http://localhost:8080은 항상 성공합니다. 이 테스트는 서비스가 실행 중이라는 사실만 알려줄 뿐, 방화벽 설정에 대해서는 아무것도 알려주지 않습니다.
웹 포트 허용
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-services마지막 명령을 실행하면 이전에 있던 항목과 함께 http https이 목록에 표시되어야 합니다. 만약 사이트가 여전히 응답하지 않는다면, 방화벽이 원인이 아닐 수 있습니다. 규칙은 패킷을 허용할 뿐이며, 해당 포트에서 응답을 대기하는 프로세스가 여전히 실행 중이어야 합니다.
sudo ss -tlnp0.0.0.0:443 또는 *:443으로 표시된 소켓은 모든 주소로부터의 연결을 수락합니다. 127.0.0.1:443로 표시된 소켓은 루프백 주소에서만 응답하며, 방화벽 규칙을 어떻게 설정하더라도 외부에서 접근할 수 없습니다. Linux의 포트와 리스닝 소켓에서 이 차이점에 대해 더 자세히 다룹니다.
포트를 다시 닫으려면 어떻게 해야 합니까?
sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reload--permanent 규칙은 여기서도 적용되며, 이 방향에서는 더 큰 문제를 일으킵니다. 런타임에서만 서비스를 제거하면 포트가 닫힌 것처럼 보이지만, 다음 리로드나 재부팅 시 저장된 파일에서 다시 열립니다. 이는 실행한 검사가 통과되었기 때문에 알아차리기 어려운 보안 구멍입니다.
존재하지 않는 항목을 제거하려고 하면 Warning: NOT_ENABLED: http이 출력되지만 종료 코드는 0을 반환합니다. 동일한 항목을 두 번 추가하면 Warning: ALREADY_ENABLED: http가 출력됩니다. 두 경우 모두 안전합니다. 이름의 철자가 틀린 경우는 다릅니다. Error: INVALID_SERVICE는 firewalld에 해당 이름으로 정의된 항목이 없으며 아무것도 변경되지 않았음을 의미합니다.
--list-all에 cockpit이 표시되는데 포트 9090에서 Cockpit 웹 콘솔을 사용하지 않는다면, 해당 서비스를 제거하십시오. 열려 있는 모든 포트는 지속적으로 패치해야 하는 서비스입니다.
특정 소스 주소로 포트 접근 제한하기
Rich rule은 단순 서비스 이름만으로 의도를 표현할 수 없을 때 사용하는 상세 설정 방식입니다. SSH 접근을 특정 사무실 주소로 제한하려면 두 개의 명령어가 필요하며, 사람들은 흔히 두 번째 명령어를 잊어버립니다.
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 --reloadfirewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
firewall-cmd --permanent --remove-service="ssh"
firewall-cmd --reload
Zone은 권한의 집합이지, 첫 번째 일치 항목에서 멈추는 번호 매겨진 목록이 아닙니다. Rich rule은 특정 주소에 대한 허용 규칙을 추가할 뿐, 누구도 거부하지 않습니다. ssh이 여전히 services: 라인에 남아 있다면, 인터넷 전체가 여전히 22번 포트에 접근할 수 있으며 Rich rule은 아무런 실질적인 변화를 주지 못합니다. 광범위한 항목을 제거하지 않으면 좁은 범위의 규칙은 장식에 불과합니다.
서비스 이름이 없는 포트의 경우, 서비스 이름 대신 포트 번호를 지정하십시오.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" port port="5432" protocol="tcp" accept'firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="8080" protocol="tcp" accept'
시끄러운 네트워크를 차단하고 기록을 남기려면, Rich rule 언어의 문법에 따라 action 앞에 log 요소를 배치해야 합니다.
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-dropfirewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" log prefix="DROP: " level="info" limit value="1/m" drop'
limit 값은 패킷 홍수로 인해 저널이 가득 차는 것을 방지합니다. SSH를 단일 주소로 고정하기 전에 해당 주소가 안정적인지 확인하십시오. IP 주소가 변경되는 가정용 회선을 사용하면 주소가 바뀌는 날 즉시 접속이 차단되므로, 먼저 제공업체의 콘솔 접근 권한이 정상적으로 작동하는지 확인해야 합니다.
ufw 명령어와 그에 대응하는 firewall-cmd 명령어
동일한 작업이라도 도구에 따라 방식이 다릅니다. 모든 --permanent 줄 뒤에는 sudo firewall-cmd --reload가 필요하며, 이 목록에서는 이를 일일이 보여드릴 수 없습니다.
sudo ufw enable은sudo systemctl enable --now firewalld가 됩니다.sudo ufw disable는sudo systemctl disable --now firewalld이 됩니다.sudo ufw status verbose은sudo firewall-cmd --list-all이 됩니다.sudo ufw allow OpenSSH는sudo firewall-cmd --permanent --add-service=ssh이 됩니다.sudo ufw allow 443/tcp은sudo firewall-cmd --permanent --add-port=443/tcp가 됩니다.sudo ufw delete allow 443/tcp은sudo firewall-cmd --permanent --remove-port=443/tcp가 됩니다.sudo ufw allow from 203.0.113.10 to any port 22는 위에서 설명한 rich rule이 됩니다.sudo ufw reload은sudo firewall-cmd --reload이 됩니다.sudo ufw default deny incoming은 이미public영역이 동작하는 방식이며,--set-target=DROP은 그 조용한(silent) 버전입니다.sudo ufw logging on은sudo firewall-cmd --set-log-denied=all가 됩니다.
한 가지 차이점은 명확히 짚고 넘어가야 합니다. ufw는 규칙에 번호를 매겨 관리하므로 1번 위치에 규칙을 삽입할 수 있습니다. 반면 firewalld는 규칙 번호가 없으므로 "이 규칙을 가장 먼저 적용하라"는 개념이 존재하지 않습니다. 두 개의 firewalld 항목이 서로 충돌하는 것처럼 보일 경우, 거부(deny) 규칙이 없기 때문에 더 넓은 범위의 허용(accept) 규칙이 우선합니다. 따라서 넓은 범위의 규칙은 사용자가 직접 제거해야 합니다.
방화벽이 닫혀 있는데도 Docker 컨테이너에 접근할 수 있는 이유는 무엇입니까?
공개된 컨테이너 포트는 방화벽의 영역(zone)이 제어하는 지점에 도달하지 않기 때문입니다. docker run -d -p 8080:80 nginx은 Docker에게 자체 NAT(네트워크 주소 변환) 및 포워딩 규칙을 작성하도록 지시합니다. 8080 포트로 들어오는 패킷은 재작성되어 컨테이너로 라우팅되므로, 호스트로 전달되는 것이 아니라 포워딩됩니다. 사용자의 영역에 있는 services: 및 ports: 라인은 호스트로 전달되는 패킷을 제어합니다. Docker의 규칙은 포워딩 경로를 제어하며, 이 규칙은 패킷을 허용합니다.
그 결과 sudo firewall-cmd --list-all에서는 8080 포트가 보이지 않지만, 다른 머신에서 nc -zv 203.0.113.20 8080을 실행하면 연결되는 서버 상태가 됩니다. Docker가 설치한 규칙을 확인하십시오.
sudo iptables -t nat -L DOCKER -n해결책은 publish 플래그에 있습니다. 포트를 루프백(loopback)에 바인딩하고 그 앞에 리버스 프록시를 배치하십시오.
docker run -d -p 127.0.0.1:8080:80 nginx이제 컨테이너는 서버 내부의 curl http://127.0.0.1:8080에만 응답하며 외부에서는 아무것도 응답하지 않습니다. Ubuntu 사용자도 Docker 컨테이너가 ufw를 우회하여 포트를 공개하는 이유에 설명된 것과 동일한 문제에 직면합니다. Rocky 및 AlmaLinux의 기본 저장소에서 제공하는 Rootful Podman 역시 동일한 NAT 방식으로 포트를 공개하므로, 영역 목록을 신뢰하기보다는 다른 머신에서 직접 테스트하십시오.
재부팅 후에도 설정이 유지되도록 하기 및 발생 가능한 오류
sudo systemctl is-enabled firewalld
sudo systemctl status firewalldenabled와 active (running)을 사용해야 합니다. 방화벽이 실행 중이지만 활성화되지 않은 상태라면 첫 재부팅 전까지만 보호를 받을 수 있습니다. 이 점검 항목은 새 VPS 설정 후 첫 10분에 수행하는 작업 목록에 SSH 키 설정 및 업데이트와 함께 포함되어야 합니다.
원시 nftables 명령어와 firewalld는 함께 사용할 수 없습니다. firewalld는 inet firewalld이라는 테이블을 독점적으로 관리합니다. sudo nft flush ruleset를 실행하면 해당 테이블이 삭제되어 서버가 모든 트래픽에 노출되지만, firewall-cmd --list-all은 커널의 실제 상태가 아닌 firewalld가 인지하는 설정값만 출력합니다. sudo firewall-cmd --reload를 실행해야 규칙이 다시 설치됩니다. 규칙을 작성할 때는 firewall-cmd를 사용하여 재로드 후에도 설정이 유지되도록 하십시오.
한 서버에 두 개의 방화벽 관리자를 두지 마십시오. firewalld와 함께 ufw나 iptables-services을 설치하면 서로의 존재를 모르는 두 프로그램이 규칙을 작성하게 되며, 마지막에 시작된 서비스가 우선권을 갖게 됩니다. 하나만 선택하십시오. Rocky 및 AlmaLinux에서는 배포판에서 기본으로 지원하는 firewalld를 사용하는 것이 좋습니다.
서버 앞단의 제공자 방화벽. 많은 VPS 관리 패널은 별도의 네트워크 방화벽을 제공합니다. --list-all에서 포트가 열려 있는데도 외부 연결이 실패한다면, 서버 설정을 변경하기 전에 관리 패널을 먼저 확인하십시오. 반대의 경우도 마찬가지입니다. 패널에서 규칙을 열어두어도 firewalld가 패킷을 거부하면 연결되지 않습니다.
sudo 없이 firewall-cmd 실행. 모든 변경 사항은 root 권한이 필요합니다. 권한이 없으면 인증 단계에서 요청이 거부되어 아무것도 수정되지 않으며, 명령어 자체가 무시된 것처럼 보일 수 있습니다.
대부분의 작업은 다음 6가지 명령어로 처리할 수 있습니다. 상태를 확인하는 --list-all, 포트를 개방하는 --permanent --add-service 또는 --add-port, 포트를 닫는 --permanent --remove-service, 저장된 파일을 적용하는 --reload, 그리고 실험 후 설정을 확정하는 --runtime-to-permanent입니다. 영역은 public를 사용하고, 플래그는 --permanent를 사용하며, 가장 정확한 연결 확인은 다른 기기에서 직접 수행해야 합니다.
FAQ
재부팅 후 firewalld 규칙이 사라지는 이유는 무엇입니까?
해당 규칙이 런타임 설정에만 적용되었기 때문입니다. sudo firewall-cmd --add-service=http은 즉시 적용되지만 재시작이나 부팅 시에는 삭제됩니다. /etc/firewalld/zones/public.xml에 저장된 설정 파일은 변경되지 않았기 때문입니다. --permanent을 추가한 뒤 sudo firewall-cmd --reload를 실행하십시오. 이미 수동으로 추가한 규칙을 유지하려면 sudo firewall-cmd --runtime-to-permanent을 실행하여 현재 적용된 규칙을 저장된 파일로 복사하십시오.
--permanent 옵션으로 규칙을 추가했는데 왜 아무런 변화가 없습니까?
--permanent은 파일에 내용을 기록할 뿐 실행 중인 방화벽에는 영향을 주지 않기 때문입니다. sudo firewall-cmd --reload를 통해 저장된 설정을 커널에 불러오기 전까지는 포트가 닫힌 상태로 유지됩니다. sudo firewall-cmd --list-services과 sudo firewall-cmd --permanent --list-services를 비교해 보십시오. 저장된 목록에는 항목이 있는데 현재 목록에는 없다면, 설정을 다시 불러오지 않은 것입니다.
--add-service와 --add-port 중 무엇을 사용해야 합니까?
운영 중인 서비스에 정의된 이름이 있다면 --add-service를 사용하십시오. 이는 의도를 명확히 하며, sudo firewall-cmd --info-service=https을 통해 해당 이름이 어떤 포트를 포함하는지 확인할 수 있습니다. 서비스가 정의되어 있지 않거나 표준 포트가 아닌 곳에서 대기 중이라면 --add-port을 사용하십시오. ssh 서비스는 22/tcp 포트만 의미하므로, SSH를 2222 포트로 옮겼다면 --add-port=2222/tcp와 함께 해당 포트에 대한 SELinux 레이블 설정이 필요합니다.
firewall-cmd에서 포트가 닫혀 있는데 왜 Docker 컨테이너에는 접근이 가능합니까?
공개된 포트는 Docker 자체 NAT 규칙에 의해 재작성되어 컨테이너로 전달됩니다. 따라서 패킷이 호스트에 도달하지 않으며, 방화벽 존의 서비스 및 포트 목록은 호스트로 전달되는 패킷에만 적용됩니다. 컨테이너는 외부에서 응답하지만 --list-all에는 아무것도 나타나지 않습니다. docker run -d -p 127.0.0.1:8080:80 nginx을 사용하여 루프백으로만 공개하고, 그 앞에 리버스 프록시를 배치하십시오.
Rocky Linux에서 firewalld 대신 ufw를 설치해도 됩니까?
한 서버에 두 개의 방화벽 관리자를 사용하면 서로의 규칙을 알지 못한 채 설정을 덮어쓰게 되며, 마지막에 시작된 서비스의 규칙만 남게 됩니다. firewalld는 Rocky Linux와 AlmaLinux에서 지원하는 도구이며 이미 설치되어 있습니다. 또한 ufw가 사용하는 것과 동일한 nftables 백엔드를 제어합니다. 기본 존과 --permanent 플래그를 익히면 도구 전체를 충분히 활용할 수 있습니다.