nftables란?
Linux 커널 3.13부터 도입된 nftables는 iptables, ip6tables, arptables, ebtables를 통합한 차세대 패킷 필터링 프레임워크다. Debian 10+, RHEL 8+, Ubuntu 20.04+에서 기본 방화벽으로 채택되었으며, iptables의 복잡한 체인 구조와 성능 한계를 해결한다.
# iptables (레거시)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
# nftables (현대적)
nft add rule inet filter input tcp dport { 80, 443 } accept
nft add rule inet filter input tcp dport 22 ip saddr 10.0.0.0/8 accept
nftables의 핵심 장점은 세트(Set)와 맵(Map) 자료구조, IPv4/IPv6 통합 처리, 원자적(atomic) 룰셋 교체다.
nftables 아키텍처
iptables와 달리 nftables는 고정된 테이블/체인이 없다. 사용자가 직접 테이블과 체인을 정의한다.
| 계층 | iptables | nftables |
|---|---|---|
| Address Family | 별도 명령어 (iptables/ip6tables) | inet (IPv4+IPv6 통합) |
| 테이블 | 고정 (filter, nat, mangle) | 사용자 정의 |
| 체인 | 고정 (INPUT, OUTPUT, FORWARD) | 사용자 정의 + hook 지정 |
| 룰 | 선형 매칭 | Set/Map 기반 O(1) 매칭 |
# nftables 기본 구조
table inet filter { # inet = IPv4 + IPv6
chain input {
type filter hook input priority 0; policy drop;
# 기본 허용 규칙
ct state established,related accept
iif lo accept
# 서비스 포트
tcp dport { 22, 80, 443 } accept
# ICMP
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Set과 Map: nftables의 핵심 자료구조
iptables에서 IP 화이트리스트를 관리하려면 규칙을 하나씩 추가해야 했다. nftables의 Named Set은 이를 O(1) 해시 룩업으로 처리한다.
table inet filter {
# Named Set 정의
set trusted_ips {
type ipv4_addr
flags interval
elements = {
10.0.0.0/8,
172.16.0.0/12,
192.168.0.0/16,
}
}
set blocked_ports {
type inet_service
elements = { 3306, 5432, 6379, 27017 }
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
# Set 참조
ip saddr @trusted_ips accept
tcp dport @blocked_ports drop
tcp dport { 80, 443 } accept
}
}
# 런타임에 Set 요소 추가/삭제 (재시작 불필요)
nft add element inet filter trusted_ips { 203.0.113.50 }
nft delete element inet filter trusted_ips { 203.0.113.50 }
# Set 내용 확인
nft list set inet filter trusted_ips
Map은 키-값 매핑으로 더 복잡한 라우팅이 가능하다.
table inet filter {
# Map: 소스 IP → rate limit
map rate_limits {
type ipv4_addr : limit
elements = {
10.0.0.0/24 : "100/second",
172.16.0.0/16 : "50/second",
}
}
# Verdict Map: 포트 → 동작
map port_policy {
type inet_service : verdict
elements = {
22 : accept,
80 : accept,
443 : accept,
3306 : drop,
}
}
chain input {
type filter hook input priority 0; policy drop;
tcp dport vmap @port_policy
}
}
Rate Limiting: 브루트포스 방어
SSH 브루트포스 공격을 nftables의 meter와 limit로 방어하는 실전 패턴이다.
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
# SSH: 분당 3회 초과 시 차단
tcp dport 22 ct state new limit rate 3/minute accept
tcp dport 22 ct state new drop
# 더 정교한 방식: IP별 rate limit (meter)
tcp dport 22 ct state new
meter ssh_bruteforce { ip saddr limit rate 5/minute burst 3 packets }
accept
tcp dport 22 ct state new drop
# HTTP: IP별 초당 요청 제한
tcp dport { 80, 443 }
meter http_flood { ip saddr limit rate 100/second burst 50 packets }
accept
tcp dport { 80, 443 } drop
}
}
NAT 설정
프록시 서버, Docker 네트워크, VPN 게이트웨이에서 NAT는 필수다.
table ip nat {
chain prerouting {
type nat hook prerouting priority -100;
# DNAT: 외부 80 → 내부 10.0.0.5:8080
tcp dport 80 dnat to 10.0.0.5:8080
# 포트 범위 DNAT
tcp dport 3000-3010 dnat to 10.0.0.5
}
chain postrouting {
type nat hook postrouting priority 100;
# SNAT: 내부 네트워크 → 외부 IP
ip saddr 10.0.0.0/24 oifname "eth0" masquerade
# 고정 SNAT (성능 우수)
ip saddr 10.0.0.0/24 oifname "eth0" snat to 203.0.113.1
}
}
설정 파일 관리와 원자적 교체
nftables의 가장 큰 운영 장점은 원자적(atomic) 룰셋 교체다. 전체 룰셋을 한 번에 교체하므로 규칙 사이의 빈 순간이 없다.
# /etc/nftables.conf — 설정 파일
#!/usr/sbin/nft -f
flush ruleset # 기존 규칙 전체 삭제 (원자적)
table inet filter {
set trusted_ips {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8 }
}
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
ip saddr @trusted_ips accept
tcp dport { 22, 80, 443 } accept
ip protocol icmp accept
counter drop # 드롭 카운터
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
# 설정 적용
nft -f /etc/nftables.conf
# 문법 검증 (적용하지 않음)
nft -c -f /etc/nftables.conf
# 현재 룰셋 백업
nft list ruleset > /etc/nftables-backup.conf
# systemd로 부팅 시 자동 적용
systemctl enable nftables
iptables에서 nftables 마이그레이션
기존 systemd 서비스에서 iptables를 사용 중이라면 iptables-translate로 자동 변환할 수 있다.
# 단일 규칙 변환
$ iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
nft add rule ip filter INPUT tcp dport 22 counter accept
# 전체 ruleset 변환
$ iptables-save | iptables-restore-translate
# nft 형식으로 전체 출력
# 주의사항:
# - 일부 match/target은 수동 변환 필요 (connlimit, hashlimit 등)
# - iptables-nft (호환 레이어)를 임시로 사용 가능
# - 장기적으로는 네이티브 nftables 사용 권장
모니터링과 디버깅
# 전체 룰셋 확인
nft list ruleset
# 특정 테이블만
nft list table inet filter
# 카운터 포함 상세 출력
nft list chain inet filter input
# 실시간 패킷 추적
nft monitor trace
# 특정 체인에 trace 활성화
nft add rule inet filter input meta nftrace set 1
# JSON 출력 (자동화/파싱용)
nft -j list ruleset
| 명령 | 용도 |
|---|---|
nft list ruleset |
전체 규칙 확인 |
nft monitor |
실시간 이벤트 모니터링 |
nft -c -f file |
문법 검증 (dry run) |
nft -j list ruleset |
JSON 출력 |
conntrack -L |
커넥션 트래킹 테이블 |
정리
nftables는 iptables를 대체하는 Linux 표준 방화벽이다. Named Set/Map으로 O(1) 매칭, inet 패밀리로 IPv4/IPv6 통합, 원자적 룰셋 교체로 무중단 변경, meter 기반 rate limiting으로 브루트포스 방어까지 모던 인프라 운영에 필수적인 기능을 제공한다. iptables-translate로 점진적 마이그레이션이 가능하므로 신규 서버부터 nftables를 도입하는 것을 권장한다.