시스템 보안 · 취약점 › A. Linux 서버 보안 설정 · 15/50편 (전체 015/450)
학습 단계: 2단계 · 설정 및 점검
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
firewalld는 zone(신뢰 수준별 규칙 묶음) 단위로 정책을 관리합니다. 패킷이 들어오면 먼저 "어느 zone에 속하는가"를 결정하고, 그 zone의 규칙을 적용합니다.
들어온 패킷
↓
① 출발지 IP가 zone의 source에 등록돼 있나? → 있으면 그 zone
② 아니면, 들어온 인터페이스가 속한 zone → 예: ens160 → public
↓
zone 규칙 적용 (services / ports / rich rules)
↓
허용 or 거부(LogDenied 설정 시 커널 로그 기록)
이 구조를 이용하면 trusted 대신 관리 전용 zone을 만들어 SSH는 관리망에서만, 웹은 모든 곳에서 허용하는 설계가 가능합니다.
LogDenied=off), 탐지에 쓰려면 별도 설정이 필요합니다.| 명령 | 용도 |
|---|---|
firewall-cmd --get-active-zones | 활성 zone과 인터페이스/source |
firewall-cmd --list-all --zone=public | zone의 허용 서비스·포트 |
firewall-cmd --list-all --permanent --zone=public | 영구 설정(런타임과 비교) |
firewall-cmd --get-log-denied / --set-log-denied=all | 차단 로그 설정 |
firewall-cmd --direct --get-all-rules | direct 규칙(우회 경로) 확인 |
# 1) 관리 zone 생성: 관리망에서만 SSH 허용
sudo firewall-cmd --permanent --new-zone=mgmt
sudo firewall-cmd --permanent --zone=mgmt --add-source=192.168.56.0/28
sudo firewall-cmd --permanent --zone=mgmt --add-service=ssh
# 2) public에서는 SSH 제거, 웹만 허용
sudo firewall-cmd --permanent --zone=public --remove-service=ssh
sudo firewall-cmd --permanent --zone=public --add-service=http
# 3) 차단 로그 활성화 후 적용
sudo firewall-cmd --set-log-denied=unicast
sudo firewall-cmd --reload
# 4) 런타임 vs 영구 설정 비교 (차이가 있으면 누군가 런타임만 바꾼 것)
diff <(sudo firewall-cmd --list-all --zone=public) <(sudo firewall-cmd --list-all --zone=public --permanent)
실습은 반드시 VMware 콘솔에 접속한 상태에서 진행합니다. SSH 세션에서 SSH 허용을 지우면 접속이 끊길 수 있습니다.
$ sudo firewall-cmd --get-active-zones
mgmt
sources: 192.168.56.0/28
public
interfaces: ens160
$ sudo firewall-cmd --list-all --zone=public | grep -E 'services|ports'
services: http
ports:
런타임과 영구 설정의 diff 결과가 없어야 정상입니다.
$ diff <(firewall-cmd --list-all --zone=public) <(firewall-cmd --list-all --zone=public --permanent)
< ports: 4444/tcp
---
> ports:
4444/tcp가 열려 있음 → 재부팅/reload 시 사라지는 일시적 개방LogDenied를 켜면 차단 패킷이 커널 로그로 남고, firewalld 설정 변경은 auditd·journal로 추적합니다(가상의 예시 로그).
Oct 1 09:15:02 rocky9-web01 kernel: filter_IN_public_REJECT: IN=ens160 OUT= MAC=00:0c:29:aa:bb:cc:00:0c:29:11:22:33:08:00 SRC=192.168.56.77 DST=192.168.56.10 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=40121 DF PROTO=TCP SPT=51544 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0
Oct 1 09:20:31 rocky9-web01 sudo[7301]: admin1 : TTY=pts/0 ; PWD=/root ; USER=root ; COMMAND=/usr/bin/firewall-cmd --add-port=4444/tcp
| 필드 | 의미 |
|---|---|
filter_IN_public_REJECT | public zone 인바운드 거부 |
SRC/DST/DPT=22 | 외부(비관리망)에서 SSH 시도 → zone 설계대로 차단됨 |
SYN | 연결 시작 패킷 |
--add-port (permanent 없음) | 런타임 전용 개방 명령 |
차단 로그 형식은 iptables LOG와 같아 네트워크 영역의 271. Firewall Logging에서 다룬 분석 방법을 그대로 적용할 수 있습니다.
firewall-cmd의 --add-*, --remove-*, --set-default-zone, --direct 실행은 모두 수집합니다.<rule id="100220" level="9">
<if_sid>5402</if_sid>
<regex type="pcre2">COMMAND=\S*firewall-cmd .*--add-port|COMMAND=\S*firewall-cmd .*--direct|COMMAND=\S*firewall-cmd .*--add-rich-rule</regex>
<description>방화벽 허용 규칙 추가 명령 실행</description>
</rule>
Kibana에서 차단 로그 집계: message : "filter_IN_public_REJECT" 후 시각화에서 SRC 기준 Top N
firewall-cmd 실행 이력을 확인합니다.ss -tn)를 확인합니다.firewall-cmd --list-all-zones 결과와 sudo/journal 로그를 보존합니다.--remove-port)하고 --reload로 영구 설정 기준으로 복원합니다.| 구분 | 핵심 내용 |
|---|---|
| zone 결정 순서 | source 매칭 → 인터페이스 zone |
| 설계 패턴 | 관리 zone(source=관리망) + public(서비스만) |
| 런타임 vs 영구 | 불일치 = 일시적 개방 의심 |
| 차단 로그 | --set-log-denied, kernel: filterIN_REJECT |
| 면접 포인트 | "permanent 없이 추가된 규칙은 재부팅 시 사라지는 흔적 최소화 기법" |
다음 편 016. Linux 서버 보안 — nftables 규칙셋 점검과 차단 로깅 에서는 firewalld 아래에서 실제로 동작하는 nftables 규칙셋 점검과 차단 로깅을 다룹니다.
이전 편: 014. Linux 서버 보안 — 열린 포트 기준선 비교 점검
📚 시리즈 전체 보기: 시스템 보안 · 취약점