가장 많이 쓰는 테이블은 filter(패킷 허용/차단 결정). 옵션 없이 iptables를 쓰면 이 테이블이 기본 대상이다.
다른 테이블: NAT 처리용 nat, 패킷 변조용 mangle.
filter 테이블에는 세 개의 내장 체인이 있고, 각 체인은 패킷의 흐름 방향에 따라 적용된다.
체인
적용 대상
INPUT
이 시스템으로 들어오는(목적지가 나) 패킷
OUTPUT
이 시스템에서 나가는(출발지가 나) 패킷
FORWARD
이 시스템을 거쳐 가는(라우터 역할 시) 패킷
방향에 따라 체인이 갈린다. 외부에서 우리 서버로 들어오는 접속(웹·SSH 요청 등)을 막거나 허용하는 건 INPUT 체인이다. 시험에서 "외부 SSH 접속을 차단" → INPUT 체인 규칙. "이 호스트가 다른 곳으로 나가는 트래픽 제어" → OUTPUT 체인. "게이트웨이를 통과하는 트래픽" → FORWARD 체인.
각 체인의 규칙들은 위에서 아래로 순서대로 적용된다.
패킷이 어떤 규칙과 일치하면 그 규칙의 타깃(처리 동작)이 실행된다.
어떤 규칙과도 일치하지 않으면 기본 정책(policy)이 적용된다.
이 "순서대로 매칭, 일치하면 즉시 처리"가 iptables를 이해하는 가장 중요한 원리다.
각 체인은 기본 정책을 가진다. 규칙에 걸리지 않은 패킷의 운명을 결정하는 최후의 규칙이다.
타깃
의미
ACCEPT
패킷을 허용한다
DROP
패킷을 조용히 버린다 (응답 없음 — 상대는 무응답으로 느낌)
REJECT
패킷을 거부하고 거부 응답을 보낸다 (상대는 즉시 거부됨을 앎)
LOG
패킷 정보를 로그에 남기고 다음 규칙으로 넘어감
DROP vs REJECT: 둘 다 차단이지만 응답이 다르다. DROP은 패킷을 묵묵히 버려서 상대는 타임아웃까지 기다려야 한다(포트 스캔을 방해하는 효과). REJECT는 "거부됨"이라는 ICMP 응답을 즉시 보내 상대가 바로 알게 한다. 보안상 외부 노출 포트는 DROP, 내부망은 사용자 편의를 위해 REJECT를 쓰는 식으로 구분하기도 한다.
# 체인의 기본 정책을 DROP으로 설정 (-P = policy)iptables -P INPUT DROPiptables -P FORWARD DROPiptables -P OUTPUT ACCEPT
⚠️ 원격 작업의 함정: 원격 SSH로 접속한 상태에서 iptables -P INPUT DROP을 먼저 실행하면, SSH 허용 규칙을 추가하기 전에 자기 자신이 끊긴다. 반드시 SSH 허용 규칙(-A INPUT -p tcp --dport 22 -j ACCEPT)을 먼저 넣은 뒤 기본 정책을 DROP으로 바꿔야 한다. 실무와 시험 모두에서 함정이 된다.
# 22번 포트(SSH) TCP 접속 허용iptables -A INPUT -p tcp --dport 22 -j ACCEPT# 80번 포트(HTTP) 허용iptables -A INPUT -p tcp --dport 80 -j ACCEPT# 특정 IP(192.168.1.50)에서 오는 모든 패킷 차단iptables -A INPUT -s 192.168.1.50 -j DROP# 루프백(자기 자신) 트래픽 허용iptables -A INPUT -i lo -j ACCEPT# 이미 연결된 세션의 응답 패킷 허용 (상태 추적)iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A vs -I의 순서 차이: 체인은 위→아래로 매칭하므로 규칙의 위치가 결과를 바꾼다. -A는 맨 끝에 붙이고, -I는 맨 앞에 끼워 넣는다. 이미 "전부 DROP" 규칙이 위에 있다면, 그 뒤에 -A로 ACCEPT를 추가해봐야 이미 DROP에 걸려 도달하지 못한다. 이럴 땐 -I로 ACCEPT를 앞에 삽입해야 한다.
# 규칙 목록 보기 (-n: IP를 이름 해석 없이 숫자로, -v: 상세, --line-numbers: 줄번호)iptables -L -n -v --line-numbers# 특정 체인만 보기iptables -L INPUT -n# 모든 규칙 초기화iptables -F# 규칙 저장 (RHEL 계열) — 재부팅 후에도 유지iptables-save > /etc/sysconfig/iptablesservice iptables save
⚠️ 휘발성 주의: iptables 규칙은 메모리에만 존재한다. 저장하지 않고 재부팅하면 모두 사라진다. RHEL 계열은 service iptables save 또는 iptables-save로 영속화해야 한다. 이를 모르고 "규칙이 사라졌다"고 당황하는 일이 흔하다.
iptables의 단점: 규칙을 하나씩 다뤄 직관적이지 않고, 규칙을 바꿀 때마다 전체를 다시 적용해 기존 연결이 끊길 수 있다.
RHEL 7부터 기본이 된 firewalld는 이를 개선한 고수준 관리 도구다.
firewalld의 핵심 개념은 zone(영역) — "네트워크 연결의 신뢰 수준"을 미리 정의해 둔 규칙 묶음이다.
인터페이스나 출발지를 특정 zone에 배정하면 그 zone의 규칙이 적용된다.
zone
신뢰 수준
drop
모든 들어오는 연결 차단, 응답 없음 (가장 폐쇄적)
block
들어오는 연결 거부(REJECT 응답)
public
(기본) 신뢰하지 않는 공개 네트워크. 선택된 연결만 허용
home / internal
신뢰하는 내부망. 대부분 허용
trusted
모든 트래픽 허용 (가장 개방적)
zone의 발상: iptables가 "규칙 한 줄 한 줄"을 다룬다면, firewalld는 "이 네트워크 카드는 공개망(public)이고, 저 카드는 내부망(internal)"처럼 상황별 규칙 묶음을 적용한다. 노트북을 공항 와이파이에 연결하면 public, 집에 오면 home zone으로 바꾸는 식의 유연함이 핵심이다.
영구 적용하려면 --permanent를 붙인다. 단 즉시 반영되지 않으므로 --reload로 다시 읽어야 한다.
# 현재 활성 zone과 설정 확인firewall-cmd --get-active-zonesfirewall-cmd --list-all# 기본 zone 확인/변경firewall-cmd --get-default-zonefirewall-cmd --set-default-zone=public# 서비스 허용 (런타임 — 재부팅 시 사라짐)firewall-cmd --add-service=http# 서비스 영구 허용 (재부팅 후 유지)firewall-cmd --add-service=http --permanent# 포트 직접 허용 (영구)firewall-cmd --add-port=8080/tcp --permanent# 영구 설정을 즉시 반영firewall-cmd --reload
명령/옵션
의미
--list-all
현재 zone의 전체 설정 보기
--add-service=이름
서비스(http, ssh 등) 허용
--remove-service=이름
서비스 허용 제거
--add-port=포트/프로토콜
특정 포트 허용
--permanent
영구 적용 (재부팅 후 유지)
--reload
영구 설정을 런타임에 다시 로드
--get-services
미리 정의된 서비스 목록 보기
--permanent 함정: firewall-cmd --add-service=http --permanent만 실행하면 설정 파일에는 기록되지만 지금 당장은 적용되지 않는다. 반드시 firewall-cmd --reload를 이어서 해야 현재 세션에도 반영된다. 반대로 --permanent 없이 추가하면 지금은 되지만 재부팅 시 사라진다. "둘 다 하려면 한 번은 런타임, 한 번은 permanent"로 두 번 실행하거나, permanent 후 reload하는 방식을 쓴다.
둘은 함께 쓰면 안 된다: firewalld와 iptables 서비스를 동시에 활성화하면 충돌한다. RHEL 7+에서는 firewalld가 기본이며, iptables를 직접 쓰려면 firewalld를 끄고(systemctl disable firewalld) iptables 서비스를 활성화해야 한다. 둘 다 결국 커널의 netfilter를 제어하므로 한쪽만 관리자로 써야 한다.
직접 쳐보기: 테스트 VM에서 firewall-cmd --add-service=http(런타임만)를 한 뒤 firewall-cmd --list-services로 확인하고, 재부팅 후 사라지는 것을 확인한다. 그다음 --permanent를 붙여 다시 하고 --reload까지 거쳐 영속됨을 확인하면 런타임/영구의 차이가 체감된다. iptables 쪽은 iptables -L -n --line-numbers로 줄번호를 본 뒤 -I와 -A의 위치 차이를 실험해 본다.