UFW는 iptables를 감싸는 편의 도구입니다. 더 세밀한 제어가 필요하거나 스크립트로 방화벽을 관리할 때는 iptables를 직접 다루는 것이 효과적입니다.
iptables 체인 구조
인터넷 → [PREROUTING] → 라우팅 결정
↓ ↓
[INPUT] [FORWARD]
↓
서버 프로세스
↓
[OUTPUT] → [POSTROUTING] → 인터넷
- INPUT: 서버로 들어오는 패킷
- OUTPUT: 서버에서 나가는 패킷
- FORWARD: 서버를 경유하는 패킷
현재 규칙 확인
# 규칙 목록 (줄 번호 포함)
sudo iptables -L -n -v --line-numbers
# NAT 테이블 확인
sudo iptables -t nat -L -n -v
기본 정책 설정
# 기본 정책: 입력은 차단, 출력은 허용
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
주의: 기본 정책을 DROP으로 바꾸기 전에 반드시 SSH 포트를 허용 규칙으로 추가하세요. 순서가 바뀌면 서버에 접속할 수 없게 됩니다.
필수 허용 규칙
# 루프백 인터페이스 허용
sudo iptables -A INPUT -i lo -j ACCEPT
# 기존 연결의 응답 패킷 허용 (ESTABLISHED, RELATED)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH 허용 (포트를 변경했다면 22 대신 변경한 포트 번호 입력)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# HTTP, HTTPS 허용
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
특정 IP 또는 대역 허용/차단
# 특정 IP만 허용
sudo iptables -A INPUT -s 203.0.113.10 -j ACCEPT
# IP 대역 허용 (CIDR 표기)
sudo iptables -A INPUT -s 203.0.113.0/24 -j ACCEPT
# 특정 IP 차단
sudo iptables -A INPUT -s 192.0.2.100 -j DROP
# 특정 IP에서 오는 SSH만 허용 (더 엄격한 제어)
sudo iptables -A INPUT -s 203.0.113.10 -p tcp --dport 22 -j ACCEPT
포트 범위 및 다중 포트
# 포트 범위 허용 (예: 8000~9000)
sudo iptables -A INPUT -p tcp --dport 8000:9000 -j ACCEPT
# 여러 포트를 한 번에 (multiport 모듈)
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPT
연결 수 제한 (브루트포스 방어)
# SSH 포트 연결 속도 제한 (1분에 4회 초과 시 차단)
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
-m recent --set --name SSH
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
-m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
ICMP (ping) 제어
# ping 차단
sudo iptables -A INPUT -p icmp -j DROP
# ping 속도 제한 허용 (DDoS 방어)
sudo iptables -A INPUT -p icmp --icmp-type echo-request \
-m limit --limit 1/s --limit-burst 5 -j ACCEPT
규칙 삭제
# 줄 번호로 삭제
sudo iptables -D INPUT 3
# 규칙 내용으로 삭제 (-A 대신 -D)
sudo iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
# 모든 규칙 초기화
sudo iptables -F INPUT
규칙 영구 저장
재부팅하면 iptables 규칙이 초기화됩니다. 영구 적용하려면:
# Debian/Ubuntu
sudo apt install iptables-persistent
sudo netfilter-persistent save
# 또는 수동 저장
sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6
# 부팅 시 자동 로드 확인
sudo systemctl enable netfilter-persistent
로깅 설정
# 차단된 패킷 로그 기록
sudo iptables -A INPUT -j LOG --log-prefix "IPT DROP: " --log-level 4
sudo iptables -A INPUT -j DROP
# 로그 확인
sudo tail -f /var/log/kern.log | grep "IPT DROP"
완성된 방화벽 스크립트 예시
#!/bin/bash
# /etc/iptables/setup.sh
# 기존 규칙 초기화
iptables -F
iptables -X
# 기본 정책
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 루프백
iptables -A INPUT -i lo -j ACCEPT
# 기존 연결 허용
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH (포트 22, 필요시 변경)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 웹 서버
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# 저장
iptables-save > /etc/iptables/rules.v4
iptables를 이해하면 방화벽 동작을 정확히 제어할 수 있습니다. 복잡한 환경에서는 fail2ban과 함께 사용하면 더욱 효과적입니다.