WireGuard로 분할 터널링 구성하기
WireGuard 분할 터널링의 개념과 라우팅 원리, AllowedIPs 및 정책 기반 마킹으로 특정 앱만 VPN 경로로 보내는 설정 예제와 검증 방법 설명
목차
개요
분할 터널링(split tunneling)은 트래픽의 일부만 VPN을 통해 전송하고 나머지는 로컬 네트워크로 빠져나가도록 하는 방식이다. 이 글에서는 WireGuard 환경에서 분할 터널링의 원리와 구현 방법을 이해하기 쉬운 단계로 정리한다. 또한 특정 애플리케이션만 VPN을 사용하도록 제어하는 현실적인 방법을 소개한다.
분할 터널링의 기본 개념
분할 터널링은 목적지 기반 라우팅과 정책 기반 라우팅(policy routing)을 활용한다. 목적지 기반은 특정 IP 대역만 터널로 보내는 방식이며, 정책 기반은 프로세스나 사용자, 포트 등 패킷 속성에 따라 라우팅을 달리한다. WireGuard 자체는 패킷을 검사하는 방식을 제공하지 않기 때문에 운영체제의 라우팅과 방화벽 기능을 함께 사용해야 한다.
WireGuard에서의 핵심 요소
AllowedIPs
AllowedIPs는 WireGuard에서 어떤 트래픽을 터널로 보낼지 결정하는 가장 기본적인 설정이다. 피어 설정에 특정 네트워크(예: 10.0.0.0/24)만 넣으면 해당 목적지로 향하는 패킷만 터널로 간다. 반대로 0.0.0.0/0을 넣으면 모든 트래픽이 터널로 라우팅된다.
정책 기반 라우팅과 마킹
특정 앱만 VPN을 통과시키려면 패킷에 마크를 남겨 전용 라우팅 테이블로 보내는 방식이 효과적이다. 일반적인 흐름은 다음과 같다.
- 앱 실행 사용자의 UID나 소스 포트 등을 기반으로 패킷에 fwmark를 부여
- fwmark를 검사하는 ip rule을 추가하여 별도의 라우팅 테이블로 전달
- 해당 라우팅 테이블에 WireGuard 인터페이스로 가는 기본경로 추가
설정 예제 1 — AllowedIPs로 목적지 기반 분할 터널링
단순히 특정 네트워크(예: 사내 10.0.0.0/24)만 터널로 보내는 설정 예제.
[Interface]
Address = 10.8.0.2/24
PrivateKey =
DNS = 10.8.0.1
[Peer]
PublicKey =
Endpoint = vpn.example.com:51820
AllowedIPs = 10.0.0.0/24
이 구성에서는 목적지가 10.0.0.0/24인 패킷만 wg0를 통해 전달된다. 나머지 트래픽은 기본 라우팅 테이블을 따른다.
설정 예제 2 — 특정 앱만 VPN 사용 (UID 기반 마킹)
리눅스 환경에서 프로세스 기반으로 트래픽을 분리하는 방법이다. 구현은 iptables(또는 nftables)와 ip rule, 별도 라우팅 테이블 조합으로 이뤄진다.
# 1) 별도 라우팅 테이블 추가 (예: table 100)
ip route add default dev wg0 table 100
# 2) fwmark에 따른 룰 추가
ip rule add fwmark 0x1 lookup 100
# 3) 특정 UID의 패킷에 마크 설정 (예: UID 1000)
iptables -t mangle -A OUTPUT -m owner --uid-owner 1000 -j MARK --set-mark 1
# 4) rp_filter 비활성화(필요 시)
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
이 흐름에서는 UID 1000으로 실행된 애플리케이션의 패킷만 fwmark를 받아 table 100으로 라우팅되고, 그 테이블은 wg0를 기본 경로로 사용한다.
nftables 대안
nftables 사용 시 마킹 룰은 다음과 같다.
nft add table ip mangle
nft 'add chain ip mangle output { type filter hook output priority 0 ; }'
nft add rule ip mangle output meta skuid 1000 mark set 1
네트워크 네임스페이스를 이용한 방법
네임스페이스는 특정 프로세스 그룹을 완전한 네트워크 격리 환경으로 이동시키는 방법이다. 해당 네임스페이스 안에 wg 인터페이스를 세팅하면 해당 네임스페이스의 트래픽만 VPN을 사용하게 된다.
# 네임스페이스 생성 및 가상 이더링 페어 생성
ip netns add vpnns
ip link add veth0 type veth peer name veth1
ip link set veth1 netns vpnns
# 호스트 쪽 설정
ip addr add 10.200.1.1/24 dev veth0
ip link set veth0 up
# 네임스페이스 쪽 설정
ip netns exec vpnns ip addr add 10.200.1.2/24 dev veth1
ip netns exec vpnns ip link set veth1 up
ip netns exec vpnns ip route add default via 10.200.1.1
# 네임스페이스 내부에서 WireGuard 구성 및 애플리케이션 실행
ip netns exec vpnns wg-quick up /etc/wireguard/wg0.conf
이 방식은 가장 격리도가 높고 특정 애플리케이션을 완전히 독립된 네트워크로 옮길 때 유용하다.
검증 및 문제 해결
- wg show로 인터페이스 상태와 최신 핸드셰이크 확인
- ip rule list와 ip route show table X로 정책 라우팅 검증
- tcpdump 또는 ss로 패킷 경로와 포트 확인
- DNS 누수 여부는 애플리케이션에서 사용하는 DNS 설정과 /etc/resolv.conf 확인
특히 마킹 기반 설정에서는 OUTPUT 체인에 룰이 적용되는지, 커널의 rp_filter 설정 때문에 응답이 차단되지 않는지 확인이 필요하다.
권장 설정과 보안 주의사항
- 분할 터널링은 편리하지만 민감한 트래픽은 VPN을 통해 보내는 것이 더 안전하다
- DNS 누수 방지를 위해 VPN 내부 DNS 사용 또는 애플리케이션 수준 DNS 설정 필요
- 정책 기반 라우팅의 우선순위와 룰 충돌을 먼저 점검
- 모바일이나 일부 OS에서는 owner 매치가 제한적이므로 네임스페이스 방식이 더 확실한 대안
요약
WireGuard 분할 터널링은 AllowedIPs를 이용한 목적지 기반과 운영체제 수준의 정책 기반 라우팅을 결합하면 실무에 바로 적용 가능한 유연한 제어가 가능하다. 특정 앱만 VPN을 사용하도록 할 때는 UID 기반 마킹이나 네임스페이스 방법을 선택하며, DNS와 rp_filter 같은 부가 요소를 함께 점검하면 안정적인 운영이 가능하다.