본문 바로가기
IT Security/LINUX Basic

45. Linux 방화벽 제어 - firewall-cmd, Zone 내부 정책 생성

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

 

 

 

 

지난 포스팅에서는 firewall-cmd가 탄생한 배경과, firewall-cmd 정책 테이블의 구성에 대해 아주 간략하게 알아보았다. 이번 포스팅에서는 Zone 내부에 정책을 직접 설정하고 통신의 진행 여부를 확인해보려한다.

 

 

 

1. Zone 관련 정보 조회

 

정책을 생성하려면, Linux 방화벽에 어떤 Zone이 존재하고 있는지 파악하는 것이 선행되어야한다. 물론, 필자가 이전 포스팅에서 언급한대로 대부분의 Linux 기반 솔루션은 네트워크 말단에 위치하기 때문에 굳이 Zone에 Interface를 할당하지 않고 public에 필요한 서비스와 포트에 대한 정책을 만들어 사용하는 방법을 많이 사용하지만, 다른 서버와의 연동이 필요하거나, 조금 복잡한 구성을 진행해야하는 경우라면, Zone을 구분하여 정책을 관리하는 방향이 좋기 때문이다.

 

 

(1)  firewall-cmd 관리 Zone 이름 전체 조회

 

Linux 방화벽의 전체 Zone 이름을 조회하는 방법은 아래와 같다.

1
2
3
# firewall-cmd 전체 Zone 이름 조회
 
firewall-cmd --get-zones
cs

 

위의 명령어로 Zone 정보를 조회하면, firewall-cmd에서 관리하는 zone의 이름이 한 줄로 출력된다. 

 

 

기본적으로 제공되는 이 Zone은 외부 통신에 대한 신뢰를 얼마나 할 수 있느냐에 따라 아래와 같이 나열될 수 있다.

1
2
3
<<-- 신뢰도 낮음                          신뢰도 높음 -->
 
drop block public external internal dmz work home trusted
cs

 

따라서 특정 Interface가 믿을 수 있는 Network와 연결된 경우, 위의 목록에서 상대적으로 우측에 위치한 Zone을 할당하며, 그렇지 않은 경우에는 좌측에 위치한 Zone들을 할당한다 (아무리 신뢰할 수 있어도 DMZ 이상의 Zone은 일반 기업에서는 거의 사용하지 않을 듯 하다. 뭐... 애초에 Linux 방화벽은 쓰지도 않겠지만).

 

그런데, 위의 명령어로 Zone의 이름 목록까지는 확인했지만, 어떤 Zone이 Default Zone의 역할을 하는지는 이 명령어로 알 수 없다. 

 

 

(2) Default로 설정된 Zone 이름 확인

 

1
2
3
# firewall-cmd Default Zone 정보 조회
 
firewall-cmd --get-default-zone
cs

 

이 때 사용하는 firewall-cmd 옵션이 --get-default-zone이다. 이 명령어는 현재 firewall-cmd가 Default로 지정한 Zone에 대한 이름만 별도로 추출하도록 하는 명령어다.

 

현재는 Default Zone이 public으로 설정되어 있고, 필자의 Linux NIC는 어떠한 Zone에도 지정되지 않았기 때문에, Linux로 들어오는 모든 Packet은 public zone의 정책 테이블을 거치게 된다.

 

만약 이 Default Zone을 변경하고 싶다면 어떻게 하면 될까?

 

 

(3) Default Zone의 변경

1
2
3
# firewall-cmd Default Zone 
 
firewall-cmd --set-default-zone=[Zone_name]
cs

 

firewall-cmd에서 제공하는 --set-default-zone 옵션은 Default Zone을 변경하는 기능을 가진다. 이 명령어로 Zone을 변경하는 즉시, 외부 통신이 참조하는 테이블이 변경된다. 한 번 테스트 해 보자.

 

현재 필자는 Linux에 ens33, ens34라는 interface가 존재하며, 각각 대역대는 172.30.1.0/24, 192.30.1.0/24를 담당한다. PublicZone이 Default인 경우에는 아무 문제 없이 두 대역대로 SSH 가능한 상태다. 우선 ens33과 ens34 모두 어느 Zone에도 할당되지 않은 상태라, 모두 Default인 Public Zone의 정책을 참고하기 때문이다.

 

 

 

이제 필자는 ens34, 192.30.1.0/24 대역대만 public zone으로 지정하도록 한 뒤, Default Zone을 Drop으로 변경해보려한다. 이렇게 설정이 되면, 192.30.1.0/24 대역으로는 SSH 접속이 정상적으로 이루어지지만, 172.30.1.0/24는 포트가 열리지 않아 SSH 접속을 진행할 수 없게 된다.

 

public에 ens33을 지정하지 않았다면 192.30.1.0/24 대역도 접속이 불가해진다.

 

 

ens33을 public zone에 지정하지 않더라도 현재 SSH 접속이 이루어져 있는(Established) 통신에는 지장이 없다. 그 대신 현재 열린 Putty를 종료하게된다면, 새 세션에서는 접속이 불가하기 때문에 직접 VM Console에서 Default Zone 설정을 public이나 기타 Zone으로 풀어야 한다.

 

 

(4) 각 Zone의 세부 정책 확인

 

원래대로 Default Zone을 public으로 다시 설정하자. 그럼 여기서 의문이 든다.

 

"Zone에 Interface도 할당하고, 조금 더 나아가면 허용할 통신 포트나 서비스 정보도 할당하는데, 이런 정보는 어떻게 보나요?"

1
2
3
#  Zone 세부 정책 설정 확인
 
firewall-cmd --list-all  {--zone=[zone_name]}
cs

 

 

--list-all 옵션은 특정 Zone의 세부 설정 정보를 보여준다. 단, --zone이 명시되지 않는다면 Default Zone의 세부 정보를 보여준다.

 

 

 

 

(5) 전체 Zone 세부 정보 확인하기

 

그런데, firewall-cmd는 약 10개 가까이 되는 Zone을 가지고 있다보니, --list-all 옵션으로 Zone을 하나씩 검색하면서 전체 세부 정책 정보를 보는 것이 여간 시간을 잡아먹는 일이다. 다행히 firewall-cmd는 --list-all-zones라는 옵션으로 firewall-cmd가 관리하는 모든 Zone의 세부 설정 정보를 조회할 수 있도록 지원하고 있다.

1
2
3
#  전체 zone 세부 정책 설정 확인
 
firewall-cmd --list-all-zones
cs

 

명령어 결과가 조금 길게 출력되니, more이나 less명령어를 pipe와 함께 사용하도록 하자.

 

Zone 정보에 대한 조회는 이것이 끝이다. 이제 각 Zone에 정책을 만드는 방법에 대해 알아보자.

 

 

 

2. Zone 내부에 정책 생성 및 삭제: --add, --remove 옵션

 

이제 본격적으로 정책을 생성해보자. Zone 내부에 허용할 정책을 생성하는 것은 - iptables와 비교했을 때 - 매우 간단하다. 단순히 해당 Zone으로 들어오는 통신에 대해 특정 포트만 오픈시키는 것 뿐만 아니라, 출발지 IP를 기준으로 나눌지, 아니면 서비스를 등록해서 정책을 만들지 등등등 정책을 만드는 방식도 다양하게 진행할 수 있다.

 

Zone 세부 정보를 나타나면 보이는 주요 값들은 대부분 --add와 --remove 옵션을 사용하여 설정을 변경할 수 있다. 예를 들어 Zone 내부에 interface를 등록하거나 삭제하려면, --add-interface / --remove-interface 옵션을 사용하면 되고, 포트를 추가하거나 삭제한다면 --add-port, --remove-port 옵션을 사용하면 된다.

 

port 정책부터 예를 들어보자. 현재 필자의 Linux에는 Apache 서버가 돌고 있는데, 외부에서 웹 브라우저로 접속하려고 하면 방화벽 내에 허용된 정책이 없어서 접속이 거부된다는 문구만 출력된다.

localhost에서는 포트가 열린 것이 확인되나, 외부에서는 접근이 불가한 것으로 보아 Linux의 방화벽 정책 문제다.

 

 

현재 필자의 HTTPD 서비스는 SSL이 적용되지 않아 TCP/80으로 통신을 한다. 따라서 Interface가 어느 Zone에도 지정되지 않은 현재는 웹 접근 통신이 public zone의 정책을 참조하므로, Public Zone에 TCP/80 포트에 대한 허용 정책을 생성해주어야 한다. 이를 위해 아래의 명령어로 통신을 진행할 Port를 Zone에 추가하면 된다.

1
2
3
# Zone 내부 포트 정책 추가
 
firewall-cmd --add-port=[포트번호]/[프로토콜] { --zone=[정책을 적용할 zone_name] }
cs

 

포트 정보를 입력할 때에는 일반적인 프로토콜 명시 방법과 달리, 포트번호/프로토콜 형태로 값을 입력한다.

 

반대로 Zone에서 해당 포트의 정보를 다시 삭제하려면 --remove-port 옵션을 사용하면 된다.

1
2
3
# Zone 내부 포트 정책 삭제
 
firewall-cmd --remove-port=[포트번호]/[프로토콜] { --zone=[포트를 삭제할 zone_name] }
cs

 

 

위의 내용을 적용하여 웹을 브라우저에서 접속할 수 있도록 만들어보자. 통신이 정상적으로 진행되면 다시 삭제를 하여 통신이 차단되는지 확인해보자.

 

 

 

port와 마찬가지로 Zone 내부에 있는 interface, source, service, protocol 등의 값들은 모두 이런 방식으로 Zone 정책을 설정하고 삭제한다.

 

 

 

조금 실수하기 쉬운 것이 하나 있는데, Public Zone에서는 Interface가 허용 정책으로 명시되어 있다면, 해당 Interface를 통해 들어오는 통신 중 세부 대역대만 허용하지 못한다는 것이다. 예를 들어, 필자가 192.30.1.0/24 대역대의 192.30.1.1 IP만 source에 추가한다고 하더라도, interface에서 이미 대역대를 허용하고 있기 때문에 192.30.1.1을 제외한 나머지 동일 대역대의 IP도 모두 허용된 포트로 접속이 가능하다는 것이다.

 

두 번째 Linux는 192.30.1.4 IP를 가지며, 윈도우는 192.30.1.1이다.

 

 

위의 결과에서도 확인할 수 있듯이, interface가 192.30.1.0/24 대역대로 설정된 마당이라 source를 동일 대역대로 설정하더라도 해당 IP 외 동일 대역의 다른 IP가 접근하는 것은 막을 수가 없다 (물론, 172.30.1.0/24 대역은 interface가 지정되지 않아 통신이 차단된다). 만약 interface 없이 source만 추가하더라도,  interface가 지정되지 않은 경우, default zone의 정책을 따른다는 firewall-cmd의 Zone 원칙에 따라, Linux로 들어오는 모든 통신이 Zone에 허용된 포트로 모두 접근이 가능하게 된다. 

 


 

 

지금까지의 내용을 보면, Zone 내부에 source는 전혀 불필요한 내용처럼 보인다. 그럼, IP를 세분화하여 통신을 차단하거나 허용하는 방법은 firewall-cmd에서는 불가능한 것일까? 사실 필자도 보안 분야에 일을 하면서 firewall-cmd를 사용해보긴 했지만, 대부분의 통신 차단은 전문 방화벽 장비가 Endpoint나 네트워크 앞 단에서 동작하기 때문에 포트 정도만 허용하는 선에서 이용했지, IP까지 세세하게 차단해 본 적은 없다. 그러나 기능을 안 썼을 뿐, 방법은 있다.

 

다음 포스팅에서는 firewall-cmd의 rich-rule에 대해 알아보려 한다.

 

 

END.

 

 

 

 

 

 

반응형

댓글