WireGuard VPN 세팅

흑두루미·2026년 7월 8일

Proxmox LXC에 WireGuard VPN 구성하기

1. 구성 목적

회사에서 특정 IP만 접속 허용하는 환경이 있을 때, 집 공인 IP를 회사에 등록해두면 집에서는 정상적으로 접속할 수 있다.

하지만 카페, 외부 장소, 다른 집에서 노트북을 사용하면 접속 출발지 IP가 바뀌기 때문에 회사 시스템에 접속할 수 없다.

이 문제를 해결하기 위해 집에 VPN 서버를 구성하고, 외부에서는 VPN을 통해 집 네트워크를 경유하도록 만들었다.

최종 목표는 다음과 같다.

외부 노트북 / 휴대폰
  ↓ WireGuard VPN
집 Proxmox 서버
  ↓
집 공인 IP
  ↓
회사 시스템 접속

즉, 외부에서 접속하더라도 회사 입장에서는 항상 집 공인 IP에서 접속한 것처럼 보이게 하는 구조다.


2. 최종 구성도

이번에 구성한 환경은 다음과 같다.

인터넷
  ↓
Proxmox Host
  - vmbr0: 공인망
    IP: 49.172.xxx.xxx/27
    GW: 49.172.xxx.1

  - vmbr1: 내부망
    IP: 10.10.10.1/24

  - LXC 102: wg-vpn
    IP: 10.10.10.20/24
    GW: 10.10.10.1
    WireGuard Port: UDP 51820

WireGuard VPN 내부 대역은 별도로 아래처럼 구성했다.

WireGuard Server: 10.8.0.1/24
WireGuard Client: 10.8.0.2/32

최종 트래픽 흐름은 다음과 같다.

휴대폰 LTE / 외부 노트북
  ↓
WireGuard Client
  ↓
Proxmox 공인 IP:51820/udp
  ↓
Proxmox iptables DNAT
  ↓
LXC wg-vpn:10.10.10.20:51820
  ↓
WireGuard wg0
  ↓
집 공인 IP로 외부 인터넷 접속

3. 사전 확인

먼저 Proxmox 호스트에서 네트워크 상태를 확인했다.

ip -4 addr show vmbr0
ip -4 addr show vmbr1
ip route
curl -4 ifconfig.me

확인 결과는 다음과 같았다.

vmbr0: 49.172.xxx.xxx/27
vmbr1: 10.10.10.1/24
default gateway: 49.172.xxx.1
curl ifconfig.me: 49.172.xxx.xxx

여기서 중요한 점은 vmbr0의 IP와 curl ifconfig.me 결과가 동일했다는 것이다.

즉, Proxmox 호스트가 사설 IP 뒤에 있는 것이 아니라 공인 IP를 직접 가지고 있는 상태였다.

또한 내부망 NAT가 이미 설정되어 있었다.

iptables -t nat -S

기존 NAT 룰은 다음과 같은 형태였다.

-A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE

IP Forward 상태도 확인했다.

sysctl net.ipv4.ip_forward

결과:

net.ipv4.ip_forward = 1

이 값이 1이어야 내부망 또는 VPN 클라이언트의 트래픽을 외부로 라우팅할 수 있다.

만약 0이라면 아래처럼 활성화한다.

echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/99-ipforward.conf
sysctl -p /etc/sysctl.d/99-ipforward.conf

4. Debian 12 LXC 생성

WireGuard는 매우 가볍기 때문에 별도의 VM보다 LXC로 구성했다.

Proxmox GUI에서 Create CT를 선택하고 다음과 같이 생성했다.

CT ID: 102
Hostname: wg-vpn
Template: Debian 12
Unprivileged container: 체크
Disk: 5GB
CPU: 1 Core
Memory: 512MB
Swap: 512MB
Bridge: vmbr1
IPv4: 10.10.10.20/24
Gateway: 10.10.10.1
DNS: 1.1.1.1

DNS 설정 시 search domain은 비워두었다.


5. LXC TUN 장치 허용

WireGuard는 /dev/net/tun 장치를 사용한다.
LXC에서 WireGuard를 사용하기 위해 Proxmox 호스트에서 다음 설정을 추가했다.

CT ID는 102 기준이다.

pct stop 102
pct set 102 -features nesting=1

mkdir -p /dev/net
[ -c /dev/net/tun ] || mknod /dev/net/tun c 10 200
chmod 666 /dev/net/tun

grep -q "c 10:200" /etc/pve/lxc/102.conf || echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >> /etc/pve/lxc/102.conf

grep -q "/dev/net" /etc/pve/lxc/102.conf || echo "lxc.mount.entry: /dev/net dev/net none bind,create=dir" >> /etc/pve/lxc/102.conf

pct start 102

이후 LXC에 접속했다.

pct enter 102

네트워크 확인:

ip a
ip route
ping -c 3 1.1.1.1
apt update

정상적으로 아래와 같이 확인되었다.

eth0: 10.10.10.20/24
default via 10.10.10.1
ping 1.1.1.1 성공
apt update 성공

6. WireGuard 설치

LXC 내부에서 WireGuard를 설치했다.

apt install -y wireguard wireguard-tools iptables curl

설치 확인:

wg --version

7. LXC 내부 IP Forward 활성화

LXC 내부에서도 VPN 클라이언트 트래픽을 전달해야 하므로 IP Forward를 활성화했다.

cat > /etc/sysctl.d/99-wireguard.conf << 'EOF'
net.ipv4.ip_forward=1
EOF

sysctl -p /etc/sysctl.d/99-wireguard.conf

정상 결과:

net.ipv4.ip_forward = 1

8. WireGuard 키 생성

LXC 내부에서 서버 키와 클라이언트 키를 생성했다.

mkdir -p /etc/wireguard
cd /etc/wireguard
umask 077

wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genkey | tee client_laptop_private.key | wg pubkey > client_laptop_public.key

파일 확인:

ls -l /etc/wireguard

생성된 파일은 다음과 같다.

server_private.key
server_public.key
client_laptop_private.key
client_laptop_public.key

주의할 점은 private.key 파일은 절대 외부에 공개하면 안 된다.


9. WireGuard 서버 설정

LXC 내부에서 /etc/wireguard/wg0.conf 파일을 생성했다.

SERVER_PRIVATE_KEY=$(cat /etc/wireguard/server_private.key)
CLIENT_PUBLIC_KEY=$(cat /etc/wireguard/client_laptop_public.key)

cat > /etc/wireguard/wg0.conf << EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = ${SERVER_PRIVATE_KEY}

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

[Peer]
PublicKey = ${CLIENT_PUBLIC_KEY}
AllowedIPs = 10.8.0.2/32
EOF

권한 설정:

chmod 600 /etc/wireguard/wg0.conf

여기서 중요한 부분은 다음이다.

Address = 10.8.0.1/24
ListenPort = 51820

WireGuard 서버는 10.8.0.1을 사용하고, UDP 51820 포트에서 대기한다.

클라이언트는 다음 IP를 사용한다.

AllowedIPs = 10.8.0.2/32

10. WireGuard 서비스 시작

WireGuard를 시작하고 자동 시작 설정을 추가했다.

systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0

상태 확인:

systemctl status wg-quick@wg0 --no-pager

정상 상태:

active (exited)
enabled

WireGuard 상태 확인:

wg

정상적으로 아래와 같은 정보가 확인된다.

interface: wg0
  listening port: 51820

peer:
  allowed ips: 10.8.0.2/32


11. Proxmox 호스트에서 포트포워딩 설정

LXC는 내부망인 10.10.10.20에 있기 때문에, 외부에서 Proxmox 공인 IP의 UDP 51820 포트로 들어온 트래픽을 LXC로 전달해야 한다.

LXC에서 나와 Proxmox 호스트에서 작업한다.

exit

Proxmox 호스트에서 아래 명령을 실행했다.

iptables -t nat -A PREROUTING -i vmbr0 -p udp --dport 51820 -j DNAT --to-destination 10.10.10.20:51820

iptables -A FORWARD -i vmbr0 -o vmbr1 -p udp -d 10.10.10.20 --dport 51820 -j ACCEPT

iptables -A FORWARD -i vmbr1 -o vmbr0 -s 10.10.10.20 -j ACCEPT

확인:

iptables -t nat -S | grep 51820
iptables -S FORWARD | grep 10.10.10.20

정상적으로 다음과 같이 확인된다.

-A PREROUTING -i vmbr0 -p udp -m udp --dport 51820 -j DNAT --to-destination 10.10.10.20:51820

-A FORWARD -d 10.10.10.20/32 -i vmbr0 -o vmbr1 -p udp -m udp --dport 51820 -j ACCEPT
-A FORWARD -s 10.10.10.20/32 -i vmbr1 -o vmbr0 -j ACCEPT

12. 클라이언트 설정 파일 생성

다시 LXC에 접속한다.

pct enter 102

클라이언트 설정 파일을 생성한다.

PUBLIC_IP=$(curl -4 -s ifconfig.me)
SERVER_PUBLIC_KEY=$(cat /etc/wireguard/server_public.key)
CLIENT_PRIVATE_KEY=$(cat /etc/wireguard/client_laptop_private.key)

cat > /root/client-laptop.conf << EOF
[Interface]
PrivateKey = ${CLIENT_PRIVATE_KEY}
Address = 10.8.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = ${SERVER_PUBLIC_KEY}
Endpoint = ${PUBLIC_IP}:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
EOF

확인:

cat /root/client-laptop.conf

설정 파일 형태는 다음과 같다.

[Interface]
PrivateKey = 클라이언트_개인키
Address = 10.8.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = 서버_공개키
Endpoint = 49.172.xxx.xxx:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

여기서 AllowedIPs = 0.0.0.0/0의 의미는 클라이언트의 모든 IPv4 트래픽을 WireGuard VPN으로 보내겠다는 뜻이다.

즉 외부에서 VPN을 켜면 인터넷 접속도 집 Proxmox 서버를 경유하게 된다.


13. 휴대폰으로 테스트

처음에는 외부 노트북으로 바로 테스트하기 어려워서 휴대폰 LTE로 테스트했다.

휴대폰에 WireGuard 앱을 설치한 뒤, client-laptop.conf 내용을 등록했다. (QR 버전으로 등록 완료)

QR 코드로 conf 등록하는 방법은 다음과 같다.

apt install -y qrencode

qrencode -t ansiutf8 < /root/client-laptop.conf
# 터미널에서 QR코드가 나옴
WireGuard 앱에서 +
→ Create from QR code
→ 화면의 QR 코드 스캔

테스트 조건은 다음과 같다.

휴대폰 Wi-Fi OFF
LTE 상태
WireGuard ON

브라우저에서 아래 사이트에 접속했다.

https://ifconfig.me

결과가 집 공인 IP로 확인되었다.

IP Address: 49.172.xxx.xxx

WireGuard를 Off하게되면 휴대폰 LTE IP로 변경되는 것을 확인했다.

즉, 휴대폰 LTE 상태에서도 VPN을 통해 집 공인 IP로 나가는 것을 확인했다.

서버에서도 확인했다.

wg

정상 연결 시 아래 항목이 보인다.

latest handshake: 몇 초 전
transfer: xx KiB received, xx KiB sent


14. 중복 iptables 룰 정리

작업 중 같은 iptables 룰이 중복으로 들어간 경우가 있었다.

전체 NAT 룰 확인:

iptables -t nat -S

FORWARD 룰 확인:

iptables -S FORWARD

중복된 NAT MASQUERADE 룰은 다음 명령으로 하나 제거했다.

iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE

중복된 DNAT 룰은 다음 명령으로 하나 제거했다.

iptables -t nat -D PREROUTING -i vmbr0 -p udp --dport 51820 -j DNAT --to-destination 10.10.10.20:51820

중복된 FORWARD 룰은 다음 명령으로 하나씩 제거했다.

iptables -D FORWARD -d 10.10.10.20/32 -i vmbr0 -o vmbr1 -p udp --dport 51820 -j ACCEPT

iptables -D FORWARD -s 10.10.10.20/32 -i vmbr1 -o vmbr0 -j ACCEPT

최종적으로 남겨야 할 핵심 룰은 다음과 같다.

nat 테이블

-A PREROUTING -i vmbr0 -p udp -m udp --dport 51820 -j DNAT --to-destination 10.10.10.20:51820
-A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
filter 테이블

-A FORWARD -d 10.10.10.20/32 -i vmbr0 -o vmbr1 -p udp -m udp --dport 51820 -j ACCEPT
-A FORWARD -s 10.10.10.20/32 -i vmbr1 -o vmbr0 -j ACCEPT

정리 후 휴대폰 LTE에서 다시 WireGuard를 켜고 ifconfig.me로 확인했으며, 정상적으로 집 공인 IP가 나왔다.


15. Proxmox 저장소 이슈 해결

iptables 영구화를 위해 apt update를 실행했는데 다음과 같은 에러가 발생했다.

401 Unauthorized
https://enterprise.proxmox.com/debian/pve
https://enterprise.proxmox.com/debian/ceph-squid

원인은 Proxmox 유료 구독용 Enterprise Repository가 활성화되어 있었기 때문이다.

구독을 사용하지 않는 홈랩 환경에서는 Enterprise 저장소를 비활성화하고 No-Subscription 저장소를 사용하면 된다.

현재 환경에서는 다음 저장소를 사용했다.

deb http://download.proxmox.com/debian/pve trixie pve-no-subscription

GUI에서는 다음 경로에서 설정할 수 있다.

pve 노드 선택
→ Updates
→ Repositories
→ Enterprise Repository 비활성화
→ No-Subscription Repository 추가

이후 다시 apt update를 실행하니 정상적으로 완료되었다.


16. iptables 영구화

iptables 룰은 기본적으로 재부팅하면 사라질 수 있다.

따라서 iptables-persistent를 설치해 영구화했다.

apt update
apt install -y iptables-persistent

설치 중 질문은 다음과 같이 선택했다.

Save current IPv4 rules? → Yes
Save current IPv6 rules? → No

설치 후 현재 룰을 저장했다.

netfilter-persistent save

저장 파일 확인:

cat /etc/iptables/rules.v4 | grep 51820
cat /etc/iptables/rules.v4 | grep "10.10.10.0/24"
cat /etc/iptables/rules.v4 | grep "10.10.10.20"

정상적으로 다음과 같은 룰이 저장되어 있어야 한다.

-A PREROUTING -i vmbr0 -p udp -m udp --dport 51820 -j DNAT --to-destination 10.10.10.20:51820
-A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
-A FORWARD -d 10.10.10.20/32 -i vmbr0 -o vmbr1 -p udp -m udp --dport 51820 -j ACCEPT
-A FORWARD -s 10.10.10.20/32 -i vmbr1 -o vmbr0 -j ACCEPT

서비스 활성화 확인:

systemctl is-enabled netfilter-persistent

정상 결과:

enabled

17. LXC 자동 시작 설정

Proxmox 서버가 재부팅되었을 때 VPN LXC도 자동으로 시작되도록 설정했다.

pct set 102 -onboot 1

확인:

pct config 102 | grep onboot

정상 결과:

onboot: 1

또는 GUI에서 다음 경로로 설정할 수 있다.

CT 102(wg-vpn)
→ Options
→ Start at boot
→ Yes

LXC 내부 WireGuard 서비스도 자동 시작 상태인지 확인했다.

pct enter 102
systemctl is-enabled wg-quick@wg0

정상 결과:

enabled

18. 최종 점검 명령어

Proxmox 호스트에서 확인할 명령어:

iptables -t nat -S | grep 51820
iptables -t nat -S | grep "10.10.10.0/24"
iptables -S FORWARD | grep "10.10.10.20"
systemctl is-enabled netfilter-persistent
pct config 102 | grep onboot

LXC 내부에서 확인할 명령어:

systemctl status wg-quick@wg0 --no-pager
wg

클라이언트에서 확인할 것:

WireGuard ON
https://ifconfig.me 접속
집 공인 IP로 보이는지 확인

19. 최종 결과

최종적으로 다음 상태가 되었다.

Proxmox Host
  - 공인 IP: 49.172.xxx.xxx
  - vmbr0: 공인망
  - vmbr1: 내부망 10.10.10.1/24
  - iptables-persistent 활성화

WireGuard LXC
  - CT ID: 102
  - Hostname: wg-vpn
  - IP: 10.10.10.20/24
  - WireGuard Server IP: 10.8.0.1/24
  - Listen Port: UDP 51820
  - Start at boot: enabled

Client
  - VPN IP: 10.8.0.2/32
  - AllowedIPs: 0.0.0.0/0

휴대폰 LTE 환경에서 WireGuard를 켰을 때 ifconfig.me 결과가 집 공인 IP로 확인되었으므로, VPN 구성은 정상적으로 완료되었다.


20. 주의사항

첫 번째, client-laptop.conf 파일에는 클라이언트 개인키가 들어 있다.
블로그나 외부 문서에 절대 그대로 올리면 안 된다.

PrivateKey = 절대_공개_금지

두 번째, 같은 클라이언트 설정을 휴대폰과 노트북에서 동시에 사용하면 안 된다.

예를 들어 휴대폰과 노트북이 둘 다 아래 설정을 동시에 사용하면 충돌이 발생할 수 있다.

같은 PrivateKey
같은 Address = 10.8.0.2/32

테스트 후 휴대폰에서 터널을 삭제하고 노트북에서 같은 설정을 사용하는 것은 괜찮다.
하지만 운영용으로는 기기별로 Peer를 분리하는 것이 좋다.

노트북: 10.8.0.2/32
휴대폰: 10.8.0.3/32

세 번째, 가정용 인터넷의 공인 IP는 유동 IP일 수 있다.
집 공인 IP가 바뀌면 회사에 등록된 허용 IP도 다시 변경해야 한다.

네 번째, Proxmox 호스트와 LXC를 재부팅해도 VPN이 자동 복구되려면 아래 세 가지가 모두 되어 있어야 한다.

1. netfilter-persistent enabled
2. CT 102 onboot enabled
3. wg-quick@wg0 enabled

마무리

이번 구성으로 외부에서도 WireGuard VPN을 통해 집 Proxmox 서버를 경유할 수 있게 되었다.

결과적으로 카페나 외부 장소에서 노트북을 사용하더라도 회사 시스템에는 항상 집 공인 IP로 접속하는 구조가 완성되었다.

외부 노트북
  → WireGuard
  → 집 Proxmox
  → 집 공인 IP
  → 회사 시스템

리소스도 매우 적게 사용한다.

WireGuard LXC
CPU: 1 Core
Memory: 512MB
Disk: 5GB

따라서 작은 홈서버나 Proxmox 환경에서도 부담 없이 운영할 수 있는 구성이라고 볼 수 있다.

0개의 댓글