The simplest way to make a personal VPN is to install WireGuard on an Ubuntu server with a public IP address, generate encryption keys, configure one client, and route traffic through the server. WireGuard is a VPN protocol built around encrypted tunnels, public-key authentication and simple peer configuration.
This guide creates a full-tunnel VPN. Your device sends IPv4 internet traffic through your own server.
What You Need
| Requirement | Example |
|---|---|
| VPN server | Ubuntu 22.04 or 24.04 VPS |
| VPN software | WireGuard |
| Server address | Public IPv4 address |
| VPN tunnel network | 10.8.0.0/24 |
| VPN port | UDP 51820 |
| Client device | Windows, macOS, Linux, Android or iPhone |
WireGuard provides installation options for Ubuntu, Windows, macOS, Android and iOS. On Ubuntu, install the server package with sudo apt install wireguard.
Step 1: Install WireGuard on the VPN Server
Connect to your Ubuntu server over SSH, then install WireGuard and iptables:
sudo apt update
sudo apt install wireguard iptables
Enable IPv4 forwarding so the server can pass traffic from the VPN tunnel to the internet:
sudo tee /etc/sysctl.d/99-wireguard-forward.conf > /dev/null <<'EOF'
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
Find the server's public network interface:
ip route show default
The output should look similar to this:
default via 203.0.113.1 dev eth0
In this example, the interface is eth0. Your server may use a name such as ens3 or enp1s0. Use the name shown on your server in the WireGuard configuration.
Step 2: Generate Server and Client Keys
WireGuard uses a private key and a matching public key for each peer. Keep every private key secret. WireGuard's quick-start documentation uses wg genkey and wg pubkey to create the keys.
Create the protected configuration directory:
sudo install -m 700 -d /etc/wireguard
Generate the server and client keys:
sudo sh -c 'umask 077
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
wg genkey | tee /etc/wireguard/client_private.key | wg pubkey > /etc/wireguard/client_public.key'
Display the keys when you need to copy them into the configuration:
sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key
sudo cat /etc/wireguard/client_private.key
sudo cat /etc/wireguard/client_public.key
Do not publish or share server_private.key or client_private.key.
Step 3: Create the WireGuard Server Configuration
Create the server configuration file:
sudo nano /etc/wireguard/wg0.conf
Add this configuration. Replace the key placeholders with the matching keys from Step 2. Replace eth0 if your public interface has a different name.
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
Address is the server's address inside the VPN tunnel. AllowedIPs assigns the client the tunnel address 10.8.0.2.
WireGuard uses AllowedIPs for routing and peer address assignment, so each client should normally have its own tunnel address.
Secure the file:
sudo chmod 600 /etc/wireguard/wg0.conf
Step 4: Allow the VPN Port Through the Firewall
Allow inbound UDP traffic on port 51820.
If you use UFW, run:
sudo ufw allow OpenSSH
sudo ufw allow 51820/udp
sudo ufw enable
If your hosting provider has a separate cloud firewall, add this inbound rule:
Protocol: UDP
Port: 51820
Source: 0.0.0.0/0
You can restrict the source IP if the client has a fixed public IP address. Home and mobile connections often change public IP addresses, so many clients need access from any source address.
Step 5: Start the VPN Server
Start WireGuard and configure it to start when the server boots:
sudo systemctl enable --now wg-quick@wg0
Check the interface and peer configuration:
sudo wg show
You should see the wg0 interface and the configured client public key. The wg and wg-quick tools let you inspect and manage WireGuard interfaces.
Step 6: Create the Client Configuration
Create a file named client.conf on your computer:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.8.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
Replace these values:
CLIENT_PRIVATE_KEYwith the contents ofclient_private.keySERVER_PUBLIC_KEYwith the contents ofserver_public.keySERVER_PUBLIC_IPwith the VPS public IPv4 address
AllowedIPs = 0.0.0.0/0 sends all IPv4 traffic through the VPN server. To route only selected private networks, replace it with the required network range.
PersistentKeepalive = 25 can help when the client is behind NAT or a restrictive firewall. It periodically keeps the connection mapping open. WireGuard identifies 25 seconds as a sensible general-purpose interval for this situation.
Treat client.conf as a secret because it contains the client's private key.
Step 7: Connect Your Device
Import client.conf into the WireGuard application:
- Windows: Install WireGuard, then choose Import tunnel(s) from file
- macOS: Install WireGuard and import the configuration
- Android or iPhone: Install WireGuard and import the file or scan a QR code
- Linux: Save the file as
/etc/wireguard/wg0.conf, then run:
sudo wg-quick up wg0
To start the Linux client automatically:
sudo systemctl enable wg-quick@wg0
Step 8: Test the VPN Connection
On the client, test the server's tunnel address:
ping 10.8.0.1
On the server, check the latest handshake:
sudo wg show
A recent handshake shows that the client and server have exchanged encrypted traffic.
Then check the public IP address from the client:
curl```
The result should show the VPN server's public IP address instead of the public IP address of the home or mobile connection.
## How to Add More Devices
Create a separate key pair and tunnel address for every device.
| Device | VPN address |
|---|---:|
| Laptop | `10.8.0.2` |
| Phone | `10.8.0.3` |
| Tablet | `10.8.0.4` |
Add another peer to `/etc/wireguard/wg0.conf`:
```ini
[Peer]
PublicKey = SECOND_CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.3/32
Restart WireGuard:
sudo systemctl restart wg-quick@wg0
Do not reuse one private key across multiple devices. A separate peer lets you remove one device without changing the others.
Full-Tunnel VPN Versus Private-Network VPN
A full-tunnel VPN routes all IPv4 internet traffic through the server:
AllowedIPs = 0.0.0.0/0
Use this when you want to protect traffic on public Wi-Fi or make websites see the VPN server's public IP address.
A private-network VPN routes traffic only to a specific network:
AllowedIPs = 10.10.10.0/24
Use this when the peer can reach a home network, NAS, security camera or private server and you do not want ordinary internet traffic to use the VPN.
WireGuard supports peer-to-site connections, such as remote access to a home network, and site-to-site connections between separate networks.
Important Security Limitations
A self-hosted VPN does not make you completely anonymous.
- Your VPS provider can still observe activity associated with your server.
- Websites will see the VPS IP address.
- HTTPS protects web content between your device and the website, but the VPN server remains the traffic exit point.
- A VPN does not protect an infected client device or information that you provide to a website.
- The VPN network is bidirectional. Devices on the remote network may be able to connect back to your client unless firewall rules restrict access. Ubuntu recommends using firewall rules to control traffic on the VPN interface.
- Never share a WireGuard private key. Ubuntu warns that configuration files often contain private keys and should be cleaned before they are posted or stored publicly.
You can add an optional preshared key for another layer of symmetric-key protection between peers:
sudo wg genpsk
Add the same preshared key to the matching peer configuration on both sides.
If You Want to Make a VPN at Home
Instead of renting a VPS, install WireGuard on one of these devices:
- A compatible home router
- A Raspberry Pi
- A small Linux computer
- A home server
You will normally need to:
- Give the WireGuard device a fixed local IP address.
- Forward UDP port
51820from the router to the WireGuard device. - Use dynamic DNS if the home public IP address changes.
- Create a client configuration that uses the home connection's public hostname.
- Restrict access with firewall rules.
A home VPN is useful for accessing local devices while travelling. A VPS VPN is more practical when you want traffic to exit from a separate public IP address.
Final Recommendation
For most people, use WireGuard on an Ubuntu VPS instead of attempting to build a VPN protocol from scratch. WireGuard provides the encrypted tunnel and peer authentication. Ubuntu provides documented configurations for peer-to-site and full-tunnel deployments.
Your main responsibilities are protecting private keys, updating the server, configuring firewall rules and checking the VPN connection.