SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-29

Cara Membuat VPN WireGuard di VPS Linux Sendiri

Panduan WireGuard di VPS Linux: buat kunci dan wg0.conf, aktifkan forwarding serta NAT, pahami AllowedIPs, DNS, dan error handshake yang sering muncul.

Yang Anda bangun

VPN WireGuard pada server yang Anda miliki memerlukan sekitar empat puluh baris konfigurasi: satu pasangan kunci, satu file antarmuka, satu sysctl, satu aturan NAT, dan satu celah pada firewall. Instalasinya sederhana, sehingga sebagian besar panduan ini membahas hal-hal yang dapat gagal, izin kunci, AllowedIPs, forwarding, dan DNS.

WireGuard adalah tunnel Layer 3 di kernel dan telah menjadi bagian dari mainline sejak Linux 5.6. Karena itu, Ubuntu 24.04 dan Debian 13 menyertakannya tanpa modul eksternal. Tidak ada negosiasi cipher, certificate authority, atau langkah username/password: peer terdiri atas kunci publik dan alamat IP yang boleh digunakan oleh kunci tersebut. Paket yang gagal dalam pemeriksaan MAC akan dibuang tanpa balasan, sehingga port tidak merespons pemindaian. Konsekuensinya, tidak ada server autentikasi. Untuk mencabut akses, hapus peer pada server.

Periksa virtualisasi terlebih dahulu

WireGuard memerlukan kernel yang dapat dimuati modul. Pada VPS KVM, WireGuard dapat langsung digunakan. Pada virtualisasi berbasis container yang berbagi kernel host, seperti OpenVZ dan LXC, perintah pertama gagal dengan RTNETLINK answers: Operation not supported. Gunakan implementasi userspace wireguard-go sebagai alternatif. Periksa terlebih dahulu dengan sudo modprobe wireguard && echo ok.

Buat kunci tanpa membocorkannya

/etc/wireguard/server.key yang dapat dibaca oleh semua pengguna sama saja dengan tidak memiliki VPN. Baris umask 077 && wg genkey | sudo tee ... yang umum digunakan tidak andal karena sudo menerapkan umask-nya sendiri pada file yang dibuat oleh tee. Tetapkan mode file 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.key

Buat pasangan kunci klien dengan cara yang sama. wg genpsk menambahkan kunci yang dibagikan sebelumnya secara 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/32

chmod 600; peringatan saat startup yang menyatakan bahwa file dapat diakses oleh semua pengguna berarti Anda melewatkan langkah tersebut. Address adalah alamat server di dalam tunnel, dengan mask seluruh subnet VPN. Pilih rentang yang tidak akan bertabrakan dengan jaringan yang digunakan di luar, karena 192.168.1.0/24 bertabrakan dengan banyak router rumahan yang digunakan klien Anda. Akibatnya, tunnel kalah secara diam-diam terhadap rute lokal.

AllowedIPs milik peer di sisi server adalah /32, yaitu satu-satunya alamat tunnel yang dimiliki klien tersebut. Jika dua peer diberi allowed IP yang sama, alamat itu berpindah ke peer yang dikonfigurasi terakhir. Peer pertama berhenti menerima trafik tanpa pesan error apa pun. Biarkan SaveConfig tidak disetel, atau wg-quick down akan menulis ulang file ini berdasarkan status aktif.

Ubah server menjadi router

Server Linux membuang paket yang tidak ditujukan kepadanya. Forwarding dan source NAT tidak aktif secara default.

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_forward

sysctl -w polos berfungsi sampai reboot berikutnya, lalu berhenti tanpa pesan. NAT memerlukan interface egress, yaitu NIC yang terhubung ke Internet, bukan wg0. Jangan mengasumsikan eth0; ambil nama interface Anda 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 karena perintah tersebut menghapus ruleset yang ada. Jangan lakukan ini pada server 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: policy drop ditambah kesalahan ketik pada aturan SSH dapat mengunci Anda dari server sendiri. Perhatikan hal yang tidak diizinkan oleh chain forward, yaitu wg0 ke wg0. Peer dapat mengakses Internet, tetapi tidak dapat saling mengakses. Tambahkan iifname "wg0" oifname "wg0" accept untuk VPN peer-to-peer. Chain yang sama mengatur apa yang boleh diakses peer pada server itu sendiri. Ini penting jika server juga digunakan sebagai server pengembangan jarak jauh yang menjalankan Claude Code dalam tmux dan Anda tidak ingin mengekspos fungsi tersebut ke publik.

Pada server yang menggunakan ufw: ufw allow 51820/udp, DEFAULT_FORWARD_POLICY="ACCEPT" di dalam /etc/default/ufw, dan aturan POSTROUTING MASQUERADE *nat di bagian atas /etc/ufw/before.rules.

Menjalankannya dengan systemd

sudo systemctl enable --now wg-quick@wg0
sudo wg show

wg-quick membuat interface, menambahkan alamat, dan memasang rute yang diturunkan dari AllowedIPs. enable --now adalah bagian pentingnya: wg-quick up wg0 yang dijalankan manual akan hilang setelah reboot berikutnya, dan pembaruan kernel mengharuskan reboot. Unit yang gagal berjalan kembali setelah salah satu reboot tersebut tidak akan menampilkan indikasi apa pun sampai seseorang mencoba terhubung. Karena itu, drop-in OnFailure= pada wg-quick@wg0 yang diarahkan ke server ntfy Anda sendiri adalah cara termurah untuk menerima pemberitahuan di ponsel, bukan mengetahuinya dari pengguna yang tidak dapat login.

Konfigurasi client dan pengaturan yang sering disalahpahami

[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 = 25

AllowedIPs menjalankan dua fungsi yang berbeda sekaligus. Mencampurkan kedua fungsi ini menjadi penyebab sebagian besar kebingungan tentang WireGuard.

Untuk trafik keluar, pengaturan ini berfungsi sebagai tabel routing. Paket yang tujuan-nya cocok dengan AllowedIPs milik sebuah peer akan dienkripsi dan dikirim ke peer tersebut. 0.0.0.0/0, ::/0 mengirimkan semua trafik melalui tunnel, yaitu full tunnel dengan server sebagai default route. Split tunnel menggunakan daftar yang lebih sempit: AllowedIPs = 10.8.0.0/24, 10.20.0.0/16 membawa trafik VPN serta satu jaringan privat di belakang server, sedangkan trafik lainnya tetap menggunakan route lokalnya. Daftar yang lebih sempit ini memungkinkan Anda sepenuhnya menjauhkan layanan dari Internet publik. Contohnya, instance Nextcloud privat pada VPS yang terikat pada alamat tunnel, atau VM lab nested virtualisation yang berjalan pada mesin yang sama, tetap dapat diakses oleh peer dan tidak terlihat oleh pihak lain.

Untuk trafik masuk, pengaturan ini berfungsi sebagai daftar kontrol akses. Paket yang telah didekripsi dari sebuah peer akan dibuang jika alamat sumbernya tidak termasuk dalam AllowedIPs milik peer tersebut. Karena itu, server mencantumkan 10.8.0.2/32 untuk laptop. Entri 0.0.0.0/0 di sana akan memungkinkan client tersebut melakukan spoofing terhadap alamat apa pun di dalam tunnel.

PersistentKeepalive digunakan untuk client di belakang NAT, ketika router hanya mempertahankan pemetaan UDP selama ada paket yang mengalir. Setelah pemetaan tersebut kedaluwarsa, server tidak dapat lagi menjangkau client. PersistentKeepalive = 25 mempertahankan pemetaan tetap aktif. Atur pengaturan ini pada client, bukan pada server yang memiliki alamat IP publik.

DNS dan kebocoran yang tidak disadari siapa pun

Dengan AllowedIPs = 0.0.0.0/0 dan tanpa baris DNS =, klien tetap menggunakan resolver yang diperoleh dari jaringan lokal, yaitu router kafe pada 192.168.1.1. Rute tersebut lebih spesifik daripada rute default. Karena itu, kueri DNS keluar melalui tautan lokal dalam bentuk teks biasa, sementara lalu lintas lainnya diteruskan melalui tunnel. Lalu lintasnya privat, tetapi daftar nama yang diakses tidak.

Ada dua opsi yang dapat digunakan. Arahkan DNS ke resolver publik (DNS = 9.9.9.9). Kueri akan melewati tunnel dan keluar dari server Anda, tetapi resolver tersebut tetap dapat melihatnya. Atau jalankan unbound atau dnsmasq yang terikat pada 10.8.0.1, tetapkan DNS = 10.8.0.1, lalu tambahkan udp dport 53 iifname "wg0" accept ke input chain. Tetapkan baris tersebut dan abaikan resolver. Namun, tidak ada nama yang dapat di-resolve.

Pada klien Linux, wg-quick menerapkan DNS melalui resolvconf. Jika tidak ada, Anda akan mendapatkan resolvconf: command not found. Instal openresolv, atau tetapkan PostUp = resolvectl dns %i 10.8.0.1 pada klien systemd-resolved.

Menambahkan dan menghapus peer tanpa memutus tunnel

Memulai ulang interface untuk menambahkan pengguna akan memutus semua koneksi yang sedang aktif. Tambahkan blok [Peer] ke wg0.conf, lalu muat ulang kumpulan peer tanpa memutus koneksi.

sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'

wg-quick strip menampilkan konfigurasi tanpa kunci khusus wg-quick (Address, DNS, PostUp), sedangkan syncconf menerapkan perbedaannya saat tunnel tetap aktif. Perintah ini hanya memperbarui peer: perubahan pada Address tetap memerlukan proses down/up penuh. Cabut akses dengan sudo wg set wg0 peer <public key> remove, lalu hapus blok tersebut dari file. Jika tidak, blok akan muncul kembali pada pemuatan ulang berikutnya.

Mode kegagalan dan string yang akan Anda lihat

Handshake tidak pernah selesai. wg show mencantumkan peer tanpa latest handshake, dan log klien berisi:

Handshake for peer 1 (10.0.0.10:51820) did not complete after 5 seconds, retrying (try 2)

Tidak ada paket yang tiba, atau tidak ada paket yang diterima. Periksa secara berurutan: apakah UDP 51820 terbuka pada firewall VPS dan firewall jaringan provider Anda, yang pada sebagian besar panel merupakan pengaturan terpisah; apakah alamat dan port Endpoint sudah benar; apakah kunci tertukar. Kunci pada blok [Peer] milik klien harus merupakan kunci publik server, dan sebaliknya. Menempelkan kunci privat atau kunci publik milik klien sendiri akan menimbulkan gejala yang sama persis. sudo tcpdump -ni any udp port 51820 pada server menunjukkan apakah paket benar-benar tiba. Modul kernel secara default tidak mencatat apa pun. Pesan WireGuard muncul di dmesg hanya setelah Anda mengaktifkan dynamic debug (echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control). Setelah diaktifkan, ketidakcocokan kunci akan terlihat sebagai paket yang dibuang karena MAC tidak valid.

Handshake berhasil, tetapi tidak ada Internet. ping 10.8.0.1 berhasil, tetapi ping 1.1.1.1 mengalami timeout: forwarding atau NAT belum dikonfigurasi. Pastikan sysctl net.ipv4.ip_forward menghasilkan 1, lalu pantau penghitung 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. Jika penghitung bertambah tetapi tidak ada balasan, masalah kemungkinan berada pada kebijakan forward chain.

Internet berfungsi, tetapi nama host tidak. ping 1.1.1.1 berhasil dan curl https://example.com menghasilkan Could not resolve host. Baris DNS tidak ada, atau baris tersebut menetapkan resolver yang tidak dapat dijangkau dari dalam tunnel.

Beberapa situs HTTPS berhenti merespons. SSH dan ping berfungsi, tetapi halaman besar berhenti dimuat. Ini merupakan masalah path MTU: tunnel menambah overhead, dan suatu link di tengah jalur membuang paket yang terlalu besar tanpa mengirimkan pesan ICMP kembali. Turunkan MTU pada [Interface] klien, coba 1420, kemudian 1380, lalu 1280. Jika menurunkan MTU mengatasi masalah tersebut tetapi throughput masih rendah, jangan menebak dengan angka bulat. Ikuti cara menemukan path MTU yang sebenarnya dengan bisection dan melakukan clamping TCP MSS. Langkah ini juga membantu menyingkirkan penyebab yang sama sekali tidak berkaitan dengan tunnel.

Interface menolak untuk start. 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 tidak lagi dipelihara dan repositorinya telah diarsipkan. Menjalankan VPN dengan otomatisasi yang ditinggalkan menimbulkan masalah keamanan yang berkembang secara perlahan. Tidak ada pemutakhiran langsung di tempat, dan PKI OpenVPN tidak dapat dikonversi. WireGuard tidak menggunakan sertifikat, CA, atau masa berlaku. Karena itu, setiap klien harus mendapatkan pasangan kunci baru.

Lakukan migrasi secara paralel. WireGuard pada UDP 51820 dapat berjalan berdampingan dengan OpenVPN pada 1194 di server yang sama. Siapkan wg0, pindahkan klien satu per satu, lalu hentikan service lama. Model nama pengguna/password dan pencabutan akses OpenVPN tidak dapat dipindahkan. Jika Anda memerlukan akun atau jejak audit, tambahkan lapisan tersebut di atas WireGuard.

Backup, upgrade, dan hal-hal yang membebani pada skala besar

/etc/wireguard adalah server itu sendiri. Cadangkan (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 private key server hilang, setiap konfigurasi klien harus diterbitkan ulang karena klien menyematkan public key server. Upgrade cukup berupa apt upgrade biasa ditambah reboot untuk pembaruan kernel, dan wg-quick@wg0 akan aktif kembali secara otomatis jika Anda mengaktifkannya.

State per peer berukuran kecil dan kriptografi berjalan di kernel. Karena itu, batasnya ditentukan oleh CPU dan bandwidth VPS Anda, bukan oleh hal lain dalam konfigurasi ini. Ukur dengan iperf3 melalui tunnel, bukan dengan mengandalkan angka yang dipublikasikan. Hal yang membebani pada skala besar adalah operasional. Setiap peer memerlukan IP tunnel yang unik. Mengedit manual enam puluh blok [Peer] dapat menyebabkan AllowedIPs duplikat muncul. Buat konfigurasi dari script. Satu server berarti satu endpoint UDP dan satu titik kegagalan. WireGuard tidak memiliki clustering. Redundansi berarti server kedua dengan key-nya sendiri. Rotasi key tetap dilakukan secara manual. Karena itu, catat siapa yang memegang setiap key dan bagaimana cara mencabutnya. Jika pencatatan tersebut sudah tidak cukup ditangani oleh file teks, solusi yang umum adalah menggunakan control plane di atas data plane kernel yang sama. Server NetBird yang di-host sendiri menangani alokasi alamat, distribusi peer, dan setup key yang sebelumnya harus Anda lakukan secara manual. Jika menjalankan control plane sendiri berarti menambah satu server, Tailscale dapat mengelolanya untuk Anda. Paket gratisnya mencakup enam pengguna dengan perangkat tanpa batas, sehingga sebagian besar jaringan pribadi tidak perlu membayar. Setelah melewati batas tersebut, biaya ditentukan oleh jumlah pengguna, bukan jumlah mesin. Jadi, biaya yang sebenarnya dibayar rumah tangga atau tim kecil bergantung pada jumlah orang yang memiliki login, bukan jumlah peer yang harus Anda masukkan secara manual ke dalam wg0.conf. Pada sisi tersebut, pencatatan AllowedIPs untuk split tunnel berubah menjadi mengiklankan range privat dari subnet router, yang diumumkan satu kali dari satu VPS dan disetujui secara terpusat, bukan ditempelkan ke setiap file klien. Apakah perubahan tersebut layak dilakukan bergantung pada apa yang sebenarnya dapat dijangkau oleh control plane yang di-host. Control plane tersebut tidak pernah menyimpan key yang mengenkripsi trafik Anda, tetapi menentukan peer mana yang dapat saling mengetahui.

Semua ini memerlukan box Linux yang Anda kendalikan, IP publik, kernel yang dapat memuat module, dan firewall yang Anda kelola sepenuhnya.

FAQ

Mengapa handshake WireGuard tidak pernah selesai?

wg show yang menampilkan peer tanpa latest handshake berarti paket tidak tiba atau tidak diterima. Periksa UDP 51820 pada firewall VPS dan firewall jaringan terpisah milik provider, pastikan host dan port Endpoint benar, lalu periksa agar key tidak tertukar. Blok [Peer] pada client harus berisi public key server. sudo tcpdump -ni any udp port 51820 pada server menunjukkan apakah paket tiba sama sekali; dmesg hanya melaporkan kegagalan handshake WireGuard setelah Anda mengaktifkan debug dinamis (echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control), dan ketidakcocokan key akan muncul sebagai drop invalid-MAC.

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 nilainya ditetapkan dalam /etc/sysctl.d/, bukan hanya melalui sysctl -w yang hilang setelah reboot. Selanjutnya, periksa apakah rule masquerade menggunakan nama interface egress yang sebenarnya dari ip route show default, enp1s0, atau, lebih jarang, ens3 dan eth0.

Apakah saya memerlukan baris DNS = dalam konfigurasi client?

Dengan full tunnel dan tanpa baris DNS =, client tetap menggunakan resolver yang diperoleh dari jaringan lokal. Query tersebut dikirim dalam bentuk plaintext melalui link lokal, sedangkan trafik lainnya melewati 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 dikendalikan oleh AllowedIPs?

Parameter ini memiliki dua fungsi. Untuk trafik outbound, parameter ini merupakan tabel routing: trafik yang cocok dengan AllowedIPs milik suatu peer akan dienkripsi dan dikirim ke peer tersebut. Untuk trafik inbound, parameter ini merupakan access-control list: paket yang telah didekripsi dan sumbernya berada di luar AllowedIPs milik peer tersebut akan di-drop. Karena itu, sisi server mencantumkan /32 untuk setiap client, sedangkan sisi client dapat mencantumkan 0.0.0.0/0.

Apakah WireGuard dapat berjalan pada VPS apa pun?

Pada VPS KVM, WireGuard berjalan menggunakan modul kernel tanpa konfigurasi tambahan. Pada virtualisasi berbasis 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 lain.