Paano mag-setup ng WireGuard VPN sa VPS
Matutong mag-configure ng WireGuard sa Linux VPS. Alamin ang tamang setup para sa wg0.conf, IP forwarding, NAT, at iwasan ang mga common handshake failures.
Ang iyong bubuuin
Ang WireGuard VPN sa sarili mong server ay binubuo lamang ng humigit-kumulang apatnapung linya ng config: isang key pair, isang interface file, isang sysctl, isang NAT rule, at isang firewall hole. Madali lang ang installation, kaya ang karamihan sa guide na ito ay nakatuon sa mga posibleng error — key permissions, AllowedIPs, forwarding, at DNS.
Ang WireGuard ay isang Layer 3 tunnel sa kernel. Kasama na ito sa mainline kernel simula Linux 5.6, kaya ang Ubuntu 24.04 at Debian 13 ay may built-in na support nito nang walang external module. Walang cipher negotiation, walang certificate authority, at walang username/password step: ang isang peer ay binubuo ng public key at ang mga IP address na maaaring gamitin ng key na iyon. Ang mga packet na hindi papasa sa MAC check ay ididrop nang walang reply, kaya hindi sasagot ang port sa mga scan. Ang downside nito: walang auth server, kaya para tanggalin ang access, kailangang i-delete ang peer sa mismong machine.
I-check muna ang virtualisation
Kailangan ng WireGuard ng kernel na pwedeng i-load ang module, at sa KVM VPS ay gumagana ito agad. Sa container virtualisation na gumagamit ng host kernel — gaya ng OpenVZ at LXC — mag-eerror ang unang command gamit ang RTNETLINK answers: Operation not supported. Ang fallback nito ay ang wireguard-go userspace implementation. I-check muna gamit ang sudo modprobe wireguard && echo ok.
Mag-generate ng mga key nang hindi nalalantad ang mga ito
Ang isang /etc/wireguard/server.key na world-readable ay katumbas ng walang VPN. Hindi maaasahan ang karaniwang umask 077 && wg genkey | sudo tee ... line dahil naglalapat ang sudo ng sarili nitong umask sa file na ginagawa ng tee. I-set ang mode nang explicit.
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.keyI-generate ang client pair sa parehong paraan. Nagdadagdag ang wg genpsk ng optional na pre-shared key, isang linya sa bawat config.
Ang server interface: /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 it; ang startup warning na ang file ay world accessible ay nangangahulugang nalaktawan mo ito. Ang Address ay ang address ng server sa loob ng tunnel, na sumasakop sa buong mask ng VPN subnet. Pumili ng range na hindi mo gagamitin sa ibang network — ang 192.168.1.0/24 ay nagkakabanggaan sa kalahati ng mga home router na pinagkakabentahan ng iyong mga client, at ang tunnel ay mawawala nang tahimik dahil sa local route.
Ang AllowedIPs ng isang peer sa server side ay isang /32, ang tanging tunnel address na pagmamay-ari ng client. Kung bibigyan ang dalawang peer ng parehong allowed IP, lilipat ito sa kung alin ang huling na-configure, at ang una ay hihinto sa pagtanggap ng traffic nang walang error na lumalabas kahit saan. Iwanang unset ang SaveConfig, o muling isusulat ng wg-quick down ang file na ito mula sa live state.
Gawing router ang box
Hindi tinatanggap ng Linux server ang mga packet na hindi para sa kanya. Hindi naka-enable ang forwarding at source NAT sa default settings.
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_forwardAng isang bare sysctl -w ay gagana lamang hanggang sa susunod na reboot at pagkatapos ay hihinto na sa paggana. Kailangan ng NAT ang egress interface — ang NIC na may access sa internet, hindi ang wg0. Huwag i-assume ang eth0; kunin ang sa iyo mula sa ip route show default, dahil ang mga current image ay gumagamit ng mga pangalan gaya ng enp1s0 o ens3.
Firewall: ang port, at ang forward path
Isang nftables file ang sumasaklaw sa filter at NAT. Isulat ang /etc/nftables.conf — inaalis nito ang kasalukuyang ruleset, kaya huwag itong gawin sa server na pinamamahalaan na ng ufw o 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
}
}I-apply ito gamit ang sudo systemctl enable --now nftables, habang may nakabukas na pangalawang SSH session: ang policy drop na may typo sa SSH rule ay magreresulta sa pagka-lockout sa sarili mong server. Pansinin ang mga hindi pinahihintulutan ng forward chain — wg0 hanggang wg0. Makakaabot ang mga peer sa internet, pero hindi sa isa't isa; magdagdag ng iifname "wg0" oifname "wg0" accept para sa isang peer-to-peer VPN. Ang parehong chain ang nagdidikta kung ano ang maaaring maabot ng isang peer sa mismong server, na mahalaga kapag ang server ay ginagamit din bilang remote development box na tumatakbo ang Claude Code sa tmux at ayaw mong i-expose ang bahaging iyon sa publiko.
Sa ufw box: ufw allow 51820/udp, DEFAULT_FORWARD_POLICY="ACCEPT" sa /etc/default/ufw, at isang *nat POSTROUTING MASQUERADE rule sa itaas ng /etc/ufw/before.rules.
I-setup ito gamit ang systemd
sudo systemctl enable --now wg-quick@wg0
sudo wg showGumagawa ang wg-quick ng interface, nagdadagdag ng mga address, at nag-iinstall ng mga route mula sa AllowedIPs. Ang enable --now ang mahalagang bahagi: mawawala ang manual na wg-quick up wg0 pagkatapos ng susunod na reboot, at nangangailangan ng reboot ang mga kernel upgrade.
Ang client config, at ang setting na madalas malito ang lahat
[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 = 25Ang AllowedIPs ay may dalawang magkaibang tungkulin, at ang pagpapalit sa mga ito ang sanhi ng karamihan sa WireGuard confusion.
Sa outbound, ito ay isang routing table. Ang packet na ang destination ay tugma sa AllowedIPs ng isang peer ay i-e-encrypt at ipapadala sa peer na iyon. Ang 0.0.0.0/0, ::/0 ay nagpapadala ng lahat ng traffic sa tunnel — isang full tunnel, kung saan ang server ang default route. Ang split tunnel ay isang mas maikling listahan: ang AllowedIPs = 10.8.0.0/24, 10.20.0.0/16 ay nagdadala ng VPN traffic plus isang private network sa likod ng server, habang ang lahat ng iba pa ay mananatili sa local route nito. Ang maikling listahang ito ang nagbibigay-daan upang manatiling off ang mga services sa public internet — ang isang private Nextcloud instance sa isang VPS na naka-bind sa tunnel address, o ang mga nested-virtualisation lab VMs na tumatakbo sa parehong machine, ay mananatiling reachable sa mga peer at invisible sa lahat ng iba pa.
Sa inbound, ito ay isang access-control list. Ang isang decrypted packet mula sa isang peer na ang source address ay wala sa AllowedIPs ng peer na iyon ay i-da-drop. Ito ang dahilan kung bakit nakalista ang 10.8.0.2/32 para sa laptop: ang entry na 0.0.0.0/0 doon ay magbibigay-daan sa client na iyon na i-spoof ang anumang address sa tunnel.
Ang PersistentKeepalive ay para sa mga client na nasa likod ng NAT, kung saan ang router ay nagpapanatili lamang na bukas ang UDP mapping habang may dumadaloy na mga packet. Kapag nag-expire ito, hindi na maabot ng server ang client. Ang PersistentKeepalive = 25 ang nagpapanatili na bukas ang mapping — i-set ito sa client, hindi sa server na may public IP.
DNS, at ang leak na hindi napapansin ng marami
Kapag may AllowedIPs = 0.0.0.0/0 at walang DNS = line, gagamitin ng client ang resolver na nakuha mula sa local network — ang café router sa 192.168.1.1. Mas specific ang route na ito kaysa sa default route, kaya ang mga DNS query ay lumalabas sa local link nang cleartext habang ang lahat ng iba pang traffic ay naka-tunnel. Private ang traffic; hindi private ang listahan ng mga pangalan.
May dalawang tamang opsyon. Ituro ang DNS sa isang public resolver (DNS = 9.9.9.9) para ang mga query ay dadaan sa tunnel at lalabas sa iyong server, bagaman makikita pa rin ito ng resolver na iyon. O kaya ay mag-run ng unbound o dnsmasq na naka-bind sa 10.8.0.1, i-set ang DNS = 10.8.0.1, at magdagdag ng udp dport 53 iifname "wg0" accept sa input chain — kapag na-set ang linyang iyon at hindi na gumamit ng resolver, wala nang mag-re-resolve.
Sa mga Linux client, inia-apply ng wg-quick ang DNS sa pamamagitan ng resolvconf; kung wala ito, makukuha mo ang resolvconf: command not found. I-install ang openresolv, o i-set ang PostUp = resolvectl dns %i 10.8.0.1 sa isang systemd-resolved client.
Pagdaragdag at pagtanggal ng mga peer nang hindi pinuputol ang tunnel
Ang pag-restart ng interface para magdagdag ng user ay magpapatigil sa lahat ng konektado. I-append ang [Peer] block sa wg0.conf, pagkatapos ay i-reload ang peer set sa mismong lokasyon nito.
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'Ipi-print ng wg-quick strip ang config nang walang mga wg-quick-only key (Address, DNS, PostUp), at ilalapat ng syncconf ang pagbabago habang nananatiling active ang mga live session. Ang mga peer lamang ang ina-update nito: ang binagong Address ay nangangailangan pa rin ng full down/up. I-revoke gamit ang sudo wg set wg0 peer <public key> remove, pagkatapos ay burahin ang block mula sa file o babalik ito sa susunod na reload.
Failure modes, kasama ang mga string na makikita mo
Hindi natatapos ang handshake. Ipinapakita ng wg show ang peer na walang latest handshake, at ang client logs ay:
Handshake for peer 1 (10.0.0.10:51820) did not complete after 5 seconds, retrying (try 2)Walang dumating na data, o walang tinatanggap na data. Suriin ang mga ito: bukas ba ang UDP 51820 sa VPS firewall at sa network firewall ng provider mo (isang hiwalay na control sa karamihan ng panels); tama ba ang Endpoint address at port; tama ba ang pagkaka-cross ng mga keys. Ang key sa [Peer] block ng client ay dapat ang public key ng server, at vice versa — ang pag-paste ng private key, o ng sariling public key ng client, ay nagdudulot ng ganitong sintomas. Ipinapakita ng sudo tcpdump -ni any udp port 51820 sa server kung may dumadating na packets. Walang log ang kernel module by default; lalabas lamang ang WireGuard messages sa dmesg kapag naka-enable ang dynamic debug (echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control), at kapag naka-on ito, ang key mismatch ay lalabas bilang invalid-MAC drop.
Gumagana ang handshake, pero walang internet. Nagtagumpay ang ping 10.8.0.1 pero nag-timeout ang ping 1.1.1.1: kulang ang forwarding o NAT. Suriin kung nagbabasa ang sysctl net.ipv4.ip_forward ng 1, pagkatapos ay bantayan ang mga counter habang nagpi-ping ang client gamit ang sudo nft list ruleset o sudo iptables -t nat -L POSTROUTING -n -v. Ang zero packets sa masquerade rule ay nangangahulugang mali ang egress interface name nito; ang tumataas na counter na walang replies ay indikasyon ng forward chain policy.
Gumagana ang internet, pero hindi gumagana ang mga domain name. Nagtagumpay ang ping 1.1.1.1 at nagbalik ang curl https://example.com ng Could not resolve host. Ang DNS line ay kulang, o kaya ay ang nakalagay na resolver ay hindi ma-reach mula sa loob ng tunnel.
Nag-ha-hang ang ilang HTTPS sites. Maayos ang SSH at ping; humihinto naman ang malalaking pages. Ito ay dahil sa path MTU: nagdadagdag ng overhead ang tunnel, at may link sa gitna na nagda-drop ng oversized packets nang walang bumabalik na ICMP message. Babaan ang MTU sa client [Interface] — subukan ang 1420, pagkatapos ay 1380, tapos 1280.
Ayaw mag-start ng interface. Ang Address already in use ay nangangahulugang may ibang process na gumagamit ng UDP 51820. Ang Cannot find device wg0 pagkatapos ng failed na up ay karaniwang nangangahulugang rejected ang config; basahin ang journalctl -u wg-quick@wg0 -n 50.
Pag-migrate mula sa Streisand o OpenVPN
Hindi na maintained ang Streisand at archived na ang repository nito. Ang pagtakbo ng VPN gamit ang abandonadong automation ay nagdudulot ng security problem sa katagalan. Walang in-place upgrade, at hindi pwedeng i-convert ang PKI ng OpenVPN: walang certificates, CA, o expiry ang WireGuard, kaya bawat client ay makakakuha ng bagong key pair.
Mag-migrate nang parallel — maaaring sabay ang WireGuard sa UDP 51820 at ang OpenVPN sa 1194 sa iisang box. I-setup ang wg0, i-move ang mga client nang paisa-isa, at pagkatapos ay i-stop ang lumang service. Hindi kasama sa migration ang username/password at revocation model ng OpenVPN; kung kailangan mo ng accounts o audit trail, i-layer ito sa ibabaw ng WireGuard.
Backups, upgrades, and what strains at scale
Ang /etc/wireguard ang mismong server. I-back up ito (gamit ang sudo tar czf wg-backup.tgz -C /etc wireguard, mode 600, at ilagay sa labas ng machine) para mabilis na makapag-rebuild sa isang bagong VPS sa loob ng ilang minuto. Kapag nawala ang private key ng server, kailangang mag-reissue ng lahat ng client config dahil naka-pin ang mga client sa public key ng server. Ang mga upgrade ay karaniwang apt upgrade lang at kailangan ng reboot para sa kernel updates; ang wg-quick@wg0 ay kusang babalik kung naka-enable ito.
Maliit lang ang per-peer state at tumatakbo ang crypto sa kernel. Dahil dito, ang limitasyon ay ang CPU at bandwidth allowance ng iyong VPS sa halip na ang configuration — sukatin ito gamit ang iperf3 sa loob ng tunnel sa halip na magtiwala sa mga nakatalang figure. Ang nagiging problema sa scale ay ang operations. Ang bawat peer ay nangangailangan ng unique na tunnel IP. Ang manual na pag-edit ng animnapung [Peer] blocks ay nagiging sanhi ng mga duplicate na AllowedIPs: gumamit ng script para i-generate ang mga config. Ang isang server ay iisang UDP endpoint at iisang point of failure. Walang clustering ang WireGuard: ang redundancy ay nangangailangan ng pangalawang server na may sariling mga key. Manual ang key rotation, kaya itala kung sino ang may hawak ng bawat key at kung paano i-revoke ang mga ito.
Ang lahat ng ito ay nangangailangan ng Linux box na kontrolado mo — public IP, kernel na pwedeng i-load-an ng module, at firewall na kontrolado mo nang buo.
FAQ
Bakit hindi natatapos ang WireGuard handshake?
Ang wg show na naglilista ng peer na walang latest handshake ay nangangahulugang hindi dumating o hindi tinatanggap ang mga packet. I-check ang UDP 51820 sa VPS firewall at sa hiwalay na network firewall ng iyong provider. Siguraduhin ang Endpoint host at port, at i-verify na hindi nagkapalit ang mga keys — dapat ang server's public key ang nasa [Peer] block ng client. Ang sudo tcpdump -ni any udp port 51820 sa server ay nagpapakita kung may dumating na packets; ang dmesg ay nag-uulat lamang ng WireGuard handshake failures kapag naka-enable ang dynamic debug (echo module wireguard +p | sudo tee /sys/kernel/debug/dynamic_debug/control), at lalabas ang key mismatch bilang invalid-MAC drop.
Connected ang tunnel pero walang internet. Ano ang kulang?
Ang ping 10.8.0.1 na gumagana habang ang ping 1.1.1.1 ay nagti-timeout ay indikasyon ng problema sa forwarding o NAT. Siguraduhin na ang sysctl net.ipv4.ip_forward ay nagbabasa ng 1 at naka-set ito sa /etc/sysctl.d/, hindi lang sa isang sysctl -w na nawawala pagkatapos ng reboot. Pagkatapos, i-check ang masquerade rule; tukuyin ang iyong real egress interface mula sa ip route show default — enp1s0 o ens3, at bihira ang eth0.
Kailangan ko ba ang DNS = line sa client config ko?
Sa isang full tunnel na walang DNS = line, gagamitin ng client ang resolver na nakuha mula sa local network. Ang mga query na ito ay lalabas bilang cleartext sa local link habang ang lahat ng iba pang traffic ay naka-tunnel. Ituro ang DNS sa isang public resolver, o magpatakbo ng unbound/dnsmasq na naka-bind sa 10.8.0.1 at i-open ang udp dport 53 iifname "wg0" sa input chain.
Ano ang kontrolado ng AllowedIPs?
May dalawa itong tungkulin. Sa outbound, ito ay isang routing table: ang traffic na tumutugma sa AllowedIPs ng isang peer ay i-e-encrypt at ipapadala sa peer na iyon. Sa inbound, ito ay isang access-control list: ang isang decrypted packet na ang source ay nasa labas ng AllowedIPs ng peer na iyon ay i-da-drop. Ito ang dahilan kung bakit ang server side ay naglilista ng /32 bawat client habang ang client side ay maaaring maglista ng 0.0.0.0/0.
Gagana ba ang WireGuard sa kahit anong VPS?
Sa isang KVM VPS, gagana ito gamit ang in-kernel module nang walang extra setup. Sa container virtualisation na gumagamit ng host kernel, gaya ng OpenVZ o LXC, mabibigo ang modprobe wireguard dahil sa Operation not supported at ang fallback ay ang wireguard-go userspace implementation. Patakbuhin ang sudo modprobe wireguard && echo ok bago ang anuman.