Practical guide
How to Set Up a WireGuard VPN Server on Ubuntu with a Script
Start with a fresh Ubuntu server and finish with a personal VPN connection. This guide explains the server setup, device profiles and checks that show whether your internet traffic is using the tunnel.
Tested: server setup, Linux container connectivity and a Windows speed test. Native macOS, Ubuntu Desktop, iPhone and Android checks are still pending.
1. Choose a server and prepare access
This guide describes setting up WireGuard from scratch on an Ubuntu 26.04 LTS VPS. You will need its public IPv4 address and a root password or SSH key. Choose any provider and region that suit your needs.
For this guide, we use a Vultr Shared CPU VPS with 1 vCPU, 1 GB of RAM, 25 GB of SSD storage and a monthly transfer allowance of 1 TB.
Choose a server with IPv4 so you can connect from networks that do not support IPv6. An IPv6-only server needs additional arrangements to reach IPv4-only websites and is not covered here.
2. Check that you can log in over SSH
Windows: open Start, type PowerShell and open it. Mac: press Command+Space, type Terminal and press Enter. Ubuntu Desktop: press Ctrl+Alt+T.
In every command below, replace SERVER_IP with the public IPv4 address from your server control panel. For example, ssh root@SERVER_IP means connecting to your server as root.
Use the password command, or the key command if you already use an SSH key. Replace the example key path with your own.
On your first connection, SSH may ask whether to trust this server. Check that the address is the VPS you just created, type yes and press Enter. Enter the root password when asked; nothing appears on screen while you type it.
Once connected, run the server command below to check Ubuntu, then exit to return to your computer.
ssh root@SERVER_IPssh -i ~/.ssh/id_ed25519 root@SERVER_IPcat /etc/os-release
exitIf the ssh command is not found
On Windows, open a new PowerShell window using Run as administrator and run the command below. When installation finishes, close it and reopen ordinary PowerShell. On Ubuntu, use the Ubuntu command below. macOS includes an SSH client.
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0Copy the command exactly. OpenSSH.Client~~~~0.0.1.0 is the Windows component identifier; keep the tildes and numbers unchanged.
sudo apt update
sudo apt install openssh-client3. Download and inspect the setup bundle
Download the ZIP and extract it. Keep the five scripts together in the wireguard-guide folder. Choose the Windows, Mac or Ubuntu instructions below; you only need one of these paths.
The script installs WireGuard on your VPS and creates a connection profile for your device. You may be asked for the server password several times during setup.
4a. Set up the server from Windows
Open the extracted wireguard-guide folder in File Explorer. Click its address bar, type powershell and press Enter. This opens PowerShell in the right folder.
Run one of the two commands below. Replace SERVER_IP with your VPS address. If using an SSH key, also replace its path.
The word windows after -Device is the name of this device profile. For a second Windows computer, use another name, such as laptop. Each device needs its own profile so you can connect them independently and revoke one without disconnecting the others.
When setup finishes, open the WireGuard folder in your user home folder. You can reach it by entering %USERPROFILE%\WireGuard in the File Explorer address bar. Open the folder named after your server and device to find windows.conf. The script also prints the full path. You will activate the VPN in step 5.
.\Connect-WireGuardServer.ps1 -Server SERVER_IP -Device windows.\Connect-WireGuardServer.ps1 -Server SERVER_IP -Device windows -IdentityFile "$HOME\.ssh\id_ed25519"If PowerShell blocks the script
If the error says the downloaded file is not digitally signed, run this command in the same folder, then retry the setup command.
Unblock-File -LiteralPath .\Connect-WireGuardServer.ps1If the error says running scripts is disabled, run these commands and confirm the prompt, then retry setup. This change lasts only until you close this PowerShell window.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
Unblock-File -LiteralPath .\Connect-WireGuardServer.ps1If a policy error still prevents execution, stop and keep the error message for troubleshooting.
4b. Set up the server from a Mac
Open Terminal. Type cd followed by a space, drag the extracted wireguard-guide folder from Finder into Terminal, and press Enter.
Run one of the commands below, including bash at the beginning. Replace SERVER_IP with your VPS address and, if using a key, replace its path. The word mac names this device profile; use a different name, such as macbook, for another Mac.
When setup finishes, open Finder and press Command+Shift+H to open your home folder. Open WireGuard, then the folder named after your server and device. Your profile is mac.conf. The script also prints the full path.
bash ./connect-wireguard-server.sh SERVER_IP macbash ./connect-wireguard-server.sh SERVER_IP mac 22 ~/.ssh/id_ed255194c. Set up the server from Ubuntu Desktop
Press Ctrl+Alt+T to open Terminal. Type cd followed by a space, drag the extracted wireguard-guide folder into the terminal and press Enter.
Run one of the commands below, replacing SERVER_IP with your VPS address. The word ubuntu names this device profile. You do not need sudo for this launcher or for SSH login.
When setup finishes, open your Home folder in the file manager, then WireGuard and the folder named after your server and device. Your profile is ubuntu.conf, saved at ~/WireGuard/SERVER_IP-ubuntu/ubuntu.conf using your actual server address. This guide uses NetworkManager to connect Ubuntu Desktop.
bash ./connect-wireguard-server.sh SERVER_IP ubuntubash ./connect-wireguard-server.sh SERVER_IP ubuntu 22 ~/.ssh/id_ed255195a. Connect Windows or macOS
Install the official WireGuard application for your operating system. Import the .conf file created by the launcher, approve the operating system's VPN permission and activate the tunnel. The exact import wording can vary between app versions.
The profile sends IPv4 traffic into the tunnel and includes an IPv6 default route so that IPv6 should not bypass this IPv4-only setup. The server does not provide IPv6 internet access. Verify the actual behavior on your device using the checks below.
An imported profile contains a private key. Anyone with a copy can attempt to use that device's VPN identity. Do not paste it into support tickets, upload it to online QR generators or share it between devices.
5b. Connect Ubuntu Desktop with NetworkManager
Use NetworkManager to import the profile and manage DNS and routing together. This avoids depending on a particular version of the graphical VPN import dialog. Run the commands below on your desktop, not over SSH on the VPS. Confirm that nmcli is available and NetworkManager is running before importing.
Use a profile named ubuntu.conf so the imported connection is named ubuntu. If that connection name already exists, choose a different device name and adjust the commands. Import only once; for later connections use the up and down commands. Disable automatic connection so this guide does not silently reconnect the VPN every time the desktop starts.
The DNS settings below prefer this connection for all DNS names while it is active. Browsers using their own secure DNS can behave differently. Complete the public-IP, DNS and IPv6 checks in step 7. This NetworkManager route has not yet passed a native Ubuntu Desktop test; the earlier Linux container result does not validate desktop DNS or IPv6 behavior.
Do not also activate the same profile with wg-quick: two managers configuring the same tunnel can create conflicting routes. You can inspect and disconnect the imported connection with nmcli even if the desktop interface presents it differently.
nmcli --version
systemctl is-active NetworkManagersudo nmcli connection import type wireguard file "$HOME/WireGuard/SERVER_IP-ubuntu/ubuntu.conf"
sudo nmcli connection modify ubuntu connection.autoconnect no ipv4.dns-priority -50 ipv4.dns-search "~."sudo nmcli connection up ubuntu
nmcli connection show --activesudo nmcli connection down ubuntu6. Connect iPhone or Android with a QR code
Install the official WireGuard app using the App Store or Google Play link below.
On your computer, connect to the VPS again using ssh root@SERVER_IP (or your SSH-key command). Run the command below for your phone. It creates a profile and displays its QR code.
In the WireGuard phone app, choose the option to add a tunnel by scanning a QR code. Scan the code on your computer, name the connection and approve the VPN permission. Then switch the connection on.
Use a separate profile for each phone. Do not share the QR code: it gives access to your VPN. If it appears broken across lines, enlarge the terminal window and display it again.
python3 /root/internetspeed-wireguard/manage-client.py add iphone
qrencode -t ANSIUTF8 < /etc/wireguard/clients/iphone.confpython3 /root/internetspeed-wireguard/manage-client.py add android
qrencode -t ANSIUTF8 < /etc/wireguard/clients/android.conf7. Check that internet traffic uses your VPN
Open our My IP page using the link below before switching on the VPN and note your IP address. Turn on WireGuard, refresh My IP and compare the result with the public IPv4 of your VPS.
If the page loads and shows your VPS address, that browser connection is using the VPN. If the old address remains, use the troubleshooting section below.
This confirms the browser connection, not every application or protection during a VPN interruption. The optional checks below cover DNS and IPv6.
Optional: check IPv6 and DNS
IPv6: open Test IPv6 before connecting and note whether it reports an IPv6 address. Connect the VPN and run the test again. This IPv4-only setup should have no working IPv6 internet connection. If your usual IPv6 address still appears, IPv6 is bypassing the tunnel. If IPv6 was unavailable before connecting, this test cannot show how the VPN will behave on an IPv6-enabled network.
DNS: with the VPN active, open DNS Leak Test and run its Standard test. This profile uses Cloudflare DNS. If results show your home internet provider, check the device DNS setup. Another provider can also come from the browser Secure DNS setting, so it is a reason to investigate rather than automatic proof of a leak. Neither result alone certifies that every application is protected.
8. Troubleshoot a connection that does not work
If My IP still shows your normal address: open WireGuard and check that your imported connection is switched on. Switch it off and on once, then refresh My IP.
If websites stop opening when you turn on the VPN: turn it off and try opening the same page. If the page also fails with the VPN off, first restore your ordinary internet connection. If it works with the VPN off, use the checks below.
If you want to check whether your current Wi-Fi connection is the cause, connect the same computer to your phone hotspot and try the VPN again. On a phone, switch off Wi-Fi and try mobile data. This is a temporary comparison, not a suggestion to change internet providers. Mobile data charges may apply. If the VPN works through the hotspot or mobile data but not through Wi-Fi, the problem is specific to that connection; this alone does not identify the cause.
If setup stopped with an error: keep the last error message. After correcting that problem, rerun the same setup command with the same device name. The script preserves the existing profile.
Check whether the VPN server is running
Connect to the VPS over SSH as in step 2, then run the command below. The expected result is active. If it says inactive or failed, run the restart command and check again. If it still does not say active, keep the error message for troubleshooting.
systemctl is-active wg-quick@wg0systemctl restart wg-quick@wg0
systemctl is-active wg-quick@wg0Restarting briefly disconnects any devices using this VPN.
Check whether your device reaches the server
Turn on the VPN on your device and try opening My IP. On the server, run wg show below. Under the device entry, look for latest handshake. A value such as 10 seconds ago means the device and server recently established an encrypted connection. If that line is missing, a successful connection has not yet been recorded for that device.
If no recent connection appears after you try opening a page, open the profile in WireGuard and check that Endpoint contains your VPS address followed by :51820. Then open the VPS control panel and look for Firewall or Security groups. If firewall rules are attached to this VPS, they need to allow incoming UDP on port 51820. The exact screen depends on your provider. The setup script already configures the firewall inside Ubuntu.
If a recent handshake appears but websites still do not open, record that result and the application error or log. This narrows the problem to investigate; changing advanced network settings at random can make diagnosis harder.
wg show9. What speed can you expect?
In our Windows test, WireGuard delivered approximately 350–400 Mbps download and 450–500 Mbps upload. Testing followed the same method used for the other VPNs in this project. The test path was: user in San Diego → VPN server in the San Francisco Bay Area → measurement server in Seattle.
The VPN ran on a Vultr Shared CPU vc2-1c-1gb VPS: 1 vCPU, 1 GB RAM, 25 GB SSD and 1 TB of monthly traffic, at $5 per month when provisioned.
These are the speeds observed with this setup. Your results will depend on your internet connection, server and location. We have not yet compared other VPS plans or providers.
10. Understand costs, privacy and provider limits
A self-hosted VPN gives you control of the server configuration and one chosen exit location. It also makes you responsible for security updates, account billing, device access and recovery. It does not make your activity anonymous to your hosting provider or remove the need for HTTPS.
Using the VPN consumes your VPS traffic allowance: browsing, watching videos, downloading and uploading files, and running speed tests all use traffic. Check the remaining allowance in your hosting control panel. Exceeding it may lead to extra charges or restrictions, depending on the plan.
Review the provider's current acceptable-use terms and applicable law before using peer-to-peer software. The protocol and the rights to the content are separate questions. Use content you are entitled to download and share; do not assume every host permits every P2P use.
A data-center IP can encounter CAPTCHAs, service restrictions or streaming blocks. Plain WireGuard does not promise access from every filtered network. One VPS also gives you a single failure point rather than a large provider's pool of locations and replacement servers.
11. Add devices, revoke access and maintain the server
Use one profile per device. To revoke a lost phone, remove its named peer on the server and delete any exported copies you still have. To replace it, create a new profile after revocation. Deleting a file on the phone alone does not revoke the server's peer.
Keep Ubuntu security updates current and check whether a reboot is required. Reboot at a convenient time and confirm that the VPN returns. Protect the provider account and SSH access; changing SSH authentication should be a separate step with a tested alternative login.
The removal script below stops this guide's VPN and removes its managed configuration and firewall rules. It leaves SSH access, UFW and installed packages in place. The runtime forwarding setting remains enabled until the operating system's policy is applied at reboot. Removing WireGuard does not cancel your VPS bill; delete the instance through your provider when you no longer need it, after preserving anything required.
python3 /root/internetspeed-wireguard/manage-client.py remove iphoneapt update
apt list --upgradable
test ! -f /var/run/reboot-required || cat /var/run/reboot-requiredbash /root/internetspeed-wireguard/remove-server.sh --confirm