nftables Gateway Egress 통제 가이드¶
nftables는 Linux 커널의 최신 패킷 필터 프레임워크임.
본 문서에서는 Reverse Proxy Gateway 서버에서 내부망(192.168.0.0/24)으로 나가는
TCP 아웃바운드 트래픽을 최소 허용(allowlist) 방식으로 통제하는 정책을 정의함.
본 서버의 목적은 Nginx Reverse Proxy Gateway이며,
외부 트래픽은 Nginx가 수신하고 내부 서버로 proxy_pass 하여 중계함.
Internet
↓
공유기 (Port Forward)
↓
Gateway Server (Linux + Nginx)
↓
Internal Servers (192.168.0.0/24)
목적: Gateway 서버가 내부망 전체에 임의 접근하지 못하도록 제한하고,
실제 Reverse Proxy 대상 backendIP:port만 허용함.
1. 왜 필요한가¶
Gateway 서버는 외부와 내부망 사이의 중간 지점이므로,
서버 침해 시 공격자가 내부망 전체로 이동(Pivoting / Lateral Movement)할 가능성이 존재함.
따라서 다음을 만족하도록 설계함.
- 외부 인바운드는 firewalld 로 관리 (L3)
- 내부망 아웃바운드는 nftables 로 관리 (L4)
- 허용 대상은 Nginx가 실제 proxy_pass 하는 backend
IP:port만 등록 - DB, SSH, Redis 등 내부 서비스 포트는 허용하지 않음
2. 전제 조건¶
본 정책은 다음 전제를 둠.
- Nginx Reverse Proxy 사용
- 내부망:
192.168.0.0/24 - 내부 backend는 주로
80,443,3000,3001등의 HTTP/HTTPS 계열 포트 사용 - MySQL(3306), Redis(6379), SSH(22) 등은 Gateway에서 직접 접근하지 않도록 함
- localhost backend (
127.0.0.1:3000등)는 본 정책의 차단 대상이 아님
3. firewalld 와 nftables 병행 사용 주의¶
일반론적으로는
- 단순/표준 정책 → firewalld
- 복잡/고성능/정밀 정책 → nftables
다음과 같이 역할을 분리하여 운영함.
- firewalld
- 인바운드 정책
http,https- 내부망만
ssh
- nftables
- Gateway → Internal Network (
192.168.0.0/24) 아웃바운드 allowlist
- Gateway → Internal Network (
⚠️ 주의
firewalld 와 nftables 를 함께 운용하는 경우
규칙 충돌, reload 시점, 운영 절차를 명확히 관리해야 함.
특히 firewalld reload 이후에도 nftables 커스텀 rule 이 유지되는지 확인해야 함.
운영 원칙¶
- firewalld 는 인바운드 제어 전용
- nftables 는 내부망 egress 통제 전용
- 두 정책이 서로 다른 chain/table 을 사용하도록 분리
- 변경 시 반드시 테스트 후 반영
본 방식은 운영 난이도가 높은 고급(Advanced) 패턴임.
표준 환경에서는 firewalld 단독 또는 nftables 단독 운용이 일반적이며,
병행 운용 시에는 재적용 절차와 검증 절차를 반드시 표준화해야 함.
4. 보안 목표¶
허용할 트래픽:
- loopback (
lo) - established / related
- Nginx가 실제로
proxy_pass하는 내부 backendIP:port
차단할 트래픽:
192.168.0.0/24전체에 대한 임의 TCP 접근- DB 포트 접근
- SSH 포트 접근
- 내부망 포트 스캔 성격 접근
예:
- 허용:
192.168.0.10:3000 - 허용:
192.168.0.11:3001 - 허용:
192.168.0.20:80 - 허용:
192.168.0.21:443 - 차단:
192.168.0.30:22 - 차단:
192.168.0.40:3306 - 차단:
192.168.0.50:6379
DNS outbound¶
시스템 패키지 업데이트, certbot 인증서 갱신, 외부 API 호출 등을 위해
Gateway 서버의 DNS outbound 트래픽은 허용됨.
일반적으로 다음 트래픽이 발생할 수 있음.
- UDP 53
- TCP 53
본 nftables 정책은 내부망(192.168.0.0/24) 접근 통제 목적이므로
외부 DNS 서버로의 트래픽에는 영향을 주지 않음.
5. nftables 설치¶
Rocky Linux 9 에서는 기본 포함되는 경우가 많지만, 명시적으로 설치 상태를 맞춤.
sudo dnf install -y nftables
설치 확인:
rpm -q nftables
nft --version
6. nftables 서비스 활성화 여부¶
운영 권장¶
본 문서에서는 firewalld 와의 병행 운용을 전제로 하므로
nftables.service 를 무조건 활성화하는 방식보다는
별도 rule 파일을 명시적으로 로드하는 방식을 권장함.
즉, 아래를 기본 원칙으로 함.
firewalld.service는 활성화 유지nftables.service는 즉시 활성화하지 않음- 커스텀 egress rule 은 별도 파일로 관리
- 테스트 완료 후 systemd unit 또는 운영 스크립트로 로드
7. 규칙 파일 경로¶
권장 경로:
/etc/nftables/gateway-egress.nft
디렉터리 생성:
sudo mkdir -p /etc/nftables
8. 규칙 설계 방식¶
nftables 의 set 과 concatenation(ipv4_addr . inet_service) 를 사용하여
IP:port 조합 allowlist 를 구성함.
192.168.0.10 . 3000
192.168.0.11 . 3001
192.168.0.20 . 80
192.168.0.21 . 443
장점:
- 허용 목록이 명확함
- Nginx
proxy_pass대상과 1:1 대응 가능 - 신규 backend 추가 시 allowlist 만 추가하면 됨
- DB / SSH / Redis 등은 등록하지 않는 한 접근 불가
운영 기준: allowlist 는 활성 Nginx proxy_pass 기준으로 관리¶
이 문서의 allowed_backend_tcp 는 임의로 작성하지 않음.
반드시 현재 운영 중인 Nginx 설정의 proxy_pass 대상 IP:port 를 기준으로 구성함.
즉 다음 원칙을 사용함.
- Nginx에 없는 내부
IP:port는 allowlist 에 넣지 않음 - Nginx에 새
proxy_pass가 추가되면 nftables allowlist 도 함께 반영함 - Nginx에서 제거된 backend 는 nftables allowlist 에서도 제거함
- 가능하면 domain 과
IP:port매핑표를 함께 관리함
점검 예시:
sudo nginx -T 2>/dev/null | grep -n proxy_pass
출력 예시:
proxy_pass http://192.168.0.200:3001;
proxy_pass http://192.168.0.200:3002;
proxy_pass https://192.168.0.215;
proxy_pass http://127.0.0.1:3000;
위 결과를 nftables allowlist 로 반영하면 다음과 같음.
set allowed_backend_tcp {
type ipv4_addr . inet_service
elements = {
192.168.0.200 . 3001,
192.168.0.200 . 3002,
192.168.0.215 . 443
}
}
변환 기준:
http://192.168.0.200:3001→192.168.0.200 . 3001http://192.168.0.200:3002→192.168.0.200 . 3002https://192.168.0.215→192.168.0.215 . 443http://127.0.0.1:3000은 내부망192.168.0.0/24통제 대상이 아니므로 본 allowlist 대상이 아님
운영 시에는 위 결과를 기준으로 /etc/nftables/gateway-egress.nft 의
allowed_backend_tcp 와 1:1로 대조하는 것을 표준 절차로 함.
9. 기본 규칙 예시¶
본 정책은 TCP backend 접근 통제 목적이므로 UDP 트래픽은 차단하지 않음. 또한 예시 규칙은 IPv4 내부망(192.168.0.0/24) 기준임.
내부망 전체 IPv4 트래픽을 차단하려면 다음 규칙을 사용함.
ip daddr 192.168.0.0/24 drop
TCP/UDP만 차단하려면 프로토콜별로 명시함.
meta l4proto tcp ip daddr 192.168.0.0/24 drop
meta l4proto udp ip daddr 192.168.0.0/24 drop
priority 100 은 firewalld rule 이후에 실행되도록 하기 위한 설정임.
table inet gateway_egress {
set allowed_backend_tcp {
type ipv4_addr . inet_service
elements = {
192.168.0.10 . 3000,
192.168.0.11 . 3001,
192.168.0.20 . 80,
192.168.0.21 . 443
}
}
chain output {
type filter hook output priority 100; policy accept;
oifname "lo" accept
ct state established,related accept
ip daddr . tcp dport @allowed_backend_tcp accept
meta l4proto tcp ip daddr 192.168.0.0/24 drop
}
}
의미¶
- 이미 수립된 연결은 허용
- loopback 은 허용
- 허용 목록(
allowed_backend_tcp)에 있는 내부 backend 만 허용 - 그 외 내부망 TCP 접근은 차단
10. 검증 모드 권장¶
운영 서버에서는 처음부터 차단 정책을 적용하지 않고
검증 모드(log) 를 먼저 적용하는 것을 권장함.
meta l4proto tcp ip daddr 192.168.0.0/24 log prefix "GW_EGRESS_DENY " level warn
로그 확인:
sudo journalctl -k -f
검증 완료 후 log 를 drop 으로 변경함.
11. 규칙 파일 작성¶
파일 생성:
sudo vi /etc/nftables/gateway-egress.nft
내용:
table inet gateway_egress {
set allowed_backend_tcp {
type ipv4_addr . inet_service
elements = {
192.168.0.10 . 3000,
192.168.0.11 . 3001,
192.168.0.20 . 80,
192.168.0.21 . 443
}
}
chain output {
type filter hook output priority 100; policy accept;
oifname "lo" accept
ct state established,related accept
ip daddr . tcp dport @allowed_backend_tcp accept
meta l4proto tcp ip daddr 192.168.0.0/24 drop
}
}
12. 적용 전 점검 (필수)¶
현재 nftables 상태 확인.
sudo nft list ruleset
문법 검사.
sudo nft -c -f /etc/nftables/gateway-egress.nft
backend 연결 테스트.
sudo nginx -T 2>/dev/null | grep -n proxy_pass
curl http://192.168.0.10:3000
curl http://192.168.0.11:3001
적용 전에는 반드시 Nginx proxy_pass 목록과 allowed_backend_tcp 항목이 일치하는지 확인함.
13. nftables 적용 절차¶
13.1 문법 검증¶
sudo nft -c -f /etc/nftables/gateway-egress.nft
13.2 기존 table 정리 (재적용 안정성)¶
sudo nft list table inet gateway_egress >/dev/null 2>&1 && sudo nft delete table inet gateway_egress
13.3 규칙 적용¶
sudo nft -f /etc/nftables/gateway-egress.nft
14-nftables Gateway Egress 자동 로드 가이드 방식으로
nftables-gateway-egress.service 를 운영 중인 서버에서는
직접 nft -f 를 반복 실행하기보다 아래 방식으로 재적용하는 것을 운영 표준으로 함.
sudo systemctl restart nftables-gateway-egress.service
13.4 적용 확인¶
sudo nft list table inet gateway_egress
위 절차를 사용하면 동일 명령을 반복 실행해도 적용 결과를 일정하게 유지할 수 있음.
14. 테스트 방법¶
허용 대상 테스트:
curl http://192.168.0.10:3000
curl http://192.168.0.11:3001
차단 대상 테스트:
nc -zv 192.168.0.30 22
nc -zv 192.168.0.40 3306
15. 롤백 방법¶
sudo nft delete table inet gateway_egress
16. 운영 절차¶
신규 backend 추가 시
- Nginx 설정 추가
- proxy_pass 대상 확인
- nftables allowlist 추가
- 문법 검사
- 적용
- 테스트
17. 운영 정책 요약¶
- firewalld: 인바운드 정책
- nftables: 내부망 egress 정책
- localhost backend 제외
- 내부망은 allowlist 기반 통제
18. 참고 사항¶
sudo nft list ruleset
firewalld reload 이후 표준 점검/재적용 절차:
sudo firewall-cmd --reload
sudo nft list table inet gateway_egress >/dev/null 2>&1 || sudo nft -f /etc/nftables/gateway-egress.nft
sudo nft list table inet gateway_egress
- firewalld reload 이후에도 커스텀 table 이 유지되는지 항상 확인함.
- table 이 없으면 즉시 재적용하여 egress 정책 공백을 방지함.
19. 참고 문서¶
- Red Hat firewalld Documentation
- nftables 공식 문서