본문 바로가기
IT Security/LINUX Basic

44. Linux 방화벽 제어 - firewall-cmd 개요

by Rosmary 2024. 3. 3.
728x90
반응형

 

 

 

 

 

 

최근 사용하는 대부분의 Linux는 외부 통신을 제어하는 방화벽의 관리를 iptables가 아닌 firewall-cmd라는 명령어로 진행한다.

 

*  iptables 및 방화벽에 대한 기본 개념은 필자가 이전에 작성한 포스팅을 참고하자.

Linux - 리눅스 방화벽1, 방화벽 서비스 및 정책 확인

Linux - 리눅스 방화벽2, 방화벽 정책(chain) 관련 명령어

Linux - 리눅스 방화벽3, 방화벽 규칙(rule)관련 명령어

 

 

위의 포스팅 내용을 보셨던 분들이나, 기존에 iptables 명령어를 사용해보셨던 분들이라면 아시겠지만, iptables는 적용해야하는 옵션이 많고 작성해야하는 명령어 문구가 길기 때문에, 방화벽 규칙을 작성해서 적용하기가 상당히 까다롭다. 이러한 이유로 CentOS6에서 CentOS7으로 넘어가는 시점에서 대부분의 Linux는 방화벽 관리를 firewall-cmd라는 명령어로 조금 더 쉽게(?) 진행할 수 있도록 개선되었다(물론 iptables를 사용하지 못하는 것은 아니다).

 

필자 역시 CentOS에서 iptables만 사용하다가 거의 1년 전부터는 완전히 firewall-cmd로 넘어온 상태다. 하지만, firewall-cmd를 사용하면서도 한 번도 이 기능에 대해 정리할 시간을 갖지 못해왔다. 그래서 자주 사용하지도 않는 firewall-cmd의 고급 기능을 사용할 때마다 구글링을 진행해야 했던 점이 항상 불편했었는데, 최근 시간이 조금 남아도는 김에, firewall-cmd 사용과 관련된 내용을 조금 정리해보려한다. 

 

firewall-cmd 역시 iptables처럼 여러 포스팅으로 나누어 소개하려는데, 이번 포스팅에서는 firewall-cmd의 개요와 정책 테이블 구성을 설명하는 선에서만 진행해보려한다. 본 포스팅의 내용은 Linux에 firewalld 패키지가 설치되어 있다고 가정한다. firewalld 패키지 설치는 아래와 같이 진행한다.

1
2
3
4
5
# RedHat 계열
sudo dnf install firewalld
 
# Debian 계열
sudo apt install firewalld
cs

 

 

 

1. firewalld 서비스

 

linux의 방화벽과 관련된 서비스는 iptables와 firewalld 두 가지가 존재한다. 최근에 많이 사용하는 firewalld의 경우, 내부 Architecture에 iptables가 포함되어 있기 때문에, firewalld를 사용한다고 해서 iptables의 기능을 사용하지 못하는 것은 아니다. 따라서 firewalld 서비스를 dnf (구 yum)으로 설치하면 자동으로 의존성을 참조하여 iptables도 설치하게 된다.

 

firewalld는 iptables를 의존하고 있음을 위의 명령어로 확인할 수 있다.

 

 

물론, iptables 기능을 활용할 수 있도록 만든 것이기 때문에 CentOS6나 CentOS7과 달리 최근 Linux Distro인 CentOS8이나 Ubuntu 22, 23은 iptables 기본 chain에 정책이 설정되어 있지 않다. 즉, iptables는 모든 통신을 허용하는 것을 기본 값으로 가진다. 

 

보안 종사자들이 가장 경기를 일으키는 Any Accept 방화벽 정책이다...

 

 

하지만 firewalld  서비스가 iptables와 동시에 설치되어 있다면 iptables의 규칙을 보기 전에 firewalld의 규칙을 먼저 확인하게 된다. 즉, 외부의 통신이 Linux 방화벽에 도달하면, firewalld -> iptables 순으로 정책 테이블의 정책을 검증하게 된다. 만약 firewalld에서 tcp/443에 대한 통신을 방어한다면, iptables에서는 아무리 전체 chain을 ACCEPT로 허용한다고 하더라도 외부에서 Linux의 웹 서버와 통신을 진행할 수 없게 된다.

 

PostgreSQL에 대한 내부 및 외부 접속 시도. 외부 접속 설정은 이미 0.0.0.0/0 trust로 설정한 상태다.

 

 

위의 예시를 보면 알 수 있는데, 현재 필자의 Linux는 PostgreSQL 서비스가 동작 중이라 Linux에서 직접 접속은 가능한 상태이지만, 외부에서 Linux의 PostgreSQL 접속 시, 우측처럼 외부의 요청([S]- Syn)만 있을 뿐, Linux에서 어떠한 응답(Ack, Syn-Ack)도 돌려주지 않음을 확인할 수 있다. 좌측의 firewall-cmd 명령어 결과를 보면 알겠지만, 현재 필자의 방화벽은 SSH를 제외한 나머지 서비스에 대한 INBOUND 통신(Linux 내부로 유입되는 통신)을 모조리 무시하고 있기 때문이다.

 

방화벽에 PostgreSQL과 관련된 통신 포트를 허용한다고 추가하면 방금 전과 달리, 외부에서의 통신도 정상적으로 진행되는 것을 알 수 있다.

 

 

 

물론, 이 통신 역시 iptables에서 차단한다면 다시 접속이 진행되지는 않는다. 

 

 

 

2. iptables보다 firewall-cmd를 사용하는 이유

 

firewall-cmd 이전에 사용했던 iptables로 잠깐 넘어가보자. iptables는 크게 Chain이라는 카테고리로 정책 테이블이 구분되어 있다. 이 Chain은 기본값으로 INPUT, OUTPUT, FORWARD 세 가지로 구성되어 있으며 각각 Inbound, Outbound, Forward 트래픽에 대한 정책을 정의한다. 그런데 iptables의 chain은 정책을 구성하기가 상당히 까다로운데, 외부에서 들어오는 트래픽도 어디에서 들어오느냐에 따라 Chain 밑에 하위 chain을 만들어 관리해야하기 때문이다.

 

 

 

위의 Shell 코드는 필자가 iptables 자동화를 위해 작성한 프로그램의 결과물이다 - 여러 시행착오를 거치면서 가장 관리하기 편한 폼으로 만든 것이다.. - 자세히 보면 INPUT, OUTPUT에 대한 하위 Chain을 KT__External인 Chain과 KT__INTERNAL인 Chain으로 나뉘어 작성한 것을 볼 수 있다. 저 External과 Internal은 필자의 Linux 네트워크와 연결된 Zone을 의미한다. 구성은 아래와 같다.

 

 

공유기 내부를 Internal Zone(172.30.1.0/24)로 지정하고, 그 외에는 External Zone으로 지정하여 별도로 정책을 설정하는 컨셉인데, Zone 하나에 INPUT과 OUTPUT 체인 두 개를 동시에 설정해야 하기 때문에 관리해야하는 체인의 수가 Zone * 2만큼 늘어난다. - 만약 필자 Linux에서 FORWARD 트래픽까지 관리한다면 Zone * 3만큼 Chain이 늘어나게 된다 - 위의 예시는, 필자가 개인적으로 사용하는 VM이니 망정이지, Interface 수가 최소 4개인데다 Zone도 많은 실제 운영 서버인 경우에는 Linux iptables로 정책 구성하려면 여러모로 관리가 어려울 수 밖에 없다.

 

또한 최근의 Linux 기반 서버 제품의 경우에는, 방화벽 제품이 아닌 이상 거의 말단에 위치하고 있기 때문에 iptables를 사용한 정책 구성이 오히려 불편할 수 밖에 없다. Linux의 방화벽 역할은 보통 서버가 위치한 Zone의 앞단에 방화벽 제품을 놓고 통신을 제어하는 경우가 대부분이다보니, Linux 내 iptables는 서비스 제공과 관련된 포트만 오픈해주면 된다. 그런데 iptables는 앞서 말했듯이 정책을 추가하려면 INPUT과 OUTPUT으로 나누어 정책을 2개나 설정해야하기 때문에 효율성 측면에서 볼 때 좋은 구성은 아니다. 

1
2
3
4
5
# PostgreSQL에 대한 INBOUND 규칙
iptables -A INPUT -p tcp --dport 5432 -m state --state NEW -j ACCEPT
 
# PostgreSQL에 대한 OUTBOUND 규칙
iptables -A OUTPUT -m state --state ESTABLASHED,RELATED -j ACCEPT
cs

 

 

firewall-cmd는 iptables의 이러한 불편한 점을 개선하여, 정책 테이블의 최상위 분류를 Chain이 아닌 Zone으로 구분하도록 만들어놓았다. 그리고 각 Zone에 Zone과 연결되는 Interface를 지정하도록 하며, 해당 Zone에서 허용된 서비스나 포트만 통신을 허용한다. iptables에서 두 줄이나 작성해야 했던 방화벽 설정 명령어는 firewall-cmd에서 아래의 단 한 줄로 마무리할 수 있다.

1
2
# PostgreSQL에 대한 firewall-cmd 규칙
firewall-cmd --add-port=5432/tcp
cs

 

 

 

3. firewall-cmd의 정책 테이블 구성

 

firewall-cmd는 Chain이 가장 상위에 존재하는 iptables와 달리, zone이 정책의 테이블 최상단에 존재한다. 

 

 

firewall-cmd는 위와 같이 external과 internal외에도 public 등 약 10여개의 Zone을 기본값으로 제공한다. 초기 설정에서는 public zone이 default zone으로 설정되어 있기 때문에, 외부에서 들어오는 모든 Traffic은 별도의 설정이 이루어져 있지 않은 경우 default zone의 정책을 지나가게 된다.

 

 

 

zone의 내용을 자세히 보면, target과 interface를 명시하는 부분이 있는데, target은 zone의 기본 동작을 명시하며, interface는 zone과 연관된 Linux의 NIC를 지정하는 부분이라 보면 된다. 만약 drop zone에 interface1이 지정되어 있고, interface1로부터 들어온 통신 패킷이 있다면, 이 패킷은 public zone이 아닌, drop zone을 먼저 거치게 된다. 

 

또한 각 zone의 target은 zone 내부에 명시되지 않은 port나 service에 대한 처리 로직을 담당한다. iptables의 Policy와 동일한 개념인데, target이 default인 경우, 명시되지 않은 통신을 차단(Drop), accept인 경우 모두 허용, drop인 경우 zone 내에 규칙이 명시되었더라도 모두 차단(Drop)한다. 이 부분은 조금 뒤에서 정리를 하고...

 

필자의 Linux는 현재 ens33, ens34라는 interface가 존재하며, ens33은 공유기와 직접 연결되는 Bridge 대역을, ens34는 NAT 대역을 사용하고 있다. 따라서 필자의 Linux IP인 192.30.1.3과 172.30.1.53 둘 다, 현재는 public zone을 통해 통신이 진행되기 때문에, 문제 없이 SSH 접속이 가능한 상태다(services에 ssh가 추가되어 있기 때문에 문제가 없다).

 

 

이 상태에서 필자가 ens33 interface를 Drop zone으로 지정하게 되면, 이전과 달리 172.30.1.0 대역대로는 SSH 접속이 허용되지 않게 된다.

 

 

 

이번에는 반대로, Trusted zone에 ens33을 위치시켜보려한다. Trusted zone은 Drop zone과 달리 target이 accept로 설정되어 있기 때문에, zone 내에 SSH 서비스를 사용한다고 명시하지 않더라도 ens33을 통해 들어오는 모든 통신 패킷을 허용하게 된다.

 

 

 

firewall-cmd의 정책 원칙을 정리하면 아래와 같다.


   1. 통신 패킷은 반드시 하나의 Zone을 통해 들어온다 - INBOUND

   2. 통신 패킷은 반드시 하나의 Zone을 통해 나간다 - OUTBOUN.

   3. 하나의 Zone은 신뢰 레벨, 즉 target이 정의되어 있다.

   4. Linux NIC(interface)는 하나의 Zone에만 소속될 수 있으며,

       소속된 경우 해당 NIC로 유입된 패킷은 NIC가 소속된 Zone의 정책으로 통신을 검증한다.

   5. NIC가 어느 Zone에도 소속되지 않으면, default zone의 정책으로 통신을 검증한다.


 

정책 원칙의 3번에서 target은 accpet, reject, drop, default 네 가지가 있다.

target 설명
accept 해당 zone을 거치는 모든 통신 packet 허용
drop 해당 zone을 거치는 모든 통신 packet 차단(drop)
%%reject%% 해당 zone을 거치는 모든 통신 중, firewall-cmd에 명시된 %%reject%% 통신에 대해서 거절(deny).
기본적으로 ICMP 통신에 대해 거절하도록 설정되어 있다.
default 해당 zone에 명시된 통신 packet만 허용하고 나머지는 차단(drop)

 

 


 

다음 포스팅에서는 위 내용을 바탕으로 zone 내부에 정책을 구성하는 기본적인 명령어에 대해 알아보려 한다.

 

 

END.

 

 

 

 

 

반응형

댓글