• 돌아가기
  • 아래로
  • 위로
  • 목록
  • 댓글
가이드

오라클 클라우드 인스턴스로부터 wireguard를 통해 Proxmox로 터널링

opq! 479

8

5

0. 서두 <왜 이 짓거리를 하는가>

셀프호스팅에 있어 외부에 자신을 노출시키지 않는 것만큼 안전한 것은 없습니다.[출처 필요]

방화벽을 통해 외부(WAN)로부터 모든 접근을 차단하는 거죠.

그만큼 재미는 없습니다. 집 밖을 나가는 순간, 외부에서 접근할 수 없는 내 서버는 없는 것이나 마찬가지니까요.

 

여기서 한 발자국만 더 (비교적 안전하게) 나아가려면 wireguard, 혹은 그로부터 파생된 tailscale 등을 사용해서 VPN을 구축할 수 있겠습니다.

VPN을 이용해서 내 Proxmox IP를 통해 들어가면, 어디서건 집 안에 있는 것과 같게 되고, 외부로 해당 서비스의 포트를 열 필요도 없습니다.

 

 

하지만 이 방법도 아쉬운 순간이 있습니다.

  • 내 VPN이 없는 환경에 놓일 경우, 혹은 VPN이 차단된 환경에 놓일 경우 내 서버에 접근할 수 없습니다.
  • 마찬가지로 내 친구도 내 서버에 접근할 수 없습니다. VPN 계정을 따로 만들어서 줘야겠죠. VPN이 뭔지 안다면 다행이고요...
  • 웹사이트나 다른 서비스를 대중에 열 방법이 없습니다.

그렇다고 그냥 열기엔 그것도 문제입니다.

  • 예를 들어 웹사이트를 열었을 경우 웹사이트 IP = 우리집 IP가 됩니다. 
    • (요새는 많이 줄었지만) 집 IP가 대략적인 지리적 위치를 노출시킬 수 있습니다.
    • DDoS 공격을 받으면 집 전체가 뻗습니다.
    • 만약 우리집 IP가 바뀌면 DDNS 설정 없이는 웹사이트에도, VPN에도 접근할 수 없습니다.

 

이런 문제로 인해 보통 클라우드플레어 터널링을 하거나, VPS를 통해 직접 wireguard 등의 터널을 구축해서 외부에 서비스를 열게 됩니다.

 

 

 

 

 

1. <뭘 준비했는가>

  • 도메인을 보유하고 있고, Cloudflare를 통해 DNS에 묶어두고 있습니다.
  • 집 서버의 환경은 Proxmox 8입니다.
  • Nginx Proxy Manager가 컨테이너 상에서 돌고 있습니다. 리버스 프록시 및 SSL을 담당합니다.
    TCP 80/443을 받아들입니다.
  • 이미 쓰고 있는 내부용 wireguard도 역시 별도의 컨테이너에서 돌고 있습니다.
    UDP 51820을 받아들입니다. 이것도 이제부터 만들 VPS 터널을 통하게 만들 겁니다. 터널 안의 터널이죠.
    2c53185b973e040265e45b0ea1420ae6e8f839437d58d1d182d7267dc20d3445.jpg
    굳이 이러는 이유는... VPS로부터의 터널은 그 자체만으로는 Nginx Proxy Manager에만 접근 가능하게 만드려고 하기 때문입니다.
  • VPS 서비스는 Oracle Cloud를 씁니다. 현재 실사용중인 인스턴스는 VM.Standard.A1.Flex이지만, 일단 이 가이드를 위해 VM.Standard.E2.1.Micro로 따로 구축해봅니다.
    OS는 Canonical-Ubuntu-22.04를 사용합니다. Debian충인데 Debian이 없어서 어쩔 수 없

 

 

 

 

 

 

2. <변수를 정리하자>

앞으로 인스턴스와 Proxmox를 오가면서 여러 정보를 넣어야 합니다.

제가 쓰고 있는 값이 여러분이 써야할 값과 같을 가능성은 거의 없습니다. 헷갈릴 수 있으니 지금부터 정리합시다.

알아야 할 것:
ip_oracle														// Oracle Cloud 인스턴스 IP
interface_ora													// 인스턴스의 interface 이름
subnet_wg		172.30.1.0/24									// Wireguard에 쓸 서브넷
ip_wg_oracle	172.30.1.2/24									// Wireguard 상의 인스턴스 IP
ip_wg_home		172.30.1.1/24									// Wireguard 상의 집 IP
subnet_home	172.29.1.0/24									// 집 내부 네트워크 서브넷
npm_ip			172.29.1.240									// nginx proxy manager 컨테이너 IP
wireguard_old	172.29.1.233									// 이미 있던 vpn 컨테이너 IP
private_oracle													// 인스턴스의 Wireguard 개인 키
public_oracle													// 인스턴스의 Wireguard 공개 키
private_home													// Proxmox의 Wireguard 개인 키
public_home														// Proxmox의 Wireguard 공개 키       

지금 채워넣을 수 있는 값은 이미 채워넣은 상태입니다. 앞으로의 (스크린샷을 제외한) 예제에서 각 값은 <<!!값 이름!!>> 으로 표기합니다.

  • subnet_wgsubnet_home은 서로 다른 대역으로 설정합니다.
  • Wireguard 각 단의 개인 키(private key)를 절대로 외부에 공개해서는 안됩니다.
    (제가 이 예제를 만들며 쓴 인스턴스와 컨테이너는 글을 올렸을 시점에 이미 이 세상에 없습니다.)

 

 

 

 

 

 

3. <Oracle Cloud에 인스턴스를 올리자>

상기한 대로 VM.Standard.E2.1.Micro 인스턴스를 만들어봅시다. OS는 Canonical-Ubuntu-22.04로요.

인스턴스를 만드는 법은 따로 적지 않겠습니다.

SSH key는 꼭 넣어줍시다.

이미 돌리고 있는 인스턴스가 있다면 Virtual cloud networkSubnet은 새로 만드는 게 좋겠습니다.

 

 

 

인스턴스가 만들어졌다면 Subnet - Security List에서 Ingress Rules를 수정해줍니다.Screenshot 2024-04-02 at 19-01-42 Virtual cloud networks Oracle Cloud Infrastructure.png.jpg

 

 

HTTP/S 용으로 TCP 80과 TCP 443,
이번에 구축할 wireguard 터널용 UDP 51819,

이미 가지고 있던 터널용 UDP 51820입니다.

 

* 혹시 모르니 SSH 포트의 Source CIDR도 <<!!현재 집 주소 IP!!>>/32로 바꿔줍시다.

 

 

인스턴스 페이지에서 Public IP address를 복붙해서 우리의 변수 정리함에 적어줍시다.

 

변수 정리함
ip_oracle		158.179.165.19									// Oracle Cloud 인스턴스 IP
interface_ora													// 인스턴스의 interface 이름
subnet_wg		172.30.1.0/24									// Wireguard에 쓸 서브넷
ip_wg_oracle	172.30.1.2/24									// Wireguard 상의 인스턴스 IP
ip_wg_home		172.30.1.1/24									// Wireguard 상의 집 IP
subnet_home	172.29.1.0/24									// 집 내부 네트워크 서브넷
npm_ip			172.29.1.240									// nginx proxy manager 컨테이너 IP
wireguard_old	172.29.1.233									// 이미 있던 vpn 컨테이너 IP
private_oracle													// 인스턴스의 Wireguard 개인 키
public_oracle													// 인스턴스의 Wireguard 공개 키
private_home													// Proxmox의 Wireguard 개인 키
public_home														// Proxmox의 Wireguard 공개 키       

 

 

 

 

 

이제 해당 IP에 SSH로 들어가서 업데이트 한 번 돌려줍시다.

sudo su
apt update && apt upgrade -y
reboot       

 

 

재부팅되서 돌아오면 다시 들어가서 인스턴스의 interface 이름을 가져와봅시다.

ip addr       

1.PNG.jpg

ens3가 우리의 인스턴스 인터페이스 이름이네요.

 

 

변수 정리함
ip_oracle		158.179.165.19									// Oracle Cloud 인스턴스 IP
interface_ora	ens3											// 인스턴스의 interface 이름
subnet_wg		172.30.1.0/24									// Wireguard에 쓸 서브넷
ip_wg_oracle	172.30.1.2/24									// Wireguard 상의 인스턴스 IP
ip_wg_home		172.30.1.1/24									// Wireguard 상의 집 IP
subnet_home	172.29.1.0/24									// 집 내부 네트워크 서브넷
npm_ip			172.29.1.240									// nginx proxy manager 컨테이너 IP
wireguard_old	172.29.1.233									// 이미 있던 vpn 컨테이너 IP
private_oracle													// 인스턴스의 Wireguard 개인 키
public_oracle													// 인스턴스의 Wireguard 공개 키
private_home													// Proxmox의 Wireguard 개인 키
public_home														// Proxmox의 Wireguard 공개 키       

 

 

 

 

 

이제 본격적으로 wireguard를 설치하고 개인 키와 공개 키를 만들어봅시다.

sudo su
apt install wireguard -y
cd /etc/wireguard/
wg genkey > private_oracle.key
chmod go= private_oracle.key
cat private_oracle.key | wg pubkey > public_oracle.key       

 

 

여기까지 하고 나서 cat으로 각 값을 확인해봅시다.

cat private_oracle.key
cat public_oracle.key       

2.PNG.jpg

각 값을 정리해둡시다.

 

 

변수 정리함
ip_oracle		158.179.165.19									// Oracle Cloud 인스턴스 IP
interface_ora	ens3											// 인스턴스의 interface 이름
subnet_wg		172.30.1.0/24									// Wireguard에 쓸 서브넷
ip_wg_oracle	172.30.1.2/24									// Wireguard 상의 인스턴스 IP
ip_wg_home		172.30.1.1/24									// Wireguard 상의 집 IP
subnet_home	172.29.1.0/24									// 집 내부 네트워크 서브넷
npm_ip			172.29.1.240									// nginx proxy manager 컨테이너 IP
wireguard_old	172.29.1.233									// 이미 있던 vpn 컨테이너 IP
private_oracle	wO9erzAXWJw38hkmGQPQYvn81UgBvmosoz/rGhtZNHw=	// 인스턴스의 Wireguard 개인 키
public_oracle	GPOxGpWJNaGGfATJZx2FppNcx2zH5LTYQ+nqVfqpdR4=	// 인스턴스의 Wireguard 공개 키
private_home													// Proxmox의 Wireguard 개인 키
public_home														// Proxmox의 Wireguard 공개 키       

*    다시 한번 강조하지만, 실사용시 절대로 개인 키를 공개해서는 안됩니다!!

      유출되었다면 wg genkey부터 다시 하면 됩니다.

 

 

 

 

이제 본격적으로 설정값을 입력해봅시다.

nano wg0.conf       
[Interface]
Address = <<!!ip_wg_oracle!!>>
SaveConfig = false
ListenPort = 51819
PrivateKey = <<!!private_oracle!!>>
PreUp = sysctl -w net.ipv4.ip_forward=1
PostUp = /etc/wireguard/helper/add-nat-routing.sh
PostDown = /etc/wireguard/helper/remove-nat-routing.sh


[Peer]
PublicKey = <<!!public_home!!>>
AllowedIPs = <<!!subnet_wg!!>>,<<!!subnet_home!!>>
PersistentKeepalive = 25       

3.PNG.jpg

public_home은 아직까지 없으니 일단 둡시다.

 

 

 

 

이제 helper 스크립트를 짜넣어 봅시다.

mkdir helper && cd helper
nano add-nat-routing.sh       
#!/bin/bash
IPT="/sbin/iptables"
#IPT6="/sbin/ip6tables"

IN_FACE="<<!!interface_ora!!>>"                   # NIC connected to the internet
WG_FACE="wg0"                    # WG NIC
SUB_NET="<<!!subnet_wg!!>>"          # WG IPv4 sub/net aka CIDR
WG_PORT="51819"                  # WG udp port
#SUB_NET_6="fd42:42:42::/64"      # WG IPv6 sub/net

## IPv4 ##
$IPT -t nat -I POSTROUTING 1 -s $SUB_NET -o $IN_FACE -j MASQUERADE
$IPT -I INPUT 1 -i $WG_FACE -j ACCEPT
$IPT -I FORWARD 1 -i $IN_FACE -o $WG_FACE -j ACCEPT
$IPT -I FORWARD 1 -i $WG_FACE -o $IN_FACE -j ACCEPT
$IPT -I INPUT 1 -i $IN_FACE -p udp --dport $WG_PORT -j ACCEPT

## IPv6 (Uncomment) ##
#$IPT6 -t nat -I POSTROUTING 1 -s $SUB_NET_6 -o $IN_FACE -j MASQUERADE
#$IPT6 -I INPUT 1 -i $WG_FACE -j ACCEPT
#$IPT6 -I FORWARD 1 -i $IN_FACE -o $WG_FACE -j ACCEPT
#$IPT6 -I FORWARD 1 -i $WG_FACE -o $IN_FACE -j ACCEPT

$IPT -t nat -A PREROUTING -i $IN_FACE -p tcp --dport 80 -j DNAT --to-destination <<!!npm_ip!!>>:80
$IPT -t nat -A POSTROUTING -o $WG_FACE -p tcp --dport 80 -d <<!!npm_ip!!>> -j SNAT --to-source <<!!ip_wg_oracle!!>>

$IPT -t nat -A PREROUTING -i $IN_FACE -p tcp --dport 443 -j DNAT --to-destination <<!!npm_ip!!>>:443
$IPT -t nat -A POSTROUTING -o $WG_FACE -p tcp --dport 443 -d <<!!npm_ip!!>> -j SNAT --to-source <<!!ip_wg_oracle!!>>

$IPT -t nat -A PREROUTING -i $IN_FACE -p udp --dport 51820 -j DNAT --to-destination <<!!wireguard_old!!>>:51820
$IPT -t nat -A POSTROUTING -o $WG_FACE -p udp --dport 51820 -d <<!!wireguard_old!!>> -j SNAT --to-source <<!!ip_wg_oracle!!>>       

 

nano remove-nat-routing.sh       
#!/bin/bash
IPT="/sbin/iptables"
#IPT6="/sbin/ip6tables"

IN_FACE="<<!!interface_ora!!>>"                   # NIC connected to the internet
WG_FACE="wg0"                    # WG NIC
SUB_NET="<<!!subnet_wg!!>>"          # WG IPv4 sub/net aka CIDR
WG_PORT="51819"                  # WG udp port
#SUB_NET_6="fd42:42:42::/64"      # WG IPv6 sub/net

# IPv4 rules #
$IPT -t nat -D POSTROUTING -s $SUB_NET -o $IN_FACE -j MASQUERADE
$IPT -D INPUT -i $WG_FACE -j ACCEPT
$IPT -D FORWARD -i $IN_FACE -o $WG_FACE -j ACCEPT
$IPT -D FORWARD -i $WG_FACE -o $IN_FACE -j ACCEPT
$IPT -D INPUT -i $IN_FACE -p udp --dport $WG_PORT -j ACCEPT

# IPv6 rules (uncomment) #
#$IPT6 -t nat -D POSTROUTING -s $SUB_NET_6 -o $IN_FACE -j MASQUERADE
#$IPT6 -D INPUT -i $WG_FACE -j ACCEPT
#$IPT6 -D FORWARD -i $IN_FACE -o $WG_FACE -j ACCEPT
#$IPT6 -D FORWARD -i $WG_FACE -o $IN_FACE -j ACCEPT

$IPT -t nat -D PREROUTING -i $IN_FACE -p tcp --dport 80 -j DNAT --to-destination <<!!npm_ip!!>>:80
$IPT -t nat -D POSTROUTING -o $WG_FACE -p tcp --dport 80 -d <<!!npm_ip!!>> -j SNAT --to-source <<!!ip_wg_oracle!!>>

$IPT -t nat -D PREROUTING -i $IN_FACE -p tcp --dport 443 -j DNAT --to-destination <<!!npm_ip!!>>:443
$IPT -t nat -D POSTROUTING -o $WG_FACE -p tcp --dport 443 -d <<!!npm_ip!!>> -j SNAT --to-source <<!!ip_wg_oracle!!>>

$IPT -t nat -D PREROUTING -i $IN_FACE -p udp --dport 51820 -j DNAT --to-destination <<!!wireguard_old!!>>:51820
$IPT -t nat -D POSTROUTING -o $WG_FACE -p udp --dport 51820 -d <<!!wireguard_old!!>> -j SNAT --to-source <<!!ip_wg_oracle!!>>       

조금 길지만 바꿔야 할 부분만 바꿔주면 됩니다.

터널링할 포트를 늘리려면 아래 부분에 알맞게 고쳐넣으면 됩니다. tcp/udp 잘 구분해주세요.

추후에 IPv6를 적용시키고 싶다면 해당 부분을 uncomment하면 됩니다.

 

 

마무리로 스크립트에 실행 권한을 줍니다.

chmod +x *.sh       

4.PNG.jpg

이제 Proxmox로 넘어가서 컨테이너를 만들어줍시다.

(인스턴스 SSH 창은 끄지 말고 그대로 두세요.)

 

 

 

 

 

 

4. <Proxmox에 컨테이너를 올리자>

5.jpg

컨테이너는 대충 이렇게 설정했습니다. Debian충답게 Debian을 올리고, 빈 ip를 설정해줍니다.
(예제에서 IP를 잘못 설정하는 바람에 지워뒀습니다...)

 

 

역시 SSH로 들어가서 업데이트부터 하고 재부팅합시다.

apt update && apt upgrade -y && reboot       

 

 

그 후 인스턴스에서와 같이 wireguard를 설정해줍니다. (iptables도 같이)

apt install wireguard iptables -y
cd /etc/wireguard/
wg genkey > private_home.key
chmod go= private_home.key
cat private_home.key | wg pubkey > public_home.key
cat private_home.key
cat public_home.key       

6.PNG.jpg

이제 모든 변수가 나왔네요.

 

 

변수 정리함 (끝!!)
ip_oracle		158.179.165.19									// Oracle Cloud 인스턴스 IP
interface_ora	ens3											// 인스턴스의 interface 이름
subnet_wg		172.30.1.0/24									// Wireguard에 쓸 서브넷
ip_wg_oracle	172.30.1.2/24									// Wireguard 상의 인스턴스 IP
ip_wg_home		172.30.1.1/24									// Wireguard 상의 집 IP
subnet_home	172.29.1.0/24									// 집 내부 네트워크 서브넷
npm_ip			172.29.1.240									// nginx proxy manager 컨테이너 IP
wireguard_old	172.29.1.233									// 이미 있던 vpn 컨테이너 IP
private_oracle	wO9erzAXWJw38hkmGQPQYvn81UgBvmosoz/rGhtZNHw=	// 인스턴스의 Wireguard 개인 키
public_oracle	GPOxGpWJNaGGfATJZx2FppNcx2zH5LTYQ+nqVfqpdR4=	// 인스턴스의 Wireguard 공개 키
private_home	UPM29swfwkZ2gI/SmJq6PE03Z0TWI9xMvspdC3xu024=	// Proxmox의 Wireguard 개인 키
public_home	+pXokvqmMUyDfO7FWaYcdKLZe+renG07OeStUYd9O1s=	// Proxmox의 Wireguard 공개 키       

 

 

 

 

 

nano wg0.conf       
[Interface]
Address = <<!!ip_wg_home!!>>
SaveConfig = false
ListenPort = 51819
PrivateKey = <<!!private_home!!>>

PreUp = sysctl -w net.ipv4.ip_forward=1

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT

PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown =  iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE


[Peer]
PublicKey = <<!!public_oracle!!>>
AllowedIPs = <<!!ip_wg_oracle!!>>
Endpoint = <<!!ip_oracle!!>>:51819
PersistentKeepalive = 25       

7.PNG.jpg

 

 

 

 

 

 

5. <다시 Oracle 인스턴스로 넘어가자>

이제 오라클 인스턴스에서 아까 넣지 못했던 값을 넣읍시다.

cd /etc/wireguard/
nano wg0.conf       
<...>

[Peer]
PublicKey = <<!!public_home!!>>

<...>       

8.PNG.jpg

 

이제 모든 설정이 완료되었습니다.

 

 

 

 

 

 

6. <동시에>

오라클 인스턴스Proxmox 컨테이너에 아래와 같이 입력해줍시다.

systemctl start wg-quick@wg0.service && systemctl enable wg-quick@wg0.service       

 

 

이제 wg로 상태를 확인해봅시다.

wg       

9.PNG.jpg

latest handshake 값이 있다면 일단 접속까진 성공한 겁니다.

 

 

 

그렇다면 이제 오라클 인스턴스에서 npm 컨테이너로 접근 가능한지를 봅시다.

ping <<!!npm_ip!!>>       

10.jpg

이제 Proxmox쪽에서 GUI를 통해 방화벽을 설정해서, 필요한 컨테이너의 특정 포트로만 접속할 수 있도록 설정해주시면 됩니다.

 

 

 

 

 

 

 

7. <끝>

 

11.PNG.jpg 

 

춘천 리전에서 VM.Standard.A1.Flex 인스턴스에다 돌렸을 때 다음과 같이 핑/속도가 나옵니다. (400 가까이 찍을 때도 있습니다.)

 

오라클에서 wireguard를 돌릴 때 이상하게 안되는 부분이 좀 있었어서... 찾아놨던 정보들을 한 곳에 모아두면 좋겠다는 생각이 들어 적어둡니다.

그리고 분명히 저도 나중에 까먹을 것 같아서......

 

 

 

 

도움이 된 글들

 

 

신고공유스크랩
5

댓글 쓰기 권한이 없습니다. 로그인

취소 댓글 등록

cmt alert

신고

"님의 댓글"

이 댓글을 신고하시겠습니까?

댓글 삭제

"님의 댓글"

삭제하시겠습니까?


목록

공유

facebooktwitterpinterestbandkakao story
번호 분류 제목 글쓴이 날짜 조회 추천
잡담 proxmox로 갈아탔습니다 7 기현 23시간 전07:34 291 +2
잡담 Immich가 FUTO에 합류했습니다.(Immich 핵심 팀은 정규직으로 근무합니다.) 4 달소 1일 전11:38 259 +1
정보 오픈아이콘 제공 사이트(https://cdn.jsdelivr.net) 오류 발생 => 복구됨 2 지딱코 2일 전14:31 214 +1
3894 질문
normal
스키피95 6시간 전00:07 40 0
3893 질문
normal
고심분투 13시간 전17:10 120 0
3892 질문
image
경호 14시간 전15:50 65 0
3891 질문
normal
경호 17시간 전13:23 47 0
3890 잡담
image
기현 23시간 전07:34 291 +2
3889 잡담
image
keiminem 1일 전13:12 423 0
3888 잡담
normal
달소 1일 전11:38 259 +1
3887 질문
image
EXP 2일 전23:48 84 0
3886 질문
normal
홍익 2일 전19:26 205 0
3885 정보
image
지딱코 2일 전14:31 214 +1
3884 가이드
image
달소 3일 전22:22 359 +3
3883 가이드
image
ljr10 3일 전08:20 167 0
3882 가이드
image
달소 4일 전06:46 185 +1
3881
image
달소 4일 전05:50 206 +6
3880 정보
image
달소 4일 전05:38 124 0
3879 잡담
image
달소 4일 전05:20 407 0
3878 오픈소스
image
keiminem 4일 전17:43 352 +3
3877 질문
normal
purndal 4일 전14:32 241 0
3876 질문
image
초보나스 4일 전10:46 105 0
3875 후기
image
달소 4일 전10:03 330 0