Cara Install WireGuard VPN di VPS Linux
Panduan lengkap setup WireGuard di VPS Linux. Pelajari cara konfigurasi wg0.conf, IP forwarding, NAT, hingga solusi gagal handshake pada kernel Linux terbaru.
Apa yang Anda bangun
WireGuard VPN pada server milik Anda hanya membutuhkan sekitar empat puluh baris konfigurasi: satu pasangan kunci, satu file interface, satu sysctl, satu aturan NAT, dan satu celah firewall. Proses instalasi sangat mudah, sehingga sebagian besar panduan ini membahas hal-hal yang sering bermasalah — izin kunci, AllowedIPs, forwarding, dan DNS.
WireGuard adalah tunnel Layer 3 di dalam kernel, dan telah menjadi bagian utama sejak Linux 5.6, sehingga Ubuntu 24.04 dan Debian 13 menyediakannya tanpa modul eksternal. Tidak ada negosiasi cipher, tidak ada otoritas sertifikat, dan tidak ada langkah username/password: sebuah peer adalah kunci publik ditambah alamat IP yang boleh digunakan oleh kunci tersebut. Paket yang gagal dalam pemeriksaan MAC akan dibuang tanpa balasan, sehingga port tersebut tidak akan menjawab pemindaian. Sisi lainnya: tidak ada server autentikasi, sehingga untuk mencabut akses berarti menghapus peer pada perangkat tersebut.
Periksa virtualisasi terlebih dahulu
WireGuard memerlukan kernel yang memungkinkan pemuatan modul, dan pada KVM VPS hal ini dapat langsung digunakan. Pada virtualisasi berbasis kontainer yang berbagi kernel host — OpenVZ, LXC — perintah pertama akan gagal dengan RTNETLINK answers: Operation not supported, dan solusi cadangannya adalah implementasi userspace wireguard-go. Periksa terlebih dahulu dengan sudo modprobe wireguard && echo ok.
Generate keys without leaking them
/etc/wireguard/server.key yang dapat dibaca oleh semua pengguna sama saja dengan tidak menggunakan VPN sama sekali. Baris umask 077 && wg genkey | sudo tee ... yang umum digunakan tidak dapat diandalkan, karena sudo menerapkan umask sendiri pada file yang dibuat oleh tee. Atur mode secara eksplisit.
sudo apt update && sudo apt install -y wireguard nftables
sudo install -d -m 700 /etc/wireguard
sudo sh -c 'umask 077; wg genkey > /etc/wireguard/server.key'
sudo sh -c 'wg pubkey < /etc/wireguard/server.key > /etc/wireguard/server.pub'
sudo chmod 600 /etc/wireguard/server.keyGenerate pasangan client dengan cara yang sama. wg genpsk menambahkan pre-shared key opsional, satu baris pada setiap konfigurasi.
Antarmuka server: /etc/wireguard/wg0.conf
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <contents of /etc/wireguard/server.key>
[Peer]
PublicKey = <laptop public key>
PresharedKey = <psk, optional>
AllowedIPs = 10.8.0.2/32chmod 600 jika muncul peringatan saat startup bahwa file dapat diakses oleh semua pengguna, berarti Anda melewatkan langkah tersebut. Address adalah alamat server di dalam tunnel, yang mencakup seluruh subnet VPN. Pilih rentang yang tidak akan bertabrakan dengan jaringan lain — 192.168.1.0/24 bertabrakan dengan separuh router rumahan yang digunakan klien, sehingga tunnel akan kalah secara diam-diam oleh rute lokal.
AllowedIPs milik peer pada sisi server adalah sebuah /32, yaitu satu-satunya alamat tunnel yang dimiliki klien tersebut. Jika Anda memberikan IP yang sama pada dua peer, konfigurasi akan berpindah ke peer yang terakhir dikonfigurasi, dan peer pertama akan berhenti menerima trafik tanpa ada pesan error yang muncul. Biarkan SaveConfig tidak diatur, atau wg-quick down akan menulis ulang file ini dari status yang sedang berjalan.
Ubah perangkat menjadi router
Server Linux membuang paket yang tidak ditujukan untuknya. Secara default, fitur forwarding dan source NAT belum aktif.
printf 'net.ipv4.ip_forward = 1\nnet.ipv6.conf.all.forwarding = 1\n' \
| sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system
sysctl net.ipv4.ip_forwardsysctl -w polos akan berfungsi hingga reboot berikutnya, lalu berhenti bekerja secara diam-diam. NAT membutuhkan interface egress — NIC yang terhubung ke internet, bukan wg0. Jangan berasumsi pada eth0; gunakan hasil dari ip route show default, karena image saat ini menggunakan nama seperti enp1s0 atau ens3.
Firewall: port, dan jalur forwarding
Satu file nftables mencakup filter dan NAT. Jalankan /etc/nftables.conf — perintah ini akan menghapus ruleset yang ada, jadi lewati langkah ini pada sistem yang sudah dikelola oleh ufw atau Docker.
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 accept
udp dport 51820 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname "wg0" oifname "enp1s0" accept
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.8.0.0/24 oifname "enp1s0" masquerade
}
}Terapkan dengan sudo systemctl enable --now nftables, dan biarkan sesi SSH kedua tetap terbuka: kesalahan pengetikan pada aturan SSH di policy drop akan menyebabkan Anda terkunci dari server sendiri. Perhatikan apa yang tidak diizinkan oleh forward chain — wg0 ke wg0. Peer dapat mengakses internet, tetapi tidak dapat mengakses satu sama lain; tambahkan iifname "wg0" oifname "wg0" accept untuk VPN peer-to-peer. Chain yang sama mengatur apa yang boleh diakses peer pada server itu sendiri, hal ini penting jika sistem juga berfungsi sebagai remote development box running Claude Code in tmux dan Anda tidak ingin mengekspos sisi tersebut ke publik.
Pada sistem ufw: ufw allow 51820/udp, DEFAULT_FORWARD_POLICY="ACCEPT" di dalam /etc/default/ufw, dan aturan *nat POSTROUTING MASQUERADE di bagian atas /etc/ufw/before.rules.
Jalankan di bawah systemd
sudo systemctl enable --now wg-quick@wg0
sudo wg showwg-quick membuat antarmuka, menambahkan alamat, dan memasang rute yang berasal dari AllowedIPs. enable --now adalah bagian yang penting: wg-quick up wg0 yang dijalankan secara manual akan hilang setelah reboot berikutnya, dan pembaruan kernel memerlukan reboot.
Konfigurasi client, dan pengaturan yang sering salah dipahami
[Interface]
PrivateKey = <laptop private key>
Address = 10.8.0.2/32
DNS = 10.8.0.1
[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25AllowedIPs menjalankan dua fungsi sekaligus, dan mencampuradukkan keduanya adalah penyebab utama kebingungan WireGuard.
Untuk outbound, ini adalah tabel routing. Paket dengan tujuan yang cocok dengan AllowedIPs milik peer akan dienkripsi dan dikirim ke peer tersebut. 0.0.0.0/0, ::/0 mengirim semua data melalui tunnel — tunnel penuh, dengan server sebagai default route. Split tunnel memiliki daftar yang lebih sempit: AllowedIPs = 10.8.0.0/24, 10.20.0.0/16 hanya membawa trafik VPN ditambah satu jaringan privat di belakang server, sementara semua data lainnya tetap menggunakan route lokal. Daftar sempit tersebut memungkinkan Anda menjaga layanan tetap terpisah dari internet publik — seperti instansi Nextcloud privat pada VPS yang terikat pada alamat tunnel, atau VM lab nested-virtualisation yang berjalan pada mesin yang sama, tetap dapat dijangkau oleh peer dan tidak terlihat oleh orang lain.
Untuk inbound, ini adalah access-control list. Paket terdekripsi dari peer dengan alamat sumber yang tidak terdaftar dalam AllowedIPs milik peer tersebut akan dibuang. Itulah sebabnya server mencantumkan 10.8.0.2/32 untuk laptop: entri 0.0.0.0/0 di sana akan memungkinkan client tersebut memalsukan alamat apa pun di dalam tunnel.
PersistentKeepalive digunakan untuk client di balik NAT, di mana router hanya menjaga pemetaan UDP tetap terbuka selama ada paket yang mengalir. Saat koneksi kedaluwarsa, server tidak dapat lagi menjangkau client. PersistentKeepalive = 25 menjaga pemetaan tetap terbuka — atur ini pada client, bukan pada server dengan IP publik.
DNS, dan kebocoran yang tidak disadari
Dengan AllowedIPs = 0.0.0.0/0 dan tanpa baris DNS =, klien akan tetap menggunakan resolver yang didapat dari jaringan lokal — router kafe di 192.168.1.1. Rute tersebut lebih spesifik daripada rute default, sehingga kueri DNS keluar melalui tautan lokal dalam bentuk cleartext sementara data lainnya masuk ke dalam tunnel. Trafik bersifat privat; daftar nama tidak.
Ada dua opsi yang aman. Arahkan DNS ke resolver publik (DNS = 9.9.9.9) agar kueri melewati tunnel dan keluar dari server Anda, meskipun resolver tersebut tetap dapat melihatnya. Atau jalankan unbound atau dnsmasq yang terikat pada 10.8.0.1, atur DNS = 10.8.0.1, dan tambahkan udp dport 53 iifname "wg0" accept ke input chain — jika baris tersebut diatur, resolver tidak akan berfungsi dan tidak ada resolusi yang berjalan.
Pada klien Linux, wg-quick menerapkan DNS melalui resolvconf; jika tidak ada, Anda akan mendapatkan resolvconf: command not found. Instal openresolv, atau atur PostUp = resolvectl dns %i 10.8.0.1 pada klien systemd-resolved.
Menambah dan menghapus peer tanpa memutus tunnel
Memulai ulang interface untuk menambah pengguna akan memutuskan semua koneksi yang ada. Tambahkan blok [Peer] ke wg0.conf, lalu muat ulang peer set secara langsung.
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'wg-quick strip mencetak konfigurasi tanpa kunci wg-quick-only (Address, DNS, PostUp), dan syncconf menerapkan perubahan tersebut sementara sesi yang sedang berjalan tetap aktif. Perintah ini hanya memperbarui peer: perubahan pada Address tetap memerlukan proses down/up secara penuh. Batalkan dengan sudo wg set wg0 peer <public key> remove, lalu hapus blok tersebut dari file agar tidak muncul kembali pada pemuatan berikutnya.
Mode kegagalan, dengan string yang akan Anda lihat
Handshake tidak pernah selesai. wg show mencantumkan peer tanpa latest handshake, dan log klien menunjukkan:
Handshake for peer 1 (10.0.0.10:51820) did not complete after 5 seconds, retrying (try 2)Tidak ada data yang masuk, atau tidak ada data yang diterima. Periksa hal berikut secara berurutan: apakah UDP 51820 sudah terbuka pada firewall VPS dan pada firewall jaringan penyedia layanan Anda (kontrol terpisah pada sebagian besar panel); apakah alamat dan port Endpoint sudah benar; apakah kunci sudah tertukar. Kunci pada blok [Peer] klien harus merupakan kunci publik server, dan sebaliknya — menempelkan kunci privat, atau kunci publik milik klien sendiri, akan menyebabkan gejala ini. sudo tcpdump -ni any udp port 51820 pada server menunjukkan apakah paket sampai atau tidak. Modul kernel tidak mencatat apa pun secara default; pesan WireGuard muncul di dmesg hanya setelah Anda mengaktifkan dynamic debug (echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control), dan jika fitur tersebut aktif, ketidakcocokan kunci akan muncul sebagai invalid-MAC drop.
Handshake berhasil, tidak ada internet. ping 10.8.0.1 berhasil tetapi ping 1.1.1.1 mengalami timeout: forwarding atau NAT tidak tersedia. Periksa apakah sysctl net.ipv4.ip_forward membaca 1, lalu pantau penghitung (counter) saat klien melakukan ping, menggunakan sudo nft list ruleset atau sudo iptables -t nat -L POSTROUTING -n -v. Jika tidak ada paket pada aturan masquerade, berarti nama interface egress salah; penghitung yang terus naik tanpa ada balasan menunjukkan masalah pada kebijakan forward chain.
Internet berfungsi, nama domain tidak. ping 1.1.1.1 berhasil dan curl https://example.com mengembalikan Could not resolve host. Baris DNS hilang, atau menyebutkan resolver yang tidak dapat dijangkau dari dalam tunnel.
Beberapa situs HTTPS macet. SSH dan ping berfungsi normal; halaman besar mengalami stall. Itu adalah masalah path MTU: tunnel menambah overhead, dan salah satu link di tengah menjatuhkan paket yang terlalu besar tanpa mengirimkan pesan ICMP kembali. Turunkan MTU pada [Interface] klien — coba 1420, lalu 1380, lalu 1280.
Interface menolak untuk berjalan. Address already in use berarti proses lain sedang menggunakan UDP 51820. Cannot find device wg0 setelah up gagal biasanya berarti konfigurasi ditolak; baca journalctl -u wg-quick@wg0 -n 50.
Migrasi dari Streisand atau OpenVPN
Streisand sudah tidak dikelola dan repositorinya telah diarsipkan. Menjalankan VPN pada sistem otomatisasi yang terbengkalai akan menimbulkan masalah keamanan jangka panjang. Tidak ada pembaruan langsung (in-place upgrade), dan PKI OpenVPN tidak dapat dikonversi: WireGuard tidak menggunakan sertifikat, CA, maupun masa berlaku, sehingga setiap klien mendapatkan pasangan kunci baru.
Lakukan migrasi secara paralel — WireGuard pada UDP 51820 dapat berjalan bersamaan dengan OpenVPN pada 1194 di mesin yang sama. Instal wg0, pindahkan klien satu per satu, lalu hentikan layanan lama. Model username/password dan pencabutan (revocation) OpenVPN tidak dapat dipindahkan; jika Anda memerlukan akun atau jejak audit, terapkan lapisan tersebut di atas WireGuard.
Backup, upgrade, dan kendala pada skala besar
/etc/wireguard adalah servernya. Lakukan backup (sudo tar czf wg-backup.tgz -C /etc wireguard, mode 600, simpan di luar server) agar Anda dapat membangun ulang pada VPS baru dalam hitungan menit. Jika kunci privat server hilang, setiap konfigurasi klien harus diterbitkan ulang karena klien mengunci kunci publik server. Upgrade adalah proses apt upgrade biasa ditambah reboot untuk pembaruan kernel, dan wg-quick@wg0 akan berjalan otomatis jika Anda mengaktifkannya.
Status per-peer berukuran kecil dan kriptografi berjalan di kernel, sehingga batas kemampuannya adalah CPU dan kuota bandwidth VPS Anda, bukan batasan pada konfigurasi ini — ukur menggunakan iperf3 melalui tunnel daripada mempercayai angka yang dipublikasikan. Kendala pada skala besar adalah operasional. Setiap peer memerlukan IP tunnel yang unik, dan mengedit manual enam puluh blok [Peer] dapat menyebabkan duplikasi AllowedIPs: buatlah konfigurasi menggunakan skrip. Satu server adalah satu endpoint UDP dan satu titik kegagalan (point of failure), dan WireGuard tidak memiliki fitur clustering: redundansi berarti menggunakan server kedua dengan kunci sendiri. Rotasi kunci tetap dilakukan secara manual, jadi catat siapa yang memegang kunci tertentu dan bagaimana cara mencabutnya.
Semua ini memerlukan mesin Linux yang Anda kendalikan — IP publik, kernel yang dapat dimuat modulnya, dan firewall yang Anda kuasai sepenuhnya.
FAQ
Mengapa handshake WireGuard tidak pernah selesai?
wg show yang mencantumkan peer tanpa latest handshake berarti paket tidak sampai atau tidak diterima. Periksa UDP 51820 pada firewall VPS dan firewall jaringan terpisah dari penyedia Anda, konfirmasi host dan port Endpoint, lalu pastikan kunci tidak tertukar — blok [Peer] klien harus berisi kunci public server. sudo tcpdump -ni any udp port 51820 pada server menunjukkan apakah paket sampai atau tidak; dmesg hanya melaporkan kegagalan handshake WireGuard setelah Anda mengaktifkan dynamic debug (echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control), dan ketidakcocokan kunci akan muncul sebagai invalid-MAC drop.
Tunnel terhubung tetapi saya tidak memiliki akses internet. Apa yang kurang?
ping 10.8.0.1 yang berfungsi sementara ping 1.1.1.1 mengalami timeout menunjukkan masalah pada forwarding atau NAT. Pastikan sysctl net.ipv4.ip_forward membaca 1 dan sudah diatur di /etc/sysctl.d/, bukan hanya menggunakan sysctl -w yang hilang saat reboot. Kemudian periksa nama aturan masquerade untuk interface egress asli Anda dari ip route show default — enp1s0 atau ens3, jarang sekali eth0.
Apakah saya memerlukan baris DNS = pada konfigurasi klien saya?
Dengan full tunnel tanpa baris DNS =, klien akan tetap menggunakan resolver dari jaringan lokal. Query tersebut akan terkirim dalam bentuk cleartext melalui link lokal sementara data lainnya masuk ke dalam tunnel. Arahkan DNS ke resolver publik, atau jalankan unbound/dnsmasq yang terikat pada 10.8.0.1 dan buka udp dport 53 iifname "wg0" pada input chain.
Apa yang sebenarnya dikontrol oleh AllowedIPs?
Ia memiliki dua fungsi. Untuk outbound, ia adalah tabel routing: trafik yang cocok dengan AllowedIPs milik peer akan dienkripsi dan dikirim ke peer tersebut. Untuk inbound, ia adalah access-control list: paket terdekripsi yang sumbernya berada di luar AllowedIPs milik peer tersebut akan dibuang (dropped). Itulah sebabnya sisi server mencantumkan /32 per klien, sementara sisi klien mungkin mencantumkan 0.0.0.0/0.
Apakah WireGuard dapat berjalan di VPS mana pun?
Pada KVM VPS, ia bekerja menggunakan modul in-kernel tanpa pengaturan tambahan. Pada virtualisasi container yang berbagi kernel host, seperti OpenVZ atau LXC, modprobe wireguard gagal dengan Operation not supported dan alternatifnya adalah implementasi userspace wireguard-go. Jalankan sudo modprobe wireguard && echo ok sebelum melakukan hal lainnya.