Bayangkan Anda punya rumah bagus di dalam gang sempit yang tidak punya nomor rumah. Kurir tidak bisa mengantar paket ke sana karena alamatnya tidak terdaftar di peta. Solusinya: Anda menyewa kotak pos di jalan raya, lalu memasang lorong pribadi dari kotak pos itu langsung ke ruang tamu Anda. Kurir cukup mengantar ke kotak pos, dan paket otomatis sampai ke rumah. Prinsip yang persis sama juga berlaku untuk akses Proxmox dari internet.
Sayangnya, begitulah kondisi kebanyakan server rumahan dan server kantor kecil di Indonesia. Internet dari ISP rumahan, Starlink, maupun modem seluler hampir selalu berada di balik CGNAT, sehingga server Anda tidak punya IP publik dan orang luar tidak bisa membukanya. Pada tutorial ini kita membahas langkah demi langkah cara membuka server Proxmox tanpa IP publik dan tanpa port forwarding: sebuah VPS murah menjadi “kotak pos” di jalan raya, sedangkan WireGuard menjadi lorong pribadinya.
Selain itu, semua langkah di bawah ini adalah konfigurasi yang benar-benar kami jalankan di server produksi: satu PC Proxmox VE di kantor (internet Starlink) yang menjalankan beberapa container LXC berisi aplikasi web Laravel, CodeIgniter, dan PHP, lalu kami buka ke publik lewat satu VPS kecil (2 core, 2 GB RAM). Akan tetapi, kami sudah mengganti IP address, domain, dan key WireGuard dengan nilai contoh, lalu menyensor screenshot asli.

Kenapa Internet Tidak Bisa Menjangkau Server Lokal?
Ada dua penghalang utama. Pertama, CGNAT (Carrier-Grade NAT): ISP memberi router Anda IP privat (misalnya 100.64.x.x) yang ratusan pelanggan lain pakai bersama. Akibatnya, koneksi dari luar tidak tahu harus menuju rumah siapa. Kedua, meskipun Anda punya IP publik, membuka port panel Proxmox (8006) langsung ke internet adalah ide yang sangat berbahaya karena panel itu akan menjadi sasaran brute force setiap hari.
Oleh karena itu, kuncinya ada pada arah koneksi. CGNAT memblokir koneksi masuk, tetapi selalu mengizinkan koneksi keluar. Jadi, kita balik logikanya: server Proxmox yang menghubungi VPS lebih dulu dan menjaga koneksi itu tetap hidup. Setelah lorong terbentuk, lalu lintas dari internet akhirnya bisa lewat dua arah.
Perbandingan Pilihan Solusi
| Metode | Kelebihan | Kekurangan |
|---|---|---|
| Port forwarding di router | Gratis, sederhana | Tidak bisa di balik CGNAT, IP sering berubah |
SSH reverse tunnel (ssh -R) | Tidak perlu software tambahan | Mudah putus, satu tunnel per port, lambat untuk banyak layanan |
| Cloudflare Tunnel | Gratis, tanpa VPS | Terikat Cloudflare, aturan konten & ukuran upload, bukan untuk SSH/panel tanpa Zero Trust |
| Tailscale / ZeroTier | Instalasinya sangat mudah | Bergantung layanan pihak ketiga, akses publik (website) tetap butuh fitur tambahan |
| WireGuard + VPS sendiri | Cepat, ringan, kendali penuh, satu IP publik untuk banyak situs, IP statis untuk whitelist | Perlu sewa VPS dan sedikit konfigurasi (artikel ini membahasnya tuntas) |
Pada akhirnya, kami memilih WireGuard + VPS karena semua komponen ada di tangan sendiri, performanya tinggi (WireGuard berjalan di kernel Linux), dan satu VPS kecil cukup untuk melayani puluhan domain.
Rencana Jaringan (IP Plan)
Sebelum mengetik perintah apa pun, susun dulu alokasi IP untuk setiap perangkat. Dengan begitu, Anda terhindar dari bentrok IP yang paling sering membuat tunnel “tersambung tetapi tidak bisa apa-apa”.
| Perangkat | IP Address | Keterangan |
|---|---|---|
| VPS jembatan | 203.0.113.10 (publik), 10.99.0.1 (wg0) | Hub WireGuard + Nginx penerus trafik |
| Server Proxmox | 192.168.1.10 (LAN), 10.99.0.2 (wg0) | Peer WireGuard, router untuk container |
| Laptop admin | 10.99.0.3 (wg0) | Untuk membuka panel Proxmox dari luar |
| Jaringan container (vmbr1) | 10.10.10.0/24 | LXC 101 = .11, LXC 102 = .12, LXC 103 = .13 |
Selain itu, pastikan LAN kantor maupun jaringan rumah laptop Anda tidak memakai subnet 10.99.0.0/24 dan 10.10.10.0/24.
Langkah 1: Siapkan VPS sebagai Hub WireGuard
Pertama, gunakan VPS Linux apa saja (contoh di sini Ubuntu 24.04). Spesifikasi kecil sudah cukup, sebab VPS hanya meneruskan trafik. Pasang WireGuard lalu buat pasangan key (private key dan public key):
sudo apt update && sudo apt install -y wireguard cd /etc/wireguard sudo sh -c 'umask 077; wg genkey | tee vps.key | wg pubkey > vps.pub' sudo cat vps.pub # public key ini nanti dipasang di Proxmox & laptop
Perintah umask 077 memastikan hanya root yang bisa membaca file private key. Oleh karena itu, jangan pernah mengirim private key ke mana pun. Anda cukup membagikan public key.
Setelah itu, aktifkan IP forwarding supaya VPS boleh meneruskan paket antar-peer:
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf sudo sysctl --system
Buat file /etc/wireguard/wg0.conf di VPS. Anda baru mengisi public key Proxmox dan laptop setelah Langkah 2 dan Langkah 6:
[Interface] Address = 10.99.0.1/24 ListenPort = 51820 PrivateKey = ISI_DENGAN_ISI_FILE_vps.key # Server Proxmox: IP wg0 + IP LAN Proxmox + jaringan container [Peer] PublicKey = PUBLIC_KEY_PROXMOX AllowedIPs = 10.99.0.2/32, 192.168.1.10/32, 10.10.10.0/24 # Laptop admin [Peer] PublicKey = PUBLIC_KEY_LAPTOP AllowedIPs = 10.99.0.3/32
Selanjutnya, bagian terpenting adalah AllowedIPs. Di sisi VPS, nilai ini berarti “paket menuju IP ini kirim lewat peer tersebut”. Karena 10.10.10.0/24 dan 192.168.1.10/32 masuk ke peer Proxmox, VPS tahu bahwa container dan panel Proxmox berada di ujung tunnel itu.
Terakhir, buka firewall lalu jalankan:
sudo ufw allow 22/tcp sudo ufw allow 80,443/tcp sudo ufw allow 51820/udp sudo ufw route allow in on wg0 out on wg0 # izinkan laptop -> Proxmox lewat VPS sudo ufw enable sudo systemctl enable --now wg-quick@wg0
Langkah 2: Hubungkan Proxmox ke VPS
Berikutnya, masuk ke shell Proxmox (lewat panel Node → Shell atau SSH di jaringan lokal). Karena Proxmox berbasis Debian, caranya pun sama:
apt update && apt install -y wireguard cd /etc/wireguard sh -c 'umask 077; wg genkey | tee pve.key | wg pubkey > pve.pub' cat pve.pub # salin ke PUBLIC_KEY_PROXMOX di wg0.conf VPS
Kemudian, buat /etc/wireguard/wg0.conf di Proxmox:
[Interface] Address = 10.99.0.2/24 PrivateKey = ISI_DENGAN_ISI_FILE_pve.key [Peer] PublicKey = PUBLIC_KEY_VPS Endpoint = 203.0.113.10:51820 AllowedIPs = 10.99.0.0/24 PersistentKeepalive = 25
PersistentKeepalive = 25 adalah kunci agar tunnel tembus CGNAT. Setiap 25 detik Proxmox mengirim paket kecil ke VPS, sehingga NAT ISP tidak menutup “lubang” tersebut. Sebaliknya, tanpa baris ini, tunnel akan terlihat tersambung tetapi VPS tidak bisa menghubungi Proxmox setelah beberapa menit tidak ada trafik.
systemctl enable --now wg-quick@wg0 # setelah wg0.conf VPS diisi public key Proxmox, di VPS jalankan: sudo systemctl restart wg-quick@wg0 sudo wg show
Jika berhasil, bagian latest handshake akan menampilkan waktu beberapa detik yang lalu, seperti screenshot asli dari VPS kami berikut:

Langkah 3: Buat Jaringan Internal untuk Container
Selanjutnya, agar VPS bisa menjangkau container (LXC) tanpa mengotori LAN kantor, kita buat bridge internal vmbr1. Dengan demikian, Proxmox bertindak sebagai router dan NAT bagi container. Tambahkan ke /etc/network/interfaces di Proxmox:
auto vmbr1
iface vmbr1 inet static
address 10.10.10.1/24
bridge-ports none
bridge-stp off
bridge-fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
Kemudian, terapkan dengan ifreload -a. Baris MASQUERADE membuat container bisa mengakses internet (untuk apt update, composer, dan lain-lain) melalui IP Proxmox.
Setelah itu, buat container. Cek nama template terbaru dengan pveam available, download dengan pveam download local NAMA_TEMPLATE, lalu:
pct create 101 local:vztmpl/debian-13-standard_13.1-2_amd64.tar.zst \ --hostname web --cores 2 --memory 2048 --rootfs local-lvm:20 \ --net0 name=eth0,bridge=vmbr1,ip=10.10.10.11/24,gw=10.10.10.1 \ --nameserver 1.1.1.1 --unprivileged 1 --onboot 1 pct start 101 pct exec 101 -- ping -c 2 10.99.0.1 # container -> VPS lewat tunnel

Langkah 4: Teruskan Trafik Web dengan Nginx SNI Passthrough
Tunnel sudah jadi. Namun, bagaimana pengunjung website sampai ke container? Kita pasang Nginx modul stream di VPS. Modul ini membaca SNI (nama domain yang browser kirim di awal koneksi HTTPS) lalu meneruskan koneksi ke container yang tepat tanpa membuka enkripsinya.

sudo apt install -y nginx libnginx-mod-stream
sudo mkdir -p /etc/nginx/stream.d
# tambahkan di /etc/nginx/nginx.conf, DI LUAR blok http { }:
# include /etc/nginx/stream.d/*.conf;
Buat /etc/nginx/stream.d/sni-router.conf:
stream {
map $ssl_preread_server_name $backend {
hostnames;
app.contoh.com lxc_web;
shop.contoh.com lxc_apps;
default lxc_web;
}
upstream lxc_web { server 10.10.10.11:443; }
upstream lxc_apps { server 10.10.10.13:443; }
server {
listen 443;
ssl_preread on; # baca SNI tanpa membuka TLS
proxy_pass $backend;
proxy_protocol on; # kirim IP asli pengunjung ke container
proxy_connect_timeout 10s;
proxy_timeout 300s;
}
}
Penjelasan singkat setiap bagian:
map $ssl_preread_server_name: tabel pencocokan domain ke tujuan. Tambah domain baru cukup dengan menambah satu baris.ssl_preread on: mengizinkan Nginx mengintip SNI dari paket ClientHello.proxy_protocol on: tanpa ini, semua pengunjung akan tercatat ber-IP10.99.0.1(IP VPS di tunnel). Sebaliknya, dengan PROXY protocol, Nginx ikut mengirim IP asli di depan koneksi.
Karena modul stream sekarang memegang port 443, pastikan tidak ada blok server di bagian http yang ikut listen 443. Untuk port 80 (HTTP dan verifikasi Let’s Encrypt), teruskan berdasarkan nama host di blok http, misalnya file /etc/nginx/sites-available/00-penerus:
map $host $http_backend {
hostnames;
app.contoh.com 10.10.10.11;
shop.contoh.com 10.10.10.13;
default 10.10.10.11;
}
server {
listen 80 default_server;
server_name _;
location / {
proxy_pass http://$http_backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Aktifkan, uji, lalu muat ulang:
sudo ln -s /etc/nginx/sites-available/00-penerus /etc/nginx/sites-enabled/ sudo rm -f /etc/nginx/sites-enabled/default sudo nginx -t && sudo systemctl reload nginx
Langkah 5: Konfigurasi Nginx dan SSL di Container
Selanjutnya, di dalam container, Nginx harus siap menerima PROXY protocol dari VPS. Buat /etc/nginx/conf.d/00-realip.conf:
# Koneksi publik selalu datang dari VPS lewat WireGuard set_real_ip_from 10.99.0.1; real_ip_header proxy_protocol;
Kemudian, buat vhost aplikasinya, misalnya Laravel/CodeIgniter dengan PHP-FPM:
server {
listen 443 ssl proxy_protocol;
http2 on; # Nginx 1.24 (Ubuntu 24.04): pakai "listen 443 ssl http2 proxy_protocol;"
server_name app.contoh.com;
root /var/www/app/public;
index index.php;
ssl_certificate /etc/letsencrypt/live/app.contoh.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.contoh.com/privkey.pem;
location / { try_files $uri $uri/ /index.php?$query_string; }
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
}
server {
listen 80;
server_name app.contoh.com;
real_ip_header X-Forwarded-For; # port 80 datang via proxy http di VPS
location ^~ /.well-known/acme-challenge/ { root /var/www/acme; }
location / { return 301 https://$host$request_uri; }
}
Arahkan DNS app.contoh.com (record A) ke IP VPS 203.0.113.10. Jika memakai Cloudflare, setel ke DNS only (awan abu-abu) agar SNI passthrough bekerja. Setelah DNS aktif, terbitkan sertifikat dari dalam container. Validasi HTTP-01 akan lewat VPS di port 80, lalu VPS meneruskannya ke container:
apt install -y certbot mkdir -p /var/www/acme # sementara blok 443 belum punya sertifikat, aktifkan dulu blok port 80 saja certbot certonly --webroot -w /var/www/acme -d app.contoh.com \ --agree-tos -m admin@contoh.com --non-interactive nginx -t && systemctl reload nginx
Selain itu, perpanjangan otomatis berjalan dari certbot.timer di dalam container, jadi VPS tidak perlu menyimpan sertifikat apa pun.
Uji dari Internet

Selanjutnya, perhatikan bagian bawah gambar: access log di container mencatat IP server penguji yang asli, bukan IP VPS. Itu bukti PROXY protocol bekerja, sehingga fitur seperti pembatasan login, log aktivitas, dan blokir IP di aplikasi tetap akurat.
Langkah 6: Akses Panel Proxmox dari Laptop di Luar Kantor
Namun, jangan pernah membuka panel Proxmox (port 8006) ke publik. Sebagai gantinya, jadikan laptop sebagai peer WireGuard. Pasang aplikasi WireGuard (Windows/macOS/Linux/Android/iOS), buat tunnel baru (aplikasi otomatis membuat private key), lalu isi:
[Interface] PrivateKey = (dibuat otomatis oleh aplikasi WireGuard) Address = 10.99.0.3/24 [Peer] PublicKey = PUBLIC_KEY_VPS Endpoint = 203.0.113.10:51820 AllowedIPs = 10.99.0.0/24, 192.168.1.10/32, 10.10.10.0/24 PersistentKeepalive = 25
Salin public key laptop ke PUBLIC_KEY_LAPTOP di wg0.conf VPS, lalu restart wg-quick@wg0 di VPS. Setelah itu, klik Activate di laptop. Kini Anda bisa membuka panel di https://192.168.1.10:8006 dari mana saja.
Perhatikan AllowedIPs di laptop: hanya tiga jaringan itu yang lewat tunnel. Internet biasa (YouTube, email, dan lain-lain) tetap lewat koneksi laptop sendiri, jadi tidak membebani VPS. Teknik ini bernama split tunnel.
Contoh Kasus Nyata
Contoh Kasus 1: Memindahkan Server Development ke PC Kantor
Awalnya, kami menyewa VPS development 4 GB untuk menjalankan staging lima aplikasi (Laravel + PostgreSQL, CodeIgniter + MySQL, dan bot PHP). Biayanya terus berjalan, padahal di kantor ada PC 40 thread dan RAM 46 GB yang menganggur. Dengan arsitektur ini:
- Pertama, kami memasang Proxmox VE di PC kantor, lalu memberi setiap kelompok aplikasi satu container LXC (web hotel, billing, aplikasi lain).
- Kemudian, kami mengganti VPS dev lama dengan VPS kecil 2 GB yang hanya menjalankan WireGuard + Nginx stream + monitoring.
- Terakhir, kami cukup mengarahkan semua subdomain lama ke IP VPS baru. Pengguna tidak merasakan perbedaan, sertifikat SSL tetap valid, dan URL situs tidak berubah.
Hasilnya, kapasitas server naik berkali lipat dengan biaya bulanan lebih kecil. Kalau internet kantor putus, VPS bisa menampilkan halaman “sedang pemeliharaan” untuk situs yang di-proxy dari VPS, sehingga pengguna tidak melihat error kosong.
Contoh Kasus 2: IP Statis untuk Whitelist API, SMTP, dan SSH
Beberapa layanan hanya menerima koneksi dari IP yang sudah terdaftar, misalnya API payment gateway, SMTP relay seperti Brevo, atau SSH ke server produksi yang dibatasi firewall. Starlink dan ISP rumahan memberi IP yang berubah-ubah, jadi whitelist mustahil. Solusinya: kirim trafik ke tujuan tertentu saja lewat VPS.
# Di Proxmox: tambahkan IP tujuan ke AllowedIPs peer VPS AllowedIPs = 10.99.0.0/24, 198.51.100.25/32
# Di VPS: samarkan (NAT) trafik dari tunnel yang keluar ke internet sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE sudo iptables -t nat -A POSTROUTING -s 10.99.0.0/24 -o eth0 -j MASQUERADE sudo ufw route allow in on wg0 out on eth0
Sekarang server 198.51.100.25 melihat semua koneksi dari container datang dari IP statis VPS, sehingga cukup satu IP itu yang di-whitelist. Trafik ke tujuan lain tetap lewat internet kantor. Agar aturan NAT tidak hilang saat reboot, simpan di /etc/ufw/before.rules (bagian *nat) atau gunakan iptables-persistent.
Tips Keamanan
- Private key tetap tersimpan di perangkat yang membuatnya. Sebaliknya, perangkat lain cukup menerima public key.
- Satu perangkat = satu peer dengan key sendiri. Jika laptop hilang, cukup hapus blok
[Peer]laptop itu di VPS, tanpa mengganti key perangkat lain. - Jangan buka port 8006 atau 22 Proxmox di VPS. Akses admin cukup lewat tunnel.
- Pasang
fail2banatau CrowdSec di VPS karena VPS adalah satu-satunya pintu yang terlihat dari internet. - Batasi container dengan
--unprivileged 1agar root di container tidak sama dengan root di host Proxmox.
Kesalahan Umum
- Handshake ada, tapi VPS tidak bisa ping Proxmox: lupa
PersistentKeepalivedi sisi Proxmox, ataunet.ipv4.ip_forwardbelum aktif di VPS. - VPS tidak bisa menjangkau container: Anda belum memasukkan
10.10.10.0/24keAllowedIPspeer Proxmox di VPS. Setelah mengubah peer denganwg set, pastikan rute juga ada (ip route replace 10.10.10.0/24 dev wg0), atau cukup restartwg-quick@wg0. - Nginx VPS gagal start setelah menambah file stream: hanya boleh ada satu blok
stream { }. Gabungkan semua konfigurasi stream ke satu file. - Error “bind() to 0.0.0.0:443 failed”: masih ada vhost di blok
httpyanglisten 443. Karena itu, pindahkan situs yang memang berjalan di VPS kelisten 127.0.0.1:8443 ssl proxy_protocollalu arahkan dari peta SNI. - “unknown directive http2”: Nginx 1.24 bawaan Ubuntu 24.04 belum mengenal
http2 on;. Gunakanlisten 443 ssl http2 proxy_protocol;. - Semua pengunjung tercatat ber-IP 10.99.0.1:
proxy_protocol ondi VPS ataureal_ip_header proxy_protocoldi container terlewat. - Browser menampilkan “broken header” / koneksi terputus: VPS mengirim PROXY protocol, tetapi
listendi container belum diberi parameterproxy_protocol(atau sebaliknya). Keduanya harus sepasang. - Certbot gagal validasi: DNS masih proxied Cloudflare, atau port 80 di VPS tidak meneruskan
/.well-known/acme-challenge/ke container yang benar. apt updatedi container sering gagal resolve DNS: pada sebagian jalur NAT (terutama Starlink), query A dan AAAA paralel sering hilang. Tambahkanoptions single-request-reopendan dua sampai tiga nameserver di/etc/resolv.confcontainer.- Laptop di kantor jadi lambat ke Proxmox: rute
/32di tunnel mengalahkan rute LAN. Matikan tunnel saat berada di jaringan yang sama dengan server.
Kesimpulan
Dengan satu VPS kecil dan WireGuard, Anda bisa akses Proxmox dari internet dan mempublikasikan banyak aplikasi dari server lokal, meskipun koneksi kantor berada di balik CGNAT tanpa IP publik. Server Proxmox membuka koneksi keluar ke VPS, VPS memilah trafik HTTPS berdasarkan nama domain dengan Nginx SNI passthrough, sementara setiap container tetap mengelola sertifikat SSL-nya sendiri. Selain itu, panel Proxmox tetap tertutup dari publik, dan hanya laptop yang terdaftar sebagai peer WireGuard yang bisa membukanya.
Dengan demikian, pola ini cocok untuk server development, aplikasi internal kantor, hingga layanan produksi skala kecil. Kalau nanti kapasitas bertambah, cukup tambah container dan satu baris di peta SNI, tanpa menyentuh router atau meminta IP publik ke ISP.
Baca Juga
- Cara Memasang SSL dan HTTPS di WordPress
- Cara Upload Website PHP ke Hosting (cPanel) untuk Pemula
- Cara Mencegah Serangan XSS dan CSRF di PHP
Referensi: WireGuard Quick Start, Proxmox VE: Linux Container, Nginx ngx_stream_ssl_preread_module, Nginx proxy_protocol.

