Skip to content
isdnetworks
Go back

Docker host 모드에서 VPN 트래픽이 전달되지 않는 문제 해결

Updated:

Docker에서 hwdsl2/ipsec-vpn-server--network host 모드로 운영할 때, VPN 연결은 성공하지만 인터넷이나 LAN에 접근할 수 없는 문제를 겪었다. outBytes=0이 계속되는 상황이었다.

Table of contents

Open Table of contents

증상

# VPN 상태 확인
docker exec ipsec-vpn-server ipsec whack --trafficstatus
# 결과: outBytes=0 — 트래픽이 전달되지 않음

원인 분석

FORWARD 체인 추적

iptables 규칙을 하나씩 추적했다.

# FORWARD 체인 확인
iptables -L FORWARD -v -n
# 패킷 매칭은 되지만 최종 MASQUERADE까지 도달하지 않음

# POSTROUTING 확인
iptables -t nat -L POSTROUTING -v -n
# MASQUERADE 규칙은 존재하지만 카운터가 0

FORWARD 체인에서 패킷이 매칭은 되지만 어딘가에서 DROP되고 있었다.

핵심 원인: Docker의 nftables FORWARD 정책

Docker는 자체 네트워크 관리를 위해 nftables 기반 FORWARD 체인을 사용한다. --network host 모드에서 컨테이너의 iptables 규칙은 호스트와 양방향으로 공유되는데, Docker가 설정한 FORWARD 체인의 기본 정책이 drop이다.

# nftables 기반 iptables 확인
iptables-nft -L FORWARD -v -n
# policy DROP — Docker가 설정한 기본 정책

VPN 서버가 추가한 FORWARD ACCEPT 규칙은 iptables-legacy에 추가되지만, Docker는 iptables-nft를 사용한다. 두 테이블이 분리되어 있어서 VPN의 ACCEPT 규칙이 Docker의 DROP 정책을 우회하지 못한다.

해결

Docker의 DOCKER-USER 체인에 VPN 서브넷을 허용하는 규칙을 추가해야 한다. DOCKER-USER는 Docker가 사용자 정의 규칙을 위해 제공하는 체인으로, Docker 재시작 시에도 유지된다.

# VPN 서브넷 정의
L2TP_NET="192.168.42.0/24"
XAUTH_NET="192.168.43.0/24"

# DOCKER-USER 체인에 VPN 트래픽 허용
if iptables-nft -L DOCKER-USER -n >/dev/null 2>&1; then
  iptables-nft -I DOCKER-USER 1 -s "$XAUTH_NET" -j ACCEPT
  iptables-nft -I DOCKER-USER 2 -d "$XAUTH_NET" -j ACCEPT
  iptables-nft -I DOCKER-USER 3 -s "$L2TP_NET" -j ACCEPT
  iptables-nft -I DOCKER-USER 4 -d "$L2TP_NET" -j ACCEPT
fi

이 규칙을 VPN 서버의 커스텀 entrypoint 스크립트(run.sh)에 추가하여, 컨테이너 시작 시 자동으로 적용되도록 했다.

추가 MASQUERADE 규칙

외부 인터넷 접근을 위해 POSTROUTING에 MASQUERADE 규칙도 필요하다. LAN 접근은 NAT 없이 직접 라우팅한다.

# 외부 접근: MASQUERADE
iptables -t nat -A POSTROUTING -s "$XAUTH_NET" -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s "$L2TP_NET" -o eth0 -j MASQUERADE

# LAN 접근: NAT 없이 직접 라우팅 (RETURN)
iptables -t nat -I POSTROUTING 1 -s "$XAUTH_NET" -d 10.0.0.0/24 -j RETURN
iptables -t nat -I POSTROUTING 2 -s "$L2TP_NET" -d 10.0.0.0/24 -j RETURN

검증

# VPN 연결 후 트래픽 확인
docker exec ipsec-vpn-server ipsec whack --trafficstatus
# outBytes > 0 확인

# 클라이언트에서 인터넷 접근
ping 8.8.8.8        # 외부 DNS
ping 10.0.0.1       # LAN 게이트웨이

핵심 정리

계층문제해결
FORWARDDocker nftables policy DROPDOCKER-USER 체인에 VPN 서브넷 ACCEPT
POSTROUTINGMASQUERADE 미도달iptables NAT 규칙 추가
LAN 접근불필요한 NATRETURN 규칙으로 직접 라우팅

Docker host 모드에서 VPN을 운영할 때는 Docker의 nftables 방화벽과 VPN의 iptables 규칙이 다른 테이블에서 동작한다는 점을 반드시 인지해야 한다. DOCKER-USER 체인이 이 문제의 공식적인 해결 지점이다.

참고 자료


Share this post on:

Previous Post
13개 Docker 프로젝트 구조를 표준화한 과정
Next Post
컴퓨터과학과 중퇴 개발자의 15년