summary: "This article will guide you to setting up your own WireGuard VPN server using Ubuntu 22.04 server on a cheap ~$6 VPS and use it as your internet gateway."
After [series of my IPsec VPN article](https://insights.ditatompel.com/en/series/ipsec-vpn/). Today, I want to share how to set up [**WireGuard VPN**](https://www.wireguard.com/) server. Because **WireGuard** use **UDP** instead of **TCP**, it's _extremely fast_ compared to [L2TP/xAuth]({{< ref "/tutorials/ipsec-l2tp-xauth-ikev2-vpn-server-auto-setup/index.md" >}}) and [IKEv2 VPN]({{< ref "/tutorials/set-up-ikev2-vpn-server-and-clients/index.md" >}}) (my previous **IPsec VPN** articles).
- Basic knowledge of _**IPv4** subnetting_ (_to be honest, I'm not familiar with IPv6 subnetting, so this article is for **IPv4** only_).
It doesn't matter which _cloud provider_ you choose. In this article, I will use [**DigitalOcean**](https://m.do.co/c/42d4ba96cc94) (_referral link_) **Droplet** for my **WireGuard VPN server** (You can get your **free $200** in credit over 60 days by registering using my _referral code_).
> _**NOTE**: You should know that **cloud providers usually charge extra amount of `$` for every GB of overuse bandwidth**. So, know your needs and your limits!_
> _VPS server I use for this article will be destroyed when this article is published._
## Deploying your new VPS (DigitalOcean Droplet, optional)
> _If you already have your own VPS running, you can skip this step and go to next step: "[Set up your WireGuard Server](#set-up-your-wireguard-server)"._
> _If you want to manage **WireGuard** peers (client) on a single server easily, you might be interested to read "[Installing WireGuard-UI to Manage Your WireGuard VPN Server]({{< ref "/tutorials/installing-wireguard-ui-to-manage-your-wireguard-vpn-server/index.md" >}})"._
Install WireGuard using `sudo apt install wireguard` command. Once WireGuard is installed, we need to generate private and public key pairs for our WireGuard server.
> _Tips: You can create **vanity** public key address for **WireGuard** using tool like [warner/wireguard-vanity-address](https://github.com/warner/wireguard-vanity-address)._
Before configuring your **WireGuard** server, you need to **decide your private network IP range for your WireGuard** connection (_tunnel_ interface). You should choose valid [private network IP ranges](https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses). For example:
- Between `10.0.0.0` - `10.255.255.255` (`10.0.0.0/8`)
- Between `172.16.0.0` - `172.31.255.255` (`172.16.0.0/12`)
- Between `192.168.0.0` - `192.168.255.255` (`192.168.0.0/16`)
> _Tips: Avoid using your current used private IP ranges and commonly used private IP range. For example: Docker uses `172.17.0.0/16` IP range by default. If you use Docker, you must use another IP range for your WireGuard IP range to avoid conflict._
You'll also need to decide which **UDP** port WireGuard should listen to. Many _network appliance_ out there (such as **Netgate**, **QNAP**, etc.) set **UDP** port **51280** as their default WireGuard listen port. But, in this article, I'll use `UDP` port `51822`.
In this article, we'll allow this WireGuard server as our default _gateway_ for _peers_ (clients), so any outgoing network traffic (except to your **LAN/WLAN** network) can go through this WireGuard server. If you use WireGuard as _peer-to-peer_ connection, you don't need to do this.
Next, you need to know which network interface used by your server as its _default route_. You can use `ip route list default` to see that. Example output of my `ip route list default` command:
Write down the word after `dev` output, that's your default network interface. We will need that information later. In this example, my default network interface is `eth0`.
Note that `wg0` above is taken from your configuration file under `/etc/wireguard` directory (but without `.conf` file extension). If your configuration file is named `internal.conf`, you can start that configuration using `systemctl start wg-quick@internal.service`.
Check that your WireGuard server is running using `systemctl status wg-quick@wg0.service` command:
```plain
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
In this section, I'll use Linux machine using `wg-quick` via `systemd` as an example to connect to our configured WireGuard server. For other method such as connecting using **NetworkManager** GUI, Different OS and mobile devices, you can read my next article: "[Configure WireGuard VPN Clients]({{<ref"/tutorials/configure-wireguard-vpn-clients/index.md">}})".
Configuring WireGuard peer (client) on Linux using `systemd` is almost the same as setting up WireGuard server. The different is you didn't need to configure firewall and IP forward for peers. All you need to do is install WireGuard, create private and public key, configure DNS server you want to use, add start the service.
If you already have your own WireGuard key pairs, you can use that keys, skip this step and go to the next step: "[Configuring WireGuard Peer (client)](#configuring-wireguard-peer-client)".
> _Tips: You can create **vanity** public key address for **WireGuard** using tool like [warner/wireguard-vanity-address](https://github.com/warner/wireguard-vanity-address)._
Before configuring your **WireGuard** peer (client), you need to **decide your WireGuard private IP address for your peer** connection (_tunnel_ interface). You should use unused IP address for peer(s) from your WireGuard network IP range. In this article, `10.10.88.1/24` already used by my WireGuard server, so I can't use that IP for peer(s). I'll use `10.10.88.2/24` (or `10.10.88.2/32`) instead.
PrivateKey = <YOUR_PEER_PRIVATE_KEY> # This example: WApLrVqFvXMbvsn+62DxfQCY8rsFqmHCEFAabAeA5WY=
Address = <YOUR_PEER_IP_ADDRESS> # This example: 10.10.88.2/24
DNS = 1.1.1.1 8.8.8.8 # You can use any public / your own DNS resolver if you want
[Peer]
PublicKey = <YOUR_SERVER_PUBLIC_KEY> # This example: 7c023YtKepRPNNKfGsP5f2H2VtfPvVptn8Hn6jjmaz8=
AllowedIPs = 0.0.0.0/0 # Route all external traffic to here
Endpoint = <YOUR_SERVER_PUBLIC_IP_ADDRESS>:<SERVER_UDP_LISTEN_PORT> # This example: xxx.xx.xx0.246:51822
PersistentKeepalive = 15
```
Replace `<YOUR_PEER_PRIVATE_KEY>`, `<YOUR_PEER_IP_ADDRESS>`, `<YOUR_SERVER_PUBLIC_KEY>`, `<YOUR_SERVER_PUBLIC_IP_ADDRESS>`, and `<SERVER_UDP_LISTEN_PORT>` with yours.
-`AllowedIPs` = `0.0.0.0/0` means all traffic will go through that peer (in this case, our WireGuard server).
You can specify / selective routing specific IP to specific peer (if you connected to multiple peers / servers).
For example, if you only want to route traffic to IP 1.0.0.1 and 8.8.4.4 using specific peer and use your current internet connection as default route, you can remove `0.0.0.0/0` and add `1.0.0.1/32,8.8.4.4/32` (separated by comma) to `AllowedIPs` value.
-`PersistentKeepalive` = `15` : How many seconds for peer send _ping_ to the server regularly, so the server can reach the peer sitting behind **NAT**/firewall.
-`DNS` You can also specify DNS servers you want to use in your `DNS` configuration value.
you need to add every peers public key to WireGuard server configuration. This need to be done to allow peers connect to our WireGuard server. There are 2 ways to do this, depending on your server configuration.
If you're following this tutorial with `SaveConfig = true` in the server config, you can add _peer public key_ by issuing this command (in WireGuard Server):
Replace `wg0` with your WireGuard server _interface_, `6gnV+QU7jG7BzwWrBbqiYpKQDGePYQunebkmvmFrxSk=` with your peer public key, and `10.10.88.2` with the IP address of that will be used by that peer.
If your WireGuard server configuration doesn't contain `SaveConfig = true` config, all you need to do is add peers information to your WireGuard server config (`/etc/wireguard/wg0.conf`). For Example:
Replace `6gnV+QU7jG7BzwWrBbqiYpKQDGePYQunebkmvmFrxSk=` with your peer public key, and `10.10.88.2` with the IP address of that will be used by that peer.
Don't forget to restart WireGuard service every time you change `/etc/wireguard/wg0.conf` file.
> _**Note 1**: `wg-do1` above is taken from your configuration file under `/etc/wireguard` directory (but without `.conf` file extension). If your configuration file is named `vpn-wireguard.conf`, you can start that configuration using `systemctl start wg-quick@vpn-wireguard.service`._
> _**Note 2**: By default `wg-quick` uses `resolvconf` to register new DNS entries. This will cause issues with network managers and DHCP clients that do not use `resolvconf`, as they will overwrite `/etc/resolv.conf` thus removing the DNS servers added by `wg-quick`._
> _The solution is to use networking software that supports `resolvconf`._
> _**Note 3**: Users of `systemd-resolved` should make sure that `systemd-resolvconf` is installed._
To verify your configurations is properly configured, try to check your public IP from your browser or terminal using `sudo wg show` or `curl ifconfig.me`.
WireGuard is my favorite VPN protocol. It's fast and less resource usage compared with other VPN protocols. It's highly configurable and works with multiple environments. Furthermore, it can be used for _peer-to-peer_ connection, _client-server_ connection, or creating secure _mesh network_.
When combined with **Nginx** as _reverse proxy_, you can even expose your local HTTP server (and almost any services) sitting behind **NAT**/firewall to the internet.
Anyway, managing large scale of WireGuard network can be very difficult. But, there are a tool to help you to manage large scale WireGuard networks, such as [Netmaker](https://www.netmaker.io/).