회사에서 특정 IP만 접속 허용하는 환경이 있을 때, 집 공인 IP를 회사에 등록해두면 집에서는 정상적으로 접속할 수 있다.
하지만 카페, 외부 장소, 다른 집에서 노트북을 사용하면 접속 출발지 IP가 바뀌기 때문에 회사 시스템에 접속할 수 없다.
이 문제를 해결하기 위해 집에 VPN 서버를 구성하고, 외부에서는 VPN을 통해 집 네트워크를 경유하도록 만들었다.
최종 목표는 다음과 같다.
외부 노트북 / 휴대폰
↓ WireGuard VPN
집 Proxmox 서버
↓
집 공인 IP
↓
회사 시스템 접속
즉, 외부에서 접속하더라도 회사 입장에서는 항상 집 공인 IP에서 접속한 것처럼 보이게 하는 구조다.
이번에 구성한 환경은 다음과 같다.
인터넷
↓
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로 외부 인터넷 접속
먼저 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
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은 비워두었다.
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 성공
LXC 내부에서 WireGuard를 설치했다.
apt install -y wireguard wireguard-tools iptables curl
설치 확인:
wg --version
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
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 파일은 절대 외부에 공개하면 안 된다.
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
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

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
다시 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 서버를 경유하게 된다.
처음에는 외부 노트북으로 바로 테스트하기 어려워서 휴대폰 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

작업 중 같은 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가 나왔다.
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를 실행하니 정상적으로 완료되었다.
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
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
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로 보이는지 확인
최종적으로 다음 상태가 되었다.
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 구성은 정상적으로 완료되었다.
첫 번째, 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 환경에서도 부담 없이 운영할 수 있는 구성이라고 볼 수 있다.