CentOS 7부터는 트래픽 필터링 규칙을 구성하기 위해 FirewallD가 도입되었습니다. iptables 규칙을 관리할 때 권장되는 도구입니다. CentOS 8에서는 기존의 표준 iptables 패킷 필터링 서비스 대신 nftables 프레임워크를 사용하며, firewalld에서 방화벽 규칙을 설정하면 실제로는 nftables가 구성됩니다. 이 글에서는 Linux CentOS 8(및 CentOS 7)이 설치된 서버에 firewalld를 설치하고 설정하는 방법과 이 방화벽의 핵심 개념들을 살펴보겠습니다.
Firewalld 기본 개념: 존(Zone)과 규칙(Rule)
firewalld를 설치하고 설정하기 전에, 먼저 다양한 연결에 대한 신뢰 수준을 결정하는 데 사용되는 '존(zone)' 개념을 이해해야 합니다. 각 firewalld 존에는 서로 다른 필터링 규칙을 적용할 수 있으며, 사전 정의된 서비스·프로토콜·포트에 대한 활성 방화벽 옵션 설정, 포트 포워딩, 리치 룰(rich rule) 등을 지정할 수 있습니다.
Firewalld는 존에 적용된 규칙에 따라 인바운드 트래픽을 필터링합니다. 발신자 IP 주소가 특정 존의 규칙과 일치하면 해당 패킷은 그 존을 통해 처리됩니다. 서버에 구성된 어떤 존과도 일치하지 않으면 기본 존(default zone)이 패킷을 처리하며, firewalld를 처음 설치했을 때 기본 존은 public입니다.
Firewalld는 다양한 서비스에 대해 미리 권한이 구성된 여러 존을 제공합니다. 이러한 기본 설정을 그대로 사용하거나 자신만의 존을 새로 만들 수도 있습니다. firewalld 설치 시 생성되는 기본 존 목록(/usr/lib/firewalld/zones/ 디렉터리에 위치)은 다음과 같습니다.
| drop | 신뢰 수준이 가장 낮은 존입니다. 모든 인바운드 연결이 응답 없이 차단되며 아웃바운드 연결만 허용됩니다. |
| block | 앞선 drop 존과 유사하지만, 들어오는 요청이 IPv4의 경우 icmp-host-prohibited, IPv6의 경우 icmp6-adm-prohibited 메시지와 함께 거부됩니다. |
| public | 공개적이고 신뢰할 수 없는 네트워크에 사용됩니다. 들어오는 연결을 개별적으로 허용할 수 있습니다. |
| external | 방화벽이 게이트웨이 역할을 할 때 외부 네트워크에 사용됩니다. NAT 마스커레이딩에 활용되어 내부 네트워크는 비공개로 유지되면서도 접근 가능하게 됩니다. |
| internal | external 존의 반대 개념으로, 호스트에 대한 신뢰 수준이 높아 추가적인 여러 서비스에 접근할 수 있습니다. |
| dmz | 비무장지대(DMZ)에 있는 컴퓨터에 사용되며, 내부 네트워크에는 접근할 수 없는 격리된 컴퓨터들이 포함됩니다. 선택된 일부 인바운드 연결만 허용됩니다. |
| work | 업무용 컴퓨터를 위한 존으로, 네트워크상 대부분의 컴퓨터가 신뢰됩니다. |
| home | 가정용 네트워크에 해당합니다. 대부분의 컴퓨터를 신뢰할 수 있지만, 선택된 일부 인바운드 연결만 허용됩니다. |
| trusted | 네트워크상의 모든 컴퓨터를 신뢰합니다. 가장 개방적인 옵션이므로 신중하게 사용해야 합니다. |
Firewalld는 영구(permanent) 규칙과 런타임(runtime) 규칙 두 가지 세트의 규칙을 사용합니다. 런타임 규칙은 서버가 재시작될 때까지 유효하며, 기본적으로 firewalld에 추가하는 규칙은 런타임 규칙으로 간주됩니다. 영구 규칙을 추가하려면 --permanent 플래그를 사용해야 하며, 이렇게 추가된 규칙은 서버 재시작 후에도 적용됩니다.
CentOS에서 FirewallD 설치 및 활성화하기
CentOS 7/8에서는 OS 설치 과정에서 firewalld가 기본적으로 함께 설치됩니다. 만약 firewalld를 삭제했다면 표준 yum/dnf 패키지 관리자를 통해 다시 설치할 수 있습니다.
# yum install firewalld -y — CentOS 7# dnf install firewalld -y — CentOS 8
firewalld 데몬이 부팅 시 자동으로 시작되도록 하려면 시스템 시작 프로그램에 등록합니다.
# systemctl enable firewalld
그리고 서비스를 시작합니다.
# systemctl start firewalld
서비스 상태를 확인하려면 다음 명령어를 실행합니다.
# 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 명령어는 nftables/iptables의 firewalld 프런트엔드(front-end) 역할을 하는 도구입니다.
running
FirewallD 규칙 관리하기
기본 FirewallD 규칙 확인
firewalld 규칙을 설정하기 전에, 현재 기본값으로 어떤 존이 사용되고 있는지 먼저 확인해야 합니다.
# firewall-cmd --get-default-zone
방금 firewalld를 설치하고 아직 설정하지 않았으므로 기본 존은 public입니다.
다음으로 활성 존(active zone)을 확인합니다. 현재는 public이라는 동일한 하나의 존만 있습니다.
# firewall-cmd --get-active-zones
public interfaces: eth0
보시다시피 eth0 인터페이스가 public 존에 의해 관리되고 있습니다.
CentOS의 네트워크 인터페이스 목록은 다음 명령어로 확인할 수 있습니다.
# ip link show
또는:# nmcli device status
활성 존의 규칙을 보려면 다음 명령어를 사용합니다.
# 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:
이 출력 결과에서 DHCP 클라이언트와 SSH 관련 공통 작업이 해당 존에 추가되어 있는 것을 확인할 수 있습니다.
사용 가능한 존 조회하기
모든 존의 목록을 보려면 다음 명령어를 실행합니다.
# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
특정 존의 규칙을 보려면 --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:
모든 존의 규칙을 한 번에 볼 수도 있습니다.
# firewall-cmd --list-all-zones
기본 존 변경하기
기본적으로 모든 네트워크 인터페이스는 public 존에 속하지만, 다음 명령어로 원하는 존으로 이동시킬 수 있습니다.
# firewall-cmd --zone=home --change-interface=eth0
--zone= 파라미터 뒤에 원하는 존 이름을 지정하면 됩니다.
기본 존을 home으로 변경하려면 다음 명령어를 실행합니다.
# firewall-cmd --set-default-zone=home
FirewallD에 애플리케이션 규칙 추가하기
특정 애플리케이션의 포트를 열려면 해당 서비스를 예외로 추가할 수 있습니다. 사용 가능한 서비스 목록을 표시하는 방법은 다음과 같습니다.
# firewall-cmd --get-services
출력 결과에는 많은 서비스가 포함됩니다. 각 서비스에 대한 상세 정보는 해당 서비스의 XML 파일에 담겨 있으며, 이 파일들은 /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...</description> <port protocol="tcp" port="25"/> </service>
XML 파일에는 서비스 설명과 firewalld에서 열릴 프로토콜 및 포트 번호가 포함되어 있습니다.
규칙을 추가할 때는 --add-service 파라미터를 사용하여 특정 서비스에 대한 방화벽 접근을 허용할 수 있습니다.
# firewall-cmd --zone=public --add-service=http
# firewall-cmd --zone=public --add-service=https
규칙을 추가한 후에는 서비스가 지정된 존에 올바르게 등록되었는지 확인할 수 있습니다.
# firewall-cmd --zone=public --list-services
dhcpv6-client http https ssh
규칙을 영구적으로 유지하려면 추가할 때 --permanent 파라미터를 함께 사용해야 합니다.
존에서 서비스를 제거하려면 다음과 같이 합니다.
# firewall-cmd --permanent --zone=public --remove-service=http
# firewall-cmd --zone=public --permanent --list-services
dhcpv6-client https ssh test
목록에 없는 자체 서비스를 예외로 추가하고 싶다면 XML 파일을 직접 생성하여 데이터를 지정할 수 있습니다. 기존 서비스의 내용을 복사한 뒤 이름, 설명, 포트 번호만 변경하면 됩니다.
smtp.xml 파일을 사용자 서비스 디렉터리로 복사합니다.
# cp /usr/lib/firewalld/services/smtp.xml /etc/firewalld/services
파일 안의 서비스 설명을 수정합니다. XML 파일명도 변경해야 하며(여기서는 서비스 이름을 test로 지정했습니다), 이후 firewalld를 재시작하고 서비스 목록에 나타나는지 확인합니다.
# firewall-cmd --get-services
syslog-tls telnet test tftp
이제 이 서비스를 원하는 존에 추가할 수 있습니다.
# firewall-cmd --zone=public --add-service=test --permanent
# firewall-cmd --zone=public --permanent --list-services
dhcpv6-client http https ssh test
원하는 서비스가 목록에 없다면 다음 명령어로 firewalld에서 직접 포트를 열 수 있습니다.
# firewall-cmd --zone=public --add-port=77/tcp — TCP 77번 포트를 엽니다.# firewall-cmd --zone=public --add-port=77/udp — UDP 77번 포트를 엽니다.# firewall-cmd --zone=public --add-port=77-88/udp — UDP 77~88번 포트 범위를 엽니다.# firewall-cmd --zone=public --list-ports — 허용된 포트 목록을 표시합니다.
ICMP 요청을 차단하거나 허용하려면 다음 명령어를 사용합니다.
# firewall-cmd --zone=public --add-icmp-block=echo-reply
# firewall-cmd --zone=public --remove-icmp-block=echo-reply
추가한 포트를 제거하려면 다음과 같이 합니다.
# firewall-cmd --zone=public --remove-port=77/udp — UDP 77번 포트의 런타임 규칙을 제거합니다.
# firewall-cmd --permanent --zone=public --remove-port=77/udp — 영구 규칙을 제거합니다.
FirewallD에서 새로운 존 만들기
자신만의 존을 직접 만들 수도 있습니다(여기서는 our라는 이름으로 생성).
# firewall-cmd --permanent --new-zone=our
새로운 존을 만든 후에는, 서비스를 만들 때와 마찬가지로 firewalld를 재시작해야 합니다.
# firewall-cmd --reload
# firewall-cmd --get-zones
block dmz drop external home internal our public trusted work
이제 our 존을 사용할 수 있으며, 여기에 서비스를 추가하거나 포트를 열 수 있습니다.
Firewalld로 IP 주소 차단 및 예외 처리하기
firewalld에서 신뢰할 수 있는 IP 주소를 예외 목록에 추가하거나, 원치 않는 IP 주소를 차단할 수 있습니다.
예를 들어 8.8.8.8 같은 IP 주소를 서버의 예외 목록에 추가하려면 다음 명령어를 실행합니다.
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="8.8.8.8" accept'
존을 확인하여 해당 IP 주소가 리치 룰(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
IP 주소를 차단하려면 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
특정 서비스가 오직 지정된 IP 주소에서만 요청을 받도록 허용할 수도 있습니다.
# firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="192.168.1.0/24" service name="https" accept'
서버로 향하는 모든 요청을 즉시 차단해야 한다면 panic 명령어를 사용하세요.
# firewall-cmd --panic-on
panic 모드는 다음 명령어로 해제할 수 있습니다.
# firewall-cmd --panic-off
또는 서버를 재시작해도 됩니다.
root 권한을 가진 로컬 서비스가 생성된 방화벽 규칙을 변경하지 못하도록 firewalld 설정을 잠글 수도 있습니다.
# firewall-cmd --lockdown-on
lockdown 모드를 해제하려면 다음 명령어를 사용합니다.
# firewall-cmd --lockdown-off
FirewallD로 포트 포워딩 설정하기
firewalld에서 포트 포워딩(port forwarding) 규칙을 만들 수 있습니다. TCP 443번 포트를 9090번으로 포워딩하려면 다음 명령어를 사용합니다.
# firewall-cmd --zone=public --add-forward-port=port=443:proto=tcp:toport=9090 --permanent
포트 포워딩 규칙을 제거하려면 다음과 같이 합니다.
# firewall-cmd --zone=public --remove-forward-port=port=443:proto=tcp:toport=9090