NGFW 고급 오프로드 구성
QUIC/TLS 1.3 ECH 환경 NGFW 대응 전략, conntrack zone·VRF·eSwitch VF 기반 멀티 테넌트 격리, Hairpin/Loopback East-West 보안, 대규모 ACL 규칙 관리, Kubernetes 멀티 클러스터 연동, HA offload 동기화, 고급 트러블슈팅 가이드
QUIC/TLS 1.3과 NGFW 오프로드
QUIC 프로토콜과 TLS 1.3의 Encrypted Client Hello(ECH)는 기존 NGFW의 DPI 기반 트래픽 분류 체계를 근본적으로 무력화합니다. 이 섹션에서는 QUIC/ECH 환경에서 NGFW 오프로드를 유지하기 위한 전략을 분석합니다.
QUIC 프로토콜이 NGFW에 미치는 영향
QUIC(RFC 9000)은 UDP 기반에 TLS 1.3 암호화를 내장한 전송 프로토콜입니다. 기존 TCP+TLS 스택과 비교하면 NGFW에 다음과 같은 도전을 제시합니다:
- UDP 기반 + 내장 TLS 1.3 암호화 — 전통적 DPI가 페이로드를 전혀 볼 수 없으며, TCP처럼 핸드셰이크 시퀀스로 상태를 추적할 수 없습니다
- Connection ID 기반 경로 — 5-tuple(src/dst IP + port + proto)이 변경되어도 CID만 유지되면 세션이 계속됩니다. 이는 conntrack의 5-tuple 기반 추적과 근본적으로 충돌합니다
- 0-RTT 재연결 — 이전 세션의 PSK를 사용하여 첫 패킷부터 암호화된 데이터를 전송하므로, conntrack의 NEW 세션 탐지가 어렵습니다
- Connection Migration — 모바일 환경에서 Wi-Fi↔LTE 전환 시 IP가 변경되어도 QUIC 세션이 유지되므로 flowtable 5-tuple 키가 무효화(Invalidation)됩니다
| 특성 | TCP + TLS 1.2/1.3 | QUIC | NGFW 영향 |
|---|---|---|---|
| 전송 프로토콜 | TCP (proto 6) | UDP (proto 17) | 포트 기반 프로토콜 식별 불가 (UDP 443) |
| 헤더 가시성 | TCP 헤더 평문, TLS record 헤더 평문 | Short Header: CID + 패킷 번호만 (암호화) | DPI가 활용할 평문 메타데이터 극소 |
| SNI 가시성 | Client Hello의 SNI 평문 (TLS 1.2/1.3) | Initial Packet에만 SNI (ECH 시 암호화) | URL Filtering 제한 또는 불가 |
| 세션 식별 | 5-tuple 고정 | Connection ID (가변 길이) | conntrack 5-tuple 키 무효화 가능 |
| 핸드셰이크 | TCP 3-way + TLS (2-3 RTT) | 1-RTT (0-RTT 재연결) | NEW 세션 탐지 시점 불명확 |
| 연결 마이그레이션 | 미지원 (새 TCP 연결 필요) | 지원 (CID 유지) | flowtable 엔트리 갱신 불가 |
| 다중화(Multiplexing) | 연결당 하나의 스트림 (HTTP/2 제외) | 단일 연결에 다중 스트림 | 하나의 conntrack 엔트리에 다중 논리 세션 |
| 오프로드 가능성 | 높음 (EST 후 flowtable) | 제한적 (CID 추적 필요) | CID 기반 오프로드 미지원 |
QUIC 트래픽 탐지와 분류
QUIC 패킷은 첫 번째 바이트(Header Form bit)로 Long Header와 Short Header를 구분합니다. NGFW에서는 Initial Packet의 Long Header를 분석하여 QUIC 연결을 식별합니다.
- Initial Packet: 첫 번째 바이트의 최상위 비트 = 1 (Long Header), 다음 2비트가 패킷 타입(00 = Initial)
- Version 필드: 바이트 오프셋(Offset) 1~4에 위치. QUIC v1은
0x00000001, QUIC v2는0x6b3343cf - Short Header: 첫 번째 바이트의 최상위 비트 = 0 → 연결 확립 후 데이터 패킷
| 패킷 유형 | Header Form | 첫 바이트 패턴 | 가시 필드 | NGFW 활용 |
|---|---|---|---|---|
| Initial | Long (1) | 0b1100xxxx (0xC0~0xCF) | Version, DCID, SCID, Token, Length | QUIC 탐지, 버전 확인, CID 추출 |
| 0-RTT | Long (1) | 0b1101xxxx (0xD0~0xDF) | Version, DCID, SCID, Length | 재연결 탐지 |
| Handshake | Long (1) | 0b1110xxxx (0xE0~0xEF) | Version, DCID, SCID, Length | 핸드셰이크 진행 확인 |
| Retry | Long (1) | 0b1111xxxx (0xF0~0xFF) | Version, DCID, SCID, Retry Token | DoS 방어 확인 |
| 1-RTT (Short) | Short (0) | 0b01xxxxxx (0x40~0x7F) | DCID만 (나머지 암호화) | CID로 기존 세션 매핑만 가능 |
nftables에서 QUIC 트래픽을 탐지하고 분류하는 규칙 예시입니다:
#!/usr/sbin/nft -f
# QUIC 트래픽 탐지 및 분류 nftables 규칙
table inet quic_detect {
# QUIC Initial Packet 탐지 set (rate limiting용)
set quic_new_conn {
type ipv4_addr . inet_service
flags dynamic,timeout
timeout 30s
}
chain forward {
type filter hook forward priority 0; policy accept;
# UDP 443 트래픽 필터링
udp dport 443 jump quic_classify
# UDP 443 + UDP 80 (alt-svc 기반 QUIC 업그레이드)
udp dport 80 @th,0,8 & 0x80 == 0x80 jump quic_classify
}
chain quic_classify {
# Long Header 판별: 첫 번째 바이트 bit7 = 1
@th,0,8 & 0x80 == 0x00 jump quic_short_header
# QUIC v1 Initial Packet: first_byte & 0xF0 == 0xC0, version == 0x00000001
@th,0,8 & 0xF0 == 0xC0 @th,8,32 == 0x00000001 \
jump quic_initial
# QUIC v2 Initial: version == 0x6b3343cf
@th,0,8 & 0xF0 == 0xC0 @th,8,32 == 0x6b3343cf \
jump quic_initial
# 0-RTT Packet (재연결): first_byte & 0xF0 == 0xD0
@th,0,8 & 0xF0 == 0xD0 \
log prefix "QUIC-0RTT: " counter
# Handshake Packet: first_byte & 0xF0 == 0xE0
@th,0,8 & 0xF0 == 0xE0 counter accept
}
chain quic_initial {
# 새 QUIC 연결 rate limiting (DDoS 방어)
update @quic_new_conn { ip saddr . udp dport } \
limit rate over 100/second burst 50 packets drop
# 로깅 후 Slow Path로 전달 (DPI 검사)
log prefix "QUIC-NEW: " counter accept
}
chain quic_short_header {
# Short Header: 이미 확립된 QUIC 세션
# conntrack EST 상태이면 flowtable으로 오프로드 가능
ct state established flow add @ft counter accept
ct state established counter accept
}
}
코드 설명
- 5-9행 QUIC 새 연결을 추적하는 동적 set입니다. 30초 타임아웃으로 자동 만료되며, DDoS rate limiting에 사용됩니다.
- 15행 QUIC은 주로 UDP 443을 사용합니다. 이 규칙으로 잠재적 QUIC 트래픽을 필터링합니다.
-
18행
@th,0,8은 transport header offset 0부터 8비트를 읽습니다. UDP 페이로드의 첫 바이트를 검사하여 Long Header 여부를 판별합니다. -
25-26행
Initial Packet은
0xC0~0xCF범위이고, 바이트 1~4가 QUIC 버전입니다. v1(0x00000001)을 확인합니다. - 42-43행 새 QUIC 연결에 대해 source IP + port 조합으로 초당 100개까지 허용하고 초과분을 DROP합니다. QUIC flood 공격 방어입니다.
- 50-51행 Short Header 패킷은 이미 QUIC 연결이 확립된 상태이므로 conntrack ESTABLISHED이면 flowtable 오프로드 대상입니다.
TLS 1.3 Encrypted Client Hello (ECH)
TLS 1.3의 ECH(RFC 9460 초안)는 Client Hello 메시지 내의 SNI(Server Name Indication)를 완전히 암호화합니다. ECH 이전에는 TLS 핸드셰이크의 Client Hello에서 SNI를 평문으로 읽어 URL Filtering과 트래픽 분류에 활용할 수 있었지만, ECH가 활성화되면 이 방법이 완전히 무력화됩니다.
- ECH 동작 원리: 클라이언트가 DNS HTTPS 레코드에서 서버의 공개키를 받아 Client Hello의 핵심 정보(SNI 포함)를 암호화합니다
- Outer SNI vs Inner SNI: ECH는 "외부 SNI"(CDN/프록시 도메인)만 노출하고, 실제 목적지 SNI는 암호화된 "내부 SNI"에 포함됩니다
- JA4 핑거프린팅: ECH 환경에서 대안으로 TLS 핸드셰이크의 구조적 특성(cipher suite 순서, extension 조합, ALPN 목록)으로 클라이언트/애플리케이션을 식별합니다
| 기술 | ECH 이전 | ECH 이후 | 대체 식별 방법 |
|---|---|---|---|
| SNI 기반 URL Filtering | Client Hello에서 SNI 평문 추출 | 외부 SNI만 가시 (CDN 도메인) | DNS 쿼리 모니터링, IP 평판 DB |
| 인증서 기반 식별 | Server Hello의 인증서 평문 | TLS 1.3부터 인증서도 암호화 | OCSP stapling 분석, CT 로그 |
| App-ID (DPI) | SNI + ALPN + 인증서 조합 | ALPN만 부분 가시 | JA4 핑거프린트, 트래픽 패턴 분석 |
| 카테고리 필터링 | SNI → 도메인 → 카테고리 DB | 외부 SNI만으로는 정확도 저하 | DNS Response Policy Zone (RPZ) |
| SSL Inspection | MITM 프록시로 복호화 | ECH 키 없이는 MITM 불가 | 엔드포인트 에이전트, WARP 방식 |
| JA3/JA4 핑거프린팅 | 보조 식별 수단 | 주요 식별 수단으로 격상 | JA4+ (JA4S, JA4H, JA4X 확장) |
t13d1516h2_8daaf6152771_e5627efa2ab1 형태의 해시로 요약합니다. 첫 부분은 프로토콜/버전/SNI유무/cipher수/extension수, 나머지는 cipher suite와 extension의 해시입니다. ECH로 SNI가 가려져도 브라우저·OS·앱별로 고유한 핑거프린트가 생성되어 식별이 가능합니다.
QUIC/ECH 환경의 NGFW 전략
QUIC과 ECH가 확산되는 환경에서 NGFW의 트래픽 가시성을 유지하기 위한 4가지 전략을 분석합니다:
전략 1: QUIC 차단/제어 (정책적 접근)
- UDP 443을 차단하여 클라이언트가 TCP+TLS로 폴백하도록 유도
- 기업 환경에서 가장 단순하고 효과적인 방법
- 단점: HTTP/3 성능 이점 상실, 일부 서비스 호환성 문제
전략 2: 초기 핸드셰이크 기반 분류 후 오프로드
- QUIC Initial Packet의 가시 정보(SNI, Version, DCID 길이)로 1차 분류
- 분류 후 ALLOW된 세션의 Short Header 패킷을 conntrack 기반 오프로드
- 5-tuple 변경(Connection Migration) 시 오프로드 해제
전략 3: DNS 기반 사전 분류 (DoH/DoT 제어)
- DNS 응답을 분석하여 IP→도메인 매핑 테이블 구축
- DoH(DNS over HTTPS)를 차단하고 내부 DNS 서버만 허용
- DNS RPZ(Response Policy Zone)로 카테고리 기반 사전 차단
전략 4: 엔드포인트 기반 (QUIC Client Hello 파싱)
- 엔드포인트 에이전트가 애플리케이션 수준에서 QUIC 세션 정보를 NGFW에 전달
- SASE(Secure Access Service Edge) 모델: 클라이언트-사이드 터널로 가시성 확보
- QUIC Initial Packet의 CRYPTO 프레임에서 Client Hello를 파싱 (복호화 가능)
다음은 nftables + Suricata를 조합하여 QUIC을 처리하는 종합 규칙 예시입니다:
#!/usr/sbin/nft -f
# QUIC/ECH 대응 NGFW nftables 규칙 (전략 1+2+3 조합)
table inet ngfw_quic {
# 정책별 QUIC 처리 모드
# 0: block (TCP fallback 유도)
# 1: inspect (Initial만 DPI)
# 2: allow (분류 후 오프로드)
# DNS 기반 IP→카테고리 매핑 (외부 스크립트로 갱신)
set dns_blocked_ips {
type ipv4_addr
flags interval
# 예: DNS RPZ에서 차단 도메인의 IP를 자동 추가
}
set quic_allowed_dsts {
type ipv4_addr
flags interval
# 예: 업무용 SaaS IP 대역 (QUIC 허용)
}
flowtable ft {
hook ingress priority 0;
devices = { eth0, eth1 };
flags offload;
}
chain forward {
type filter hook forward priority 0; policy drop;
# 1. conntrack EST 세션 → flowtable 오프로드
ct state established,related flow add @ft counter accept
# 2. DNS 기반 사전 차단 (전략 3)
ip daddr @dns_blocked_ips counter drop
# 3. QUIC 처리 (UDP 443)
udp dport 443 jump quic_policy
# 4. 일반 TCP/TLS → DPI (NFQUEUE)
tcp dport 443 ct state new \
queue num 0-3 fanout,bypass
# 5. 기타 허용 규칙
ct state established,related accept
}
chain quic_policy {
# 허용된 목적지 → QUIC 허용 (오프로드 대상)
ip daddr @quic_allowed_dsts accept
# 나머지 QUIC → 정책에 따라 처리
# 전략 1: 차단하여 TCP fallback 유도
# icmp type port-unreachable 응답으로 빠른 fallback
reject with icmpx port-unreachable
# 전략 2를 사용할 경우 (위 reject 대신):
# @th,0,8 & 0x80 == 0x80 queue num 4-5 fanout,bypass
# @th,0,8 & 0x80 == 0x00 ct state established accept
}
}
# Suricata QUIC 탐지 규칙 (suricata.rules에 추가)
# QUIC Initial Packet 탐지 (App-Layer)
alert quic $HOME_NET any -> $EXTERNAL_NET 443 \
(msg:"QUIC Initial Packet detected"; \
quic.version; content:"|00 00 00 01|"; \
sid:3000001; rev:1;)
# QUIC 0-RTT 재연결 탐지 (Early Data 위험)
alert quic $HOME_NET any -> $EXTERNAL_NET 443 \
(msg:"QUIC 0-RTT Early Data"; \
quic.header.type; content:"|01|"; \
sid:3000002; rev:1;)
# JA4 핑거프린트 기반 브라우저 식별 예시
alert tls $HOME_NET any -> $EXTERNAL_NET 443 \
(msg:"TLS JA4 - Chrome Browser detected"; \
ja4.hash; content:"t13d1516h2"; startswith; \
sid:3000003; rev:1;)
멀티 테넌트 NGFW 아키텍처
클라우드 환경과 MSSP(Managed Security Service Provider)에서는 단일 NGFW 인스턴스에서 다수의 테넌트(고객/VPC/네임스페이스)를 격리하여 운영해야 합니다. 이 섹션에서는 Linux 커널의 격리 메커니즘을 활용한 멀티 테넌트 NGFW 아키텍처를 분석합니다.
멀티 테넌시 격리 모델
Linux 커널에서 제공하는 네트워크 격리 기술을 NGFW 관점에서 비교합니다:
| 격리 방식 | 격리 수준 | conntrack 격리 | flowtable 격리 | HW offload | 장점 | 단점 |
|---|---|---|---|---|---|---|
| 네트워크 네임스페이스 | 완전 격리 (독립 네트워크 스택) | 네임스페이스별 독립 conntrack | 네임스페이스별 독립 flowtable | VF를 네임스페이스에 이동 가능 | 가장 강력한 격리, 충돌 없음 | 리소스 오버헤드, 관리 복잡성 |
| VRF (Virtual Routing & Forwarding) | L3 라우팅 격리 | 공유 (zone으로 분리 필요) | VRF별 설정 가능 | TC flower에서 VRF 매칭 가능 | 라우팅 격리, 단일 스택 유지 | L2 격리 불가, conntrack 추가 설정 필요 |
| conntrack zone | conntrack 테이블 격리 | zone ID별 완전 격리 | zone별 flowtable 분리 가능 | TC flower ct zone 지원 | 경량, 기존 인프라 유지 | nftables 규칙 복잡도 증가 |
| eSwitch VF representor | HW 수준 격리 | VF별 conntrack zone 매핑 | VF별 독립 flowtable | VF당 독립 FDB 규칙 | HW 격리, 최고 성능 | VF 수 제한 (NIC 의존), SmartNIC 필요 |
| nftables table/chain 분리 | 논리적 격리 (정책 분리) | 공유 (mark/zone으로 구분) | 공유 flowtable | 공유 | 설정 단순, 유연한 정책 | 격리 보장 약함, 버그 시 누출 |
conntrack zone 기반 테넌트 격리
conntrack zone은 동일 커널 내에서 conntrack 테이블을 논리적으로 분리하는 가장 효율적인 방법입니다. 각 테넌트에 고유한 zone ID를 할당하면 동일한 5-tuple을 가진 세션도 충돌 없이 독립적으로 추적됩니다.
#!/usr/sbin/nft -f
# 멀티 테넌트 conntrack zone 설정
# 테넌트 A: zone 100, 테넌트 B: zone 200
table inet multi_tenant {
# 테넌트별 독립 flowtable
flowtable ft_tenant_a {
hook ingress priority 0;
devices = { eth0, eth1 };
flags offload;
}
flowtable ft_tenant_b {
hook ingress priority 0;
devices = { eth0, eth2 };
flags offload;
}
# 테넌트 분류 체인 (ingress에서 mark 설정)
chain prerouting {
type filter hook prerouting priority -150; policy accept;
# 서브넷 기반 테넌트 분류
ip saddr 10.100.0.0/16 meta mark set 100
ip saddr 10.200.0.0/16 meta mark set 200
# VLAN 기반 테넌트 분류 (대안)
# vlan id 100 meta mark set 100
# vlan id 200 meta mark set 200
# mark → conntrack zone 매핑
meta mark 100 ct zone set 100
meta mark 200 ct zone set 200
}
chain forward {
type filter hook forward priority 0; policy drop;
# 테넌트 A: zone 100의 EST 세션 → 전용 flowtable
meta mark 100 ct zone 100 ct state established \
flow add @ft_tenant_a counter accept
# 테넌트 B: zone 200의 EST 세션 → 전용 flowtable
meta mark 200 ct zone 200 ct state established \
flow add @ft_tenant_b counter accept
# 새 세션: 테넌트별 DPI 큐 분리
meta mark 100 ct zone 100 ct state new \
queue num 0-3 fanout,bypass
meta mark 200 ct zone 200 ct state new \
queue num 4-7 fanout,bypass
# RELATED 세션 허용
ct state related accept
}
}
코드 설명
- 7-16행 테넌트별 독립 flowtable을 생성합니다. 각 flowtable은 자체 devices를 가지며 독립적으로 HW offload됩니다.
- 23-24행 소스 IP 서브넷으로 테넌트를 분류하여 nfmark를 설정합니다. VLAN, 인터페이스, DSCP 등 다양한 기준 사용 가능합니다.
-
32-33행
ct zone set으로 패킷의 conntrack zone을 설정합니다. 같은 5-tuple이라도 zone이 다르면 별도 conntrack 엔트리가 생성됩니다. -
40-41행
테넌트 A의 ESTABLISHED 세션을 전용 flowtable
ft_tenant_a에 오프로드합니다. zone 100 내에서만 매칭됩니다. - 49-53행 새 세션을 테넌트별 NFQUEUE 범위에 분리하여 전달합니다. Suricata 인스턴스를 테넌트별로 분리 운영할 수 있습니다.
TC flower에서도 conntrack zone을 지정하여 HW 수준의 테넌트 격리를 구현할 수 있습니다:
# TC flower: 테넌트별 conntrack zone + HW offload
# 테넌트 A (VF0, zone 100): untracked → ct zone 100 시작
tc filter add dev enp4s0f0v0 ingress prio 1 \
protocol ip flower \
ct_state -trk \
action ct zone 100
# 테넌트 A: EST → HW forward to uplink
tc filter add dev enp4s0f0v0 ingress prio 2 \
protocol ip flower \
ct_state +trk+est \
ct_zone 100 \
action ct zone 100 \
action mirred egress redirect dev enp4s0f0
# 테넌트 B (VF1, zone 200): untracked → ct zone 200 시작
tc filter add dev enp4s0f0v1 ingress prio 1 \
protocol ip flower \
ct_state -trk \
action ct zone 200
# 테넌트 B: EST → HW forward to uplink
tc filter add dev enp4s0f0v1 ingress prio 2 \
protocol ip flower \
ct_state +trk+est \
ct_zone 200 \
action ct zone 200 \
action mirred egress redirect dev enp4s0f0
# 테넌트별 conntrack 상태 확인
conntrack -L --zone 100 # 테넌트 A 세션
conntrack -L --zone 200 # 테넌트 B 세션
VRF + eSwitch VF 기반 격리
VRF(Virtual Routing and Forwarding)는 L3 라우팅을 테넌트별로 완전 격리합니다. eSwitch의 VF representor와 결합하면 HW 수준의 라우팅 + 방화벽 격리가 가능합니다.
#!/bin/bash
# VRF + eSwitch VF 기반 멀티 테넌트 설정
# 1. VRF 생성 (테넌트별)
ip link add vrf-tenant-a type vrf table 100
ip link set vrf-tenant-a up
ip link add vrf-tenant-b type vrf table 200
ip link set vrf-tenant-b up
# 2. VF representor를 VRF에 바인딩
ip link set enp4s0f0v0 master vrf-tenant-a
ip link set enp4s0f0v1 master vrf-tenant-b
# 3. 업링크 서브인터페이스를 VRF에 바인딩
ip link add link enp4s0f0 name enp4s0f0.100 type vlan id 100
ip link set enp4s0f0.100 master vrf-tenant-a
ip addr add 10.100.0.1/24 dev enp4s0f0.100
ip link add link enp4s0f0 name enp4s0f0.200 type vlan id 200
ip link set enp4s0f0.200 master vrf-tenant-b
ip addr add 10.200.0.1/24 dev enp4s0f0.200
# 4. VRF별 라우팅 테이블
ip route add default via 10.100.0.254 table 100
ip route add default via 10.200.0.254 table 200
# 5. sysctl: VRF별 forwarding 활성화
sysctl -w net.ipv4.conf.all.forwarding=1
sysctl -w net.ipv4.conf.vrf-tenant-a.forwarding=1
sysctl -w net.ipv4.conf.vrf-tenant-b.forwarding=1
#!/usr/sbin/nft -f
# VRF 기반 테넌트별 nftables 방화벽 + flowtable
table inet vrf_ngfw {
flowtable ft_a {
hook ingress priority 0;
devices = { enp4s0f0v0, enp4s0f0.100 };
flags offload;
}
flowtable ft_b {
hook ingress priority 0;
devices = { enp4s0f0v1, enp4s0f0.200 };
flags offload;
}
chain forward {
type filter hook forward priority 0; policy drop;
# VRF 인터페이스로 테넌트 구분
iifname "enp4s0f0v0" jump tenant_a_rules
iifname "enp4s0f0v1" jump tenant_b_rules
# 반환 트래픽
oifname "enp4s0f0v0" ct state established,related accept
oifname "enp4s0f0v1" ct state established,related accept
}
chain tenant_a_rules {
# 테넌트 A 보안 정책
ct state established flow add @ft_a counter accept
ct state new tcp dport { 80, 443 } accept
ct state new udp dport 53 accept
counter drop
}
chain tenant_b_rules {
# 테넌트 B 보안 정책 (더 제한적)
ct state established flow add @ft_b counter accept
ct state new tcp dport 443 accept
counter drop
}
}
Kubernetes 환경의 NGFW
Kubernetes에서는 CNI(Container Network Interface) 플러그인이 Pod 간 네트워킹을 관리합니다. NGFW 기능을 K8s 환경에 통합하려면 CNI의 데이터 플레인과 flowtable offload의 호환성을 고려해야 합니다.
| CNI 플러그인 | 데이터 플레인 | NetworkPolicy | conntrack offload | flowtable 호환 | 비고 |
|---|---|---|---|---|---|
| Cilium | eBPF (tc-bpf + XDP) | L3/L4/L7 (자체 구현) | eBPF CT map (자체) | 미지원 (자체 fast path) | 커널 conntrack 우회, 자체 CT + LB |
| Calico (eBPF) | eBPF (tc-bpf) | L3/L4 | eBPF CT (자체) | 미지원 (자체 구현) | kube-proxy 대체, eBPF conntrack |
| Calico (iptables) | iptables/nftables | L3/L4 | 커널 conntrack | 가능 (nftables 모드) | nftables 모드에서 flowtable 연동 가능 |
| OVN-Kubernetes | OVS + Geneve | L3/L4 (OVS ACL) | OVS conntrack | OVS-DPDK TC offload | SmartNIC OVS offload 시 HW 가속 |
| Antrea | OVS | L3/L4/L7 (일부) | OVS conntrack | OVS HW offload | OVS bridge offload 활용 |
| kube-router | iptables + IPVS | L3/L4 | 커널 conntrack | 가능 (수동 설정) | flowtable 수동 구성 필요 |
Hairpin/Loopback 오프로드와 East-West 트래픽 보안
전통적인 방화벽은 외부↔내부(North-South) 트래픽에 집중하지만, 현대 데이터센터에서는 전체 트래픽의 약 80%가 서버 간 East-West 통신입니다. Hairpin 오프로드는 동일 NIC에 연결된 VM/컨테이너 간 트래픽을 외부 스위치 없이 NIC 내부에서 전달하면서도 NGFW 수준의 보안 검사를 하드웨어에서 수행하는 기술입니다.
Hairpin 개념과 데이터센터 East-West 보안
Hairpin(헤어핀) 또는 Loopback(루프백)이란 패킷이 NIC으로 들어온 뒤 외부 스위치를 거치지 않고 같은 NIC 내부에서 방향을 바꿔(U-turn) 다른 가상 포트로 나가는 전달 방식입니다. 마치 머리핀처럼 들어온 경로에서 되돌아가는 형태이므로 이렇게 부릅니다.
East-West 트래픽 보안의 중요성
데이터센터 트래픽 패턴이 East-West 중심으로 전환된 배경과 보안 위협을 정리합니다.
| 항목 | North-South | East-West |
|---|---|---|
| 방향 | 외부 인터넷 ↔ 내부 서버 | 내부 서버 ↔ 내부 서버 |
| 트래픽 비율 | 약 20% | 약 80% |
| 전통 방화벽 커버리지 | 완전 커버 | 대부분 미검사(blind spot) |
| 대표 위협 | 외부 침입, DDoS | 측면 이동(Lateral Movement), 내부자 공격 |
| 대응 전략 | 경계 방화벽, IPS | 마이크로세그멘테이션(Microsegmentation) |
측면 이동(Lateral Movement)은 공격자가 초기 침입(예: 피싱, 취약점 악용)으로 하나의 VM에 접근한 뒤, 같은 네트워크 세그먼트의 다른 VM으로 이동하며 공격 범위를 넓히는 기법입니다. 전통 경계 방화벽은 이미 내부에 있는 공격자의 횡방향 이동을 탐지하지 못합니다.
마이크로세그멘테이션은 각 VM/컨테이너를 개별 보안 영역으로 분리하여, 같은 호스트 내 VM 간 통신에도 방화벽 정책을 적용하는 접근법입니다. 이를 하드웨어 수준에서 구현하려면 동일 NIC의 VF/SF 간 트래픽을 NIC 내부에서 검사하고 전달하는 Hairpin 오프로드가 필수적입니다.
Hairpin이 중요한 이유
- 성능: 외부 스위치를 경유하면 레이턴시가 수 μs 추가되고, 스위치 대역폭을 소비합니다. Hairpin은 NIC 내부에서 수십 ns 이내에 전달을 완료합니다.
- 확장성: 호스트당 수백 개의 VM/컨테이너가 상호 통신할 때, 모든 트래픽을 외부로 보내면 스위치 포트 용량이 병목이 됩니다.
- 보안: NIC eSwitch 내부에서 CT(Connection Tracking) + NAT + ACL 파이프라인을 적용할 수 있으므로, 모든 East-West 트래픽에 제로 트러스트(Zero Trust) 정책을 실현합니다.
- 비용: 별도의 East-West 전용 방화벽 어플라이언스 없이 기존 SmartNIC으로 보안 기능을 구현합니다.
TC flower Hairpin 규칙 구현
Hairpin 오프로드의 핵심은 TC flower의 mirred 리다이렉트 액션과 eSwitch FDB Hairpin 엔트리입니다. 동일 NIC의 두 representor 포트 간에 mirred egress redirect를 설정하면, eSwitch가 이를 인식하여 하드웨어 Hairpin 큐를 생성합니다.
기본 Hairpin 규칙 설정
VF0과 VF1이 같은 물리 NIC(enp1s0f0)에 속할 때, 두 VF의 representor 포트 간 트래픽을 하드웨어에서 직접 전달하는 규칙입니다.
# VF representor 포트 확인
# VF0_rep = enp1s0f0_0, VF1_rep = enp1s0f0_1
ip link show dev enp1s0f0_0
ip link show dev enp1s0f0_1
# eSwitch 모드를 switchdev로 설정 (이미 설정된 경우 생략)
devlink dev eswitch set pci/0000:01:00.0 mode switchdev
# VF0 → VF1 방향 Hairpin 규칙 (skip_sw: HW만 처리)
tc qdisc add dev enp1s0f0_0 ingress
tc filter add dev enp1s0f0_0 ingress protocol ip \
flower skip_sw \
src_mac aa:bb:cc:dd:ee:00 \
dst_mac aa:bb:cc:dd:ee:01 \
action mirred egress redirect dev enp1s0f0_1
# VF1 → VF0 방향 Hairpin 규칙 (양방향 필요)
tc qdisc add dev enp1s0f0_1 ingress
tc filter add dev enp1s0f0_1 ingress protocol ip \
flower skip_sw \
src_mac aa:bb:cc:dd:ee:01 \
dst_mac aa:bb:cc:dd:ee:00 \
action mirred egress redirect dev enp1s0f0_0
mlx5 Hairpin 큐 페어(Queue Pair) 내부 동작
Mellanox/NVIDIA ConnectX 시리즈에서 Hairpin은 하드웨어 레벨의 큐 페어(QP) 연결로 구현됩니다. 두 VF의 RQ(Receive Queue)와 SQ(Send Queue)를 NIC 내부에서 직접 연결하여, 패킷이 호스트 메모리를 거치지 않고 NIC ASIC 내에서 전달됩니다.
| 구성 요소 | 설명 |
|---|---|
| Hairpin RQ | 소스 VF의 수신 큐. 패킷을 호스트 메모리 대신 Hairpin SQ로 직접 전달 |
| Hairpin SQ | 대상 VF의 송신 큐. Hairpin RQ에서 받은 패킷을 대상 VF로 전송 |
| FDB Hairpin Entry | eSwitch FDB(Forwarding Database)에 설치된 Hairpin 전달 규칙 |
| Modify Header | Hairpin 경로에서 MAC/IP/Port 헤더 변경(NAT 등) 수행 |
# Hairpin 큐 생성 확인 (mlx5 디버그)
# /sys/kernel/debug/mlx5/ 에서 hairpin 관련 정보 확인
cat /sys/kernel/debug/mlx5/0000:01:00.0/hairpin_queues 2>/dev/null
# eSwitch FDB 엔트리 확인
tc -s filter show dev enp1s0f0_0 ingress
# 출력 예시:
# filter protocol ip pref 49152 flower chain 0
# in_hw in_hw_count 1 ← HW에 설치됨
# action order 1: mirred (Egress Redirect to device enp1s0f0_1) pipe
# Sent 1523456 bytes 10234 pkt ← HW에서 처리된 통계
5-tuple 기반 Hairpin ACL
MAC 주소뿐 아니라 5-tuple(src_ip, dst_ip, src_port, dst_port, protocol)로 세밀하게 Hairpin 정책을 적용할 수 있습니다.
# 특정 서비스 포트만 Hairpin 허용 (예: VM0 → VM1의 TCP/443)
tc filter add dev enp1s0f0_0 ingress protocol ip \
flower skip_sw \
ip_proto tcp \
src_ip 10.0.0.10 dst_ip 10.0.0.11 \
dst_port 443 \
action mirred egress redirect dev enp1s0f0_1
# 나머지 트래픽은 차단 (implicit deny)
tc filter add dev enp1s0f0_0 ingress protocol ip \
prio 99 flower skip_sw \
action drop
Hairpin + conntrack 오프로드 조합
Hairpin 전달에 conntrack(CT) 오프로드를 결합하면, NIC 하드웨어 내부에서 스테이트풀 방화벽 + NAT + ACL을 모두 처리하는 완전한 East-West NGFW 파이프라인을 구현할 수 있습니다.
TC flower chain 기반 Hairpin + CT 파이프라인
TC flower의 chain 기능을 활용하여 Hairpin 경로에 다단계 보안 파이프라인을 구성합니다. chain 0에서 CT 액션을 호출하고, chain 1에서 CT 상태에 따라 전달/차단을 결정합니다.
# === Hairpin + CT + NAT 완전 오프로드 파이프라인 ===
# 1단계: chain 0 — conntrack zone 1에 패킷 등록
tc filter add dev enp1s0f0_0 ingress protocol ip \
chain 0 flower skip_sw \
ip_proto tcp \
ct_state -trk \
action ct zone 1 nat pipe \
action goto chain 1
# 2단계: chain 1 — ESTABLISHED 상태 확인 후 Hairpin 전달
tc filter add dev enp1s0f0_0 ingress protocol ip \
chain 1 flower skip_sw \
ct_state +trk+est \
action mirred egress redirect dev enp1s0f0_1
# 2-1단계: chain 1 — 새 연결(NEW)이면 특정 포트만 허용
tc filter add dev enp1s0f0_0 ingress protocol ip \
chain 1 flower skip_sw \
ct_state +trk+new \
ip_proto tcp dst_port 443 \
action ct commit zone 1 \
action mirred egress redirect dev enp1s0f0_1
# 2-2단계: chain 1 — 허용되지 않은 새 연결은 차단
tc filter add dev enp1s0f0_0 ingress protocol ip \
chain 1 prio 99 flower skip_sw \
ct_state +trk+new \
action drop
# 역방향 규칙 (VF1 → VF0)
tc filter add dev enp1s0f0_1 ingress protocol ip \
chain 0 flower skip_sw \
ip_proto tcp \
ct_state -trk \
action ct zone 1 nat pipe \
action goto chain 1
tc filter add dev enp1s0f0_1 ingress protocol ip \
chain 1 flower skip_sw \
ct_state +trk+est \
action mirred egress redirect dev enp1s0f0_0
Hairpin + NAT 오프로드
East-West 트래픽에도 NAT가 필요한 경우(예: 서비스 VIP → 실제 VM IP 변환)가 있습니다. CT 액션에 NAT 파라미터를 추가하면 하드웨어에서 NAT 변환까지 처리합니다.
# DNAT: VIP 10.0.0.100:443 → VM1 실제 IP 10.0.0.11:8443
tc filter add dev enp1s0f0_0 ingress protocol ip \
chain 0 flower skip_sw \
ip_proto tcp \
dst_ip 10.0.0.100 dst_port 443 \
ct_state -trk \
action ct zone 1 nat commit \
ct_mark 0x1 \
nat dst addr 10.0.0.11 port 8443 pipe \
action goto chain 1
tc filter add dev enp1s0f0_0 ingress protocol ip \
chain 1 flower skip_sw \
ct_state +trk+est ct_mark 0x1 \
action mirred egress redirect dev enp1s0f0_1
성능 비교: Hairpin HW vs Software Bridge vs 외부 스위치
| 전달 경로 | 레이턴시 | 처리량(64B) | CPU 사용률 | 보안 검사 |
|---|---|---|---|---|
| Hairpin HW (eSwitch) | ~50 ns | 최대 200 Gbps | 0% | CT + NAT + ACL (HW) |
| Linux Bridge (SW) | ~5 μs | ~20 Gbps | 40~60% | iptables/nftables (SW) |
| OVS DPDK | ~2 μs | ~40 Gbps | 100% (전용 코어) | OVS flow rules (SW) |
| 외부 스위치 루프 | ~10 μs | 스위치 포트 속도 | 0% (호스트) | 스위치 ACL만 |
Scalable Function(SF)과 마이크로세그멘테이션
Scalable Function(SF, 확장 가능 함수)은 NVIDIA ConnectX-6 Dx 이상에서 도입된 경량 서브 함수(Sub-function)입니다. VF(Virtual Function)보다 더 유연하게 생성·삭제할 수 있으며, 각 SF에 전용 representor 포트가 할당되어 개별 보안 정책을 적용할 수 있습니다.
SF vs VF 비교
| 항목 | VF (Virtual Function) | SF (Scalable Function) |
|---|---|---|
| 생성 방식 | sriov_numvfs (재부팅 필요 가능) | devlink sf create (동적, 무중단) |
| 최대 개수 | PCIe 제한 (보통 128~256개) | 수천 개 (ASIC 제한까지) |
| 리소스 격리 | PCI 기능 단위 | NIC 내부 논리 분리 |
| Representor | VF당 1개 | SF당 1개 |
| 동적 생성/삭제 | 제한적 | 완전 동적 (Kubernetes 연동 적합) |
| eSwitch Hairpin | 지원 | 지원 |
| 적합 환경 | 고정 VM 환경 | Kubernetes Pod, 동적 워크로드 |
SF 생성 및 보안 정책 적용
# === SF 생성 (devlink) ===
# 1. SF 포트 생성
devlink port add pci/0000:01:00.0 flavour pcisf pfnum 0 sfnum 10
# 출력: pci/0000:01:00.0/32768: ... flavour pcisf ...
# 2. SF 활성화
devlink port function set pci/0000:01:00.0/32768 \
hw_addr 00:11:22:33:44:10 state active
# 3. SF 디바이스 확인 (representor 자동 생성)
devlink port show pci/0000:01:00.0/32768
# representor: en3f0pf0sf10
# 4. 추가 SF 생성 (Pod별 1개)
devlink port add pci/0000:01:00.0 flavour pcisf pfnum 0 sfnum 11
devlink port function set pci/0000:01:00.0/32769 \
hw_addr 00:11:22:33:44:11 state active
# representor: en3f0pf0sf11
# === SF 간 마이크로세그멘테이션 정책 ===
# SF10(웹서버 Pod) → SF11(DB Pod): TCP/5432만 허용
tc qdisc add dev en3f0pf0sf10 ingress
tc filter add dev en3f0pf0sf10 ingress protocol ip \
chain 0 flower skip_sw \
ip_proto tcp ct_state -trk \
action ct zone 100 pipe \
action goto chain 1
tc filter add dev en3f0pf0sf10 ingress protocol ip \
chain 1 flower skip_sw \
ct_state +trk+est \
action mirred egress redirect dev en3f0pf0sf11
tc filter add dev en3f0pf0sf10 ingress protocol ip \
chain 1 flower skip_sw \
ct_state +trk+new \
ip_proto tcp dst_port 5432 \
action ct commit zone 100 \
action mirred egress redirect dev en3f0pf0sf11
# 그 외 모든 트래픽 차단 (Zero Trust)
tc filter add dev en3f0pf0sf10 ingress protocol ip \
chain 1 prio 99 flower skip_sw \
action drop
# 역방향: SF11 → SF10 (TCP 응답 트래픽만 허용)
tc qdisc add dev en3f0pf0sf11 ingress
tc filter add dev en3f0pf0sf11 ingress protocol ip \
chain 0 flower skip_sw \
ip_proto tcp ct_state -trk \
action ct zone 100 pipe \
action goto chain 1
tc filter add dev en3f0pf0sf11 ingress protocol ip \
chain 1 flower skip_sw \
ct_state +trk+est \
action mirred egress redirect dev en3f0pf0sf10
Kubernetes CNI 연동
# Kubernetes NetworkPolicy 예시 (Cilium + SmartNIC offload)
# 이 정책은 Cilium이 TC flower 규칙으로 변환하여 SF representor에 설치합니다
# Pod의 SF representor에 설치된 TC 규칙 확인
kubectl exec -n kube-system cilium-xxxx -- \
tc -s filter show dev lxc_pod_web ingress
# SF 상태 모니터링
devlink port show | grep "pcisf"
devlink port function show pci/0000:01:00.0/32768
Hairpin 오프로드 아키텍처 다이어그램
아래 다이어그램은 동일 SmartNIC 내에서 Hairpin 오프로드를 통해 VM 간 트래픽을 하드웨어에서 보안 검사하고 전달하는 구조와, 비교를 위한 외부 스위치 경유 경로를 보여줍니다.
eBPF 기반 차세대 NGFW
이 주제는 별도 페이지로 분리되었습니다: eBPF + P4 프로그래머블 NGFW 파이프라인 — BPF netfilter, Cilium, P4 match-action, Tofino/FPGA 심층 가이드
P4 프로그래머블 파이프라인 NGFW 오프로드
이 주제는 별도 페이지로 분리되었습니다: eBPF + P4 프로그래머블 NGFW 파이프라인
대규모 규칙 관리
프로덕션 NGFW 환경에서는 수만~수십만 개의 ACL 규칙, 수백만 개의 conntrack 엔트리를 관리해야 합니다. 규칙 수가 증가할수록 삽입 지연, 메모리 사용량, 조회 성능이 달라지며, HW offload의 한계점도 드러납니다.
대규모 규칙 최적화 전략
| 전략 | 설명 | 적용 효과 | 구현 방법 |
|---|---|---|---|
| 계층적 규칙 구조 | TC chain으로 다단계 매칭 | 규칙 수 80% 감소 | chain 0→1→2 계층화 |
| nftables set/map | IP 집합을 set으로 그룹화 | 단일 규칙으로 수천 IP 매칭 | set allowlist { type ipv4_addr; flags interval; } |
| batch 업데이트 | 규칙 추가/삭제 일괄 처리 | 삽입 시간 10배 향상 | nft -f ruleset.nft |
| nftables concat | 복합 키로 멀티 필드 매칭 | 규칙 수 대폭 감소 | ip saddr . tcp dport |
| HW 규칙 분할 | 자주 매칭되는 규칙 우선 HW | HW TCAM 효율 극대화 | 상위 10% 규칙만 HW offload |
| CT 기반 offload | ACL 대신 CT offload 사용 | ACL 규칙 수 무관 | 첫 패킷만 ACL 검사 |
# nftables set 활용: 대규모 IP 목록 효율적 관리
nft add table inet firewall
nft add set inet firewall blocklist {
type ipv4_addr\;
flags interval\;
auto-merge\;
}
# 블록리스트에 IP 범위 일괄 추가 (배치)
nft add element inet firewall blocklist {
10.0.0.0/8,
172.16.0.0/12,
192.168.0.0/16,
100.64.0.0/10
}
# set 참조 규칙: 단 1줄로 수천 개 IP 매칭
nft add rule inet firewall forward ip saddr @blocklist drop
# nftables concat: 복합 키 매칭
nft add set inet firewall svc_acl {
type ipv4_addr . inet_service\;
}
nft add element inet firewall svc_acl {
10.0.1.0/24 . 80,
10.0.1.0/24 . 443,
10.0.2.0/24 . 8080,
10.0.3.0/24 . 5432
}
nft add rule inet firewall forward ip saddr . tcp dport @svc_acl accept
규칙 수 증가 시 성능 벤치마크
#!/bin/bash
# 대규모 규칙 삽입 벤치마크 스크립트
RULE_COUNTS="100 1000 10000 50000 100000"
for count in $RULE_COUNTS; do
echo "=== Testing $count rules ==="
# nftables batch 파일 생성
echo "flush chain inet firewall test_chain" > /tmp/bench.nft
for i in $(seq 1 $count); do
oct3=$(( (i / 256) % 256 ))
oct4=$(( i % 256 ))
echo "add rule inet firewall test_chain ip saddr 10.${oct3}.${oct4}.0/24 accept" >> /tmp/bench.nft
done
# 삽입 시간 측정
time_start=$(date +%s%N)
nft -f /tmp/bench.nft
time_end=$(date +%s%N)
insert_ms=$(( (time_end - time_start) / 1000000 ))
echo "Insert time: ${insert_ms}ms"
# HW offload된 규칙 수 확인
hw_rules=$(tc -s filter show dev eth0 ingress 2>/dev/null | grep -c "in_hw")
echo "HW offloaded rules: $hw_rules"
# Lookup 벤치마크 (iperf3로 처리량 측정)
iperf3 -c 10.0.2.1 -t 5 -P 4 --json | jq '.end.sum_sent.bits_per_second'
# 메모리 사용량
echo "conntrack memory: $(cat /proc/slabinfo | grep nf_conntrack | awk '{print $3 * $4}')"
nft flush chain inet firewall test_chain
done
-ENOSPC 에러와 함께 SW fallback됩니다. 이때 dmesg에 "failed to offload rule" 메시지가 기록됩니다. 프로덕션에서는 ethtool -S eth0 | grep tc_offload로 HW 규칙 사용량을 모니터링하고, 80% 임계값에서 경보를 설정하세요.
멀티 클러스터 NGFW offload 연동
Kubernetes 멀티 클러스터 환경에서 NGFW offload를 활용하려면 CNI 플러그인, Service Mesh, Network Policy를 HW offload와 통합해야 합니다. 이 섹션에서는 대표적인 아키텍처 패턴과 구현 방법을 다룹니다.
Kubernetes CNI + NGFW offload 아키텍처
| CNI 플러그인 | HW offload 지원 | NGFW 연동 방법 | 비고 |
|---|---|---|---|
| OVN-Kubernetes | OVS TC offload | NetworkPolicy → OVS OpenFlow → TC flower HW | NVIDIA 공식 지원 |
| Cilium | eBPF offload | CiliumNetworkPolicy → eBPF → XDP HW offload | Netronome nfp 지원 |
| Calico | eBPF dataplane | GlobalNetworkPolicy → eBPF TC → HW (제한적) | XDP offload 개발 중 |
| SR-IOV CNI | VF representor | Pod VF → eSwitch TC flower → HW ACL | SRIOV + switchdev 필수 |
| Antrea | OVS TC offload | AntreaPolicy → OVS → TC flower HW | VMware 주도 |
# Kubernetes NetworkPolicy → HW offload 예시 (OVN-Kubernetes)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-tier-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
role: loadbalancer
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 443
egress:
- to:
- podSelector:
matchLabels:
tier: app
ports:
- protocol: TCP
port: 8080
# OVN-Kubernetes가 이 정책을 OpenFlow → TC flower → HW offload로 변환
# Pod VF representor에 eSwitch FDB 규칙 자동 설치
# OVN-Kubernetes HW offload 활성화 확인
kubectl -n ovn-kubernetes get configmap ovn-config -o yaml | grep hw-offload
# hw-offload: "true"
# Pod의 VF representor에 설치된 HW 규칙 확인
# (노드에서 실행)
tc -s filter show dev enp3s0f0_2 ingress # Pod의 VF rep
# filter protocol ip pref 100 flower chain 1
# ct_state +established+tracked
# in_hw in_hw_count 1
# action order 1: mirred (Egress Redirect to device enp3s0f0_3)
# HW offload된 NetworkPolicy 확인 (OVN northd)
ovn-nbctl list ACL | grep "hw_offload"
고가용성(HA) NGFW offload
NGFW offload 환경에서 HA(고가용성)를 구현할 때, HW에 설치된 flow 엔트리의 동기화가 가장 큰 과제입니다. Active-Standby 및 Active-Active 구성별 세션 동기화 전략을 다룹니다.
HA 모드별 offload 동기화
| HA 모드 | 세션 동기화 | HW flow 처리 | failover 시간 | 제약사항 |
|---|---|---|---|---|
| Active-Standby | conntrackd FTFW | Standby: SW only, failover 시 HW re-offload | 2-5초 (HW re-install) | failover 중 일시적 성능 저하 |
| Active-Active (ECMP) | conntrackd + flow hash | 양쪽 모두 HW offload, hash 기반 분산 | <1초 (hash rehash) | 비대칭 트래픽 처리 복잡 |
| Active-Active (bonding) | conntrackd 양방향 | 양쪽 NIC에 동일 HW flow | <1초 | bond 모드 제약 (mode 4) |
| Cluster (3+ 노드) | conntrackd multicast | 각 노드 독립 HW offload | 2-10초 | 대역폭 제한, 동기화 지연 |
# conntrackd HA 구성: HW offload 환경 최적화
cat /etc/conntrackd/conntrackd.conf
Sync {
Mode FTFW {
DisableExternalCache Off
CommitTimeout 1800
PurgeTimeout 5
}
# HW offload된 엔트리도 동기화 대상에 포함
# (OFFLOAD 상태의 conntrack 엔트리는 주기적으로 SW에 stats 동기화)
Multicast {
IPv4_address 225.0.0.50
Group 3780
IPv4_interface 10.0.0.1
Interface eth2
SndSocketBuffer 1249280
RcvSocketBuffer 1249280
Checksum on
}
}
General {
Nice -20
# 1M conntrack 엔트리 동기화 시 메모리
HashSize 524288
HashLimit 1048576
# HW offload 엔트리 필터: offload 상태도 동기화
Filter From Kernelspace {
Protocol Accept {
TCP
UDP
ICMP
}
Address Ignore {
IPv4_address 127.0.0.1
}
}
# Failover 시 HW flow re-install 스크립트
EventIterationLimit 200
}
# Failover 스크립트: HW flow 재설치
cat /etc/conntrackd/primary-backup.sh
#!/bin/bash
case "$1" in
primary)
conntrackd -c
conntrackd -f
conntrackd -R
# HW offload 재활성화
nft flush flowtable inet firewall ft
nft add flowtable inet firewall ft \
{ hook ingress priority 0\; devices = { eth0, eth1 }\; flags offload\; }
logger "NGFW HA: Primary role - HW offload re-enabled"
;;
backup)
conntrackd -t
# Standby에서는 SW flowtable만 유지 (HW 리소스 절약)
nft delete flowtable inet firewall ft 2>/dev/null
nft add flowtable inet firewall ft \
{ hook ingress priority 0\; devices = { eth0, eth1 }\; }
logger "NGFW HA: Backup role - SW flowtable only"
;;
fault)
conntrackd -t
logger "NGFW HA: Fault state"
;;
esac
NGFW offload 트러블슈팅
NGFW offload 문제는 HW/SW/드라이버의 복합적 상호작용에서 발생합니다. 이 섹션에서는 실전에서 자주 겪는 문제와 체계적 디버깅 방법을 제공합니다.
트러블슈팅 의사결정 트리
자주 발생하는 문제와 해결
| 증상 | 원인 | 진단 명령 | 해결 방법 |
|---|---|---|---|
TC filter에 in_hw 미표시 | NIC가 해당 규칙 타입 미지원 | dmesg | grep "offload" | 지원되는 match/action 조합으로 변경 |
| 간헐적 패킷 드롭 | TCAM 용량 초과 → 일부 규칙 SW fallback | ethtool -S eth0 | grep tc_offload_fail | 규칙 수 축소 또는 CT offload 방식 전환 |
| conntrack 테이블 가득 참 | HW offload 엔트리도 SW 테이블 점유 | conntrack -C vs nf_conntrack_max | sysctl nf_conntrack_max 증가 |
| HW offload 후 카운터 0 | 정상 (HW에서 처리) | ethtool -S의 HW 카운터 확인 | ethtool/debugfs 카운터 사용 |
| HA failover 시 긴 끊김 | HW flow 재설치 지연 | time nft list flowtable | failover 스크립트에 SW flowtable 선행 활성화 |
| NAT offload 실패 | NAT + CT 복합 offload 미지원 | dmesg | grep "nat offload" | CX-6 Dx 이상 사용 또는 SW NAT fallback |
| OVS flow offload 부분만 동작 | tc-policy=skip_sw 미설정 | ovs-vsctl get Open_vSwitch . other_config | tc-policy=skip_sw 설정 후 OVS 재시작(Reboot) |
# 종합 진단 스크립트
#!/bin/bash
echo "=== NGFW Offload 진단 ==="
IFACE="${1:-enp3s0f0}"
echo ""
echo "1. HW TC offload 상태:"
ethtool -k $IFACE | grep "hw-tc-offload"
echo ""
echo "2. eSwitch 모드:"
devlink dev eswitch show pci/$(ethtool -i $IFACE | awk '/bus-info/ {print $2}') 2>/dev/null
echo ""
echo "3. TC flower HW 규칙 수:"
tc -s filter show dev $IFACE ingress 2>/dev/null | grep -c "in_hw"
echo ""
echo "4. Conntrack 상태:"
echo " Total: $(conntrack -C)"
echo " Max: $(sysctl -n net.netfilter.nf_conntrack_max)"
echo " Offloaded: $(conntrack -L 2>/dev/null | grep -c '\[OFFLOAD\]')"
echo ""
echo "5. HW 카운터:"
ethtool -S $IFACE 2>/dev/null | grep -E "ct_offload|flow_table|tc_offload" | head -10
echo ""
echo "6. 최근 offload 관련 커널 메시지:"
dmesg | grep -iE "offload|flower|flow_table|eswitch" | tail -10
echo ""
echo "7. devlink trap 통계 (drop 항목):"
devlink -s trap show pci/$(ethtool -i $IFACE | awk '/bus-info/ {print $2}') 2>/dev/null | \
grep -A2 "type drop" | grep "packets [1-9]" | head -5
echo ""
echo "=== 진단 완료 ==="
커널 HW 오프로드 인터페이스 심층 레퍼런스
이 주제는 별도 페이지로 분리되었습니다: 커널 HW 오프로드 인터페이스 레퍼런스 — TC action 12종, Bridge/switchdev, FIB/Routing, Tunnel, qdisc, devlink 심층 레퍼런스
- NGFW 하드웨어 오프로드 — 오프로드 아키텍처 3대 유형, 데이터 플레인, 세션 생명주기, 구현 패턴
- NGFW 암/복호화 오프로드 — kTLS, IPSec, MACsec, Intel QAT, SSL Inspection
- 상용 NGFW HW 아키텍처 — Fortinet NP7, Palo Alto SP3, Check Point, Juniper
- HW 오프로드 인터페이스 레퍼런스 — TC action 12종, switchdev, FIB, Tunnel, devlink
- eBPF + P4 NGFW 파이프라인 — BPF netfilter, Cilium, P4 match-action
- Netfilter Flowtable — SW/HW 오프로드 상세 메커니즘
- eSwitch (Embedded Switch) — TC flower offload 실전
- SmartNIC/DPU — DPU 아키텍처와 제품군
- NFQUEUE & DPI 엔진 통합 — Suricata/nDPI 연동