지난 "GCP VM(+UDP LB) 구성하여 Wireguard VPN 설치" 게시물에서 GCP 환경에서 UDP Passthrough LB와 GCE 인스턴스로 Wireguard VPN 환경을 구성한 예시가 있었다.
https://engmisankim.tistory.com/99
GCP VM(+UDP LB) 구성하여 Wireguard VPN 설치
GCP(Google Cloud Platform)에 GCE 인스턴스를 생성하여 오픈소스 VPN 인 wireguard 을 설치하고, UDP passthrough LB 를 추가하여 구성한다. # VPN VM 생성GCP 콘솔에서 생성하거나 gcloud 커맨드를 통해 생성해도 관
engmisankim.tistory.com
이대로 사용해도 큰 문제는 없을 수 있겠으나 아래와 같이 VPN 클라이언트가 늘어났을 경우 VPN Server 에서 SNAT 를 통해 프라이빗 네트워크에 액세스하기 때문에 프라이빗 네트워크에 있는 내부 서버 입장에서는 VPN 클라이언트 간의 아이피 식별이 불가능하다는 점이 있다.


때문에 이번 게시물에서는 Wireguard VPN 서버 구성 시 VPN Client 마다 부여되는 사설 아이피를 내부 서버와 통신 시 SNAT 하지 않고, 아이피를 보존하여 통신할 수 있도록 구성을 변경해보려고 한다.
처음에는 SNAT 를 하지 않는 구성이 VPN 소프트웨어마다 특별한 네트워크 옵션이 있나 싶었는데 막상 파고들어 보니 간단한 설정 만으로 가능했다.
그림으로 표현하면 아래와 같은 형태가 될 것이다.

# Wireguard VPN 서버에서 SNAT(MASQUERADE) 설정 제거
지난 게시물에서 작성한 VPN 서버 설정 파일은 GCP UDP Passthrough LB 사용 여부에 따라 다음 두가지 버전의 파일이 있을 것이다.
(34.64.242.162 아이피는 GCP UDP Passthrough LB 의 퍼블릭 아이피로 현재는 없는 LB이기 때문에 참고만 하고, 자신의 환경의 LB의 퍼블릭 아이피로 치환하면 되겠다.)
VPN 앞단에 LB를 사용하지 않는 경우
vim /etc/wireguard/wg0.conf
[Interface]
Address = 10.100.0.1/24
# MTU = 1380 ## 옵셔널
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens4 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens4 -j MASQUERADE
ListenPort = 51820
PrivateKey = 서버_개인키
[Peer]
PublicKey = 클라이언트_공개키
AllowedIPs = 10.100.0.2/32
VPN 앞단에 LB를 사용하는 경우
vim /etc/wireguard/wg0.conf
[Interface]
Address = 10.100.0.1/24
# MTU = 1380 ## 옵셔널
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens4 -j MASQUERADE; iptables -t nat -A POSTROUTING -j RETURN -d 10.0.0.8 -p udp --dport 51820; iptables -t nat -A PREROUTING -j DNAT --to-destination 10.0.0.8 -d 34.64.242.162 -p udp --dport 51820
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens4 -j MASQUERADE; iptables -t nat -D POSTROUTING -j RETURN -d 10.0.0.8 -p udp --dport 51820; iptables -t nat -D PREROUTING -j DNAT --to-destination 10.0.0.8 -d 34.64.242.162 -p udp --dport 51820
ListenPort = 51820
PrivateKey = 서버_개인키
[Peer]
PublicKey = 클라이언트_공개키
AllowedIPs = 10.100.0.2/32
여기서 수정해야하는 부분은 PostUp/PostDown 설정의 "iptables -t nat -[AD] POSTROUTING -o ens4 -j MASQUERADE" 부분만 삭제하면 된다.
만약 VPN 앞단에 LB를 사용하지 않는 경우라면
vim /etc/wireguard/wg0.conf
[Interface]
Address = 10.100.0.1/24
# MTU = 1380 ## 옵셔널
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT
ListenPort = 51820
PrivateKey = 서버_개인키
[Peer]
PublicKey = 클라이언트_공개키
AllowedIPs = 10.100.0.2/32
만약 VPN 앞단에 LB를 사용하는 경우라면
vim /etc/wireguard/wg0.conf
[Interface]
Address = 10.100.0.1/24
# MTU = 1380 ## 옵셔널
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -j RETURN -d 10.0.0.8 -p udp --dport 51820; iptables -t nat -A PREROUTING -j DNAT --to-destination 10.0.0.8 -d 34.64.242.162 -p udp --dport 51820
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -j RETURN -d 10.0.0.8 -p udp --dport 51820; iptables -t nat -D PREROUTING -j DNAT --to-destination 10.0.0.8 -d 34.64.242.162 -p udp --dport 51820
ListenPort = 51820
PrivateKey = 서버_개인키
[Peer]
PublicKey = 클라이언트_공개키
AllowedIPs = 10.100.0.2/32
이렇게만 설정을 변경하면 VPN 서버에서의 설정은 끝난다.
하지만 이 상태만으로는 내부 서버와 통신이 되지 않을 것이다.
# Office Network 의 라우팅 설정 수정
기존에 SNAT 를 통해 통신하는 구조에서는 내부 서버에서 VPN 서버로의 리턴 트래픽이 동일한 네트워크로 잘 전달되었을 것이다. 또한 퍼블릭 클라우드에서도 마찬가지로 10.0.0.0/24 대역은 로컬 네트워크이기 때문에 특별한 설정 없이도 내부 서버에서의 리턴 트래픽이 VPN 서버로 잘 전달되었을 것이다.
(아래 그림에서는 퍼블릭 클라우드를 기준으로 편의상 라우터라고 표현했으나, 온프레미스 기준으로는 동일 대역이기 때문에 라우터까지 갈 것도 없이 네트워크 스위치 등의 L2 레이어에서 처리가 되었을 것이다.)

SNAT 를 비활성화했을 때에는 VPN 내부 대역(10.100.0.0/24)에 대한 라우팅 정보가 프라이빗 네트워크 안에 존재하지 않기 때문에 라우터가 10.100.0.0/24 대역에 대한 넥스트 홉을 찾지 못하게 된다.

때문에 이 문제를 해결하기 위해 프라이빗 네트워크의 라우터에 VPN 내부 대역(10.100.0.0/24)에 대한 넥스트 홉을 VPN 서버로 잡아주는 설정이 필요하다.
GCP VPC 기준으로는 아래처럼 세팅하면 된다.
다른 퍼블릭 클라우드나 온프레미스라면 설정 방법은 다르겠지만 개념은 동일하니 각 환경에 맞게 세팅해주면 되겠다.
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_route
Terraform Registry
registry.terraform.io
gcloud 커맨드로는
gcloud compute routes create vpn \
--network=test-network \
--destination-range=10.100.0.0/24 \
--priority=1000 \
--next-hop-instance=test-vpn \
--next-hop-instance-zone=asia-northeast3-a \
--project=test-project
테라폼으로는
resource "google_compute_route" "vpn" {
name = "vpn"
dest_range = "10.100.0.0/24"
network = google_compute_network.test-network.id
next_hop_instance = google_compute_instance.vpn.id
priority = 1000
}
그럼 최종적으로는 아래처럼 통신이 가능하며, Office Network 의 내부 서버에서는 클라이언트의 사설 아이피를 식별할 수 있게 된다. 다른 VPN 소프트웨어(OpenVPN 등)를 사용하더라도 설정 방법은 조금씩 다를 수 있겠지만 기본 개념은 동일하니 참고하면 될 것 같다.

# 간단하게 세 줄로 요약하면
Wireguard VPN 서버를 통해 내부 서버에 접근하는 클라이언트의 사설 아이피를 식별(구분)하고 싶다면!
1) VPN 서버에서 SNAT(MASQUERADE) 설정을 꺼라!
2) Office Network 의 라우터에서 VPN 내부 대역(10.100.0.0/24)에 대한 라우팅 경로를 추가하라!
'GCP' 카테고리의 다른 글
| Google Certificate Manager 로 Google Managed Cert 생성하기 (2) | 2025.08.25 |
|---|---|
| GCP VM(+UDP LB) 구성하여 Wireguard VPN 설치 (0) | 2025.03.31 |
| workload identity federation with keycloak (0) | 2023.07.09 |
| workload identity federation with k8s cluster (1) | 2023.07.02 |
| GKE workload identity (0) | 2023.07.01 |