---
title: Installing and Configuring WireGuard® on Linux as a VPN server
description: Discover how to install and configure WireGuard as a VPN server on Linux using Scaleway Instances. Follow our step-by-step guide to set up a secure and high-performance VPN server.
products:
  - instances
tags: vpn WireGuard Linux android
dates:
  validation: 2025-07-16
  posted: 2019-03-28
  validation_frequency: 12
difficulty: beginner
usecase:
  - security
ecosystem:
  - third-party
---
import image from './assets/scaleway-wg-android-home.webp'
import image2 from './assets/scaleway-wg-android-conf.webp'
import image3 from './assets/scaleway-wg-android-conf-peer.webp'

import Requirements from '@macros/iam/requirements.mdx'

<ClickableBanner
  productLogo="generic"
  title="Enhance security with WireGuard VPN on your Scaleway infrastructure."
  url="https://account.scaleway.com/register"
  label="Create your account"
/>
WireGuard® is a VPN (Virtual Private Network) software designed for simplicity and efficiency. It is distinguished by its small codebase, which aims to reduce complexity and potential security vulnerabilities, and offers faster performance compared to some other VPN solutions, due to its streamlined design.

In terms of security, WireGuard uses modern cryptographic protocols, including Curve25519, ChaCha20, and Poly1305, focusing on established cryptographic methods.

It is compatible with various platforms, such as Windows, macOS, Linux, iOS, and Android, making it versatile for different users and environments.

<Requirements />

- A Scaleway account logged into the [console](https://console.scaleway.com)
- [Owner](/iam/concepts/#owner) status or [IAM permissions](/iam/concepts/#permission) allowing you to perform actions in the intended Organization
- An [SSH key](/organizations-and-projects/how-to/create-ssh-key/)
- An [Instance](/instances/how-to/create-an-instance/) configured with [local boot](/instances/how-to/use-boot-modes/#how-to-use-local-boot) and running on a Linux kernel ≥ 3.10

<Message type="important">
  WireGuard® is currently under development.
</Message>

## Installing and Configuring WireGuard on the server

The installation process is based on Ubuntu. Documentation regarding other platforms is available on the [WireGuard website](https://www.wireguard.com/install/).

<Message type="note">
  WireGuard needs kernel modules that are not yet implemented in the kernel. The installation process will install new kernel modules via DKMS.
</Message>

1. [Connect to your Instance](/instances/how-to/connect-to-instance/) via SSH.
2. Install Linux kernel headers and WireGuard.
    ```bash
    sudo apt update && apt upgrade -y
    sudo apt install linux-headers-$(uname --kernel-release) # installs the right kernel headers for your version
    sudo apt install wireguard
    ```

Once WireGuard is installed, you can check that the installation succeeded by running: `wg`. No output means that the installation has succeeded. To check that the WireGuard kernel module has loaded you can run `sudo modprobe wireguard`.

### Generating public and private keys on the server

WireGuard relies on public/private key authentication (asymmetric cryptography). You must create these keys, which can be done with the `wg genkey` and `wg pubkey` subcommands.

1. Create a directory to store the keys:
    ```bash
    mkdir -p /etc/wireguard/keys
    ```
2. Create the public and private key. The creation of the private key is done with `wg genkey` and the public key is generated by piping it into `wg pubkey`. `umask` tells the system to set the permissions of the new files to `600`.
    ```bash
    cd /etc/wireguard/keys
    umask 077
    wg genkey | tee privatekey | wg pubkey > publickey
    ```

### Configuring WireGuard server

The first step is to choose an IP range that will be used by the server. The private IP ranges defined by the [RFC 1918](https://tools.ietf.org/html/rfc1918) are the following:

- `10.0.0.0/8`
- `172.16.0.0/12`
- `192.168.0.0/16`

For this tutorial, we will use `192.168.66.0/24` which is inside the `192.168.0.0/16` range. The server will have the following IP address: `192.168.66.1`.

It is also required to choose a port, which will be exposed publicly, for the server to listen on. Here it will be `8999`. Note that the standard documentation port is usually 51820.

Create the file `/etc/wireguard/wg0.conf` with the following content:

```
[Interface]
PrivateKey = <private key of the server>
Address = 192.168.66.1/32
ListenPort = 8999
```

### Configuring the Linux, macOS, or Windows WireGuard client

1. Install WireGuard. On Linux, you can install WireGuard the same way you did for the server. To install WireGuard on macOS just run: `brew install wireguard-tools`. You can also use the [Mac App Store application](https://apps.apple.com/us/app/wireguard/id1451685025?ls=1&mt=12). To install WireGuard on Windows you can find the executable on the [WireGuard installation page](https://www.wireguard.com/install/#installation), but this guide will not cover the Windows use case.
2. Create the key pair:
    ```bash
    mkdir -p /etc/wireguard/keys
    cd /etc/wireguard/keys
    umask 077
    wg genkey | tee privatekey | wg pubkey > publickey
    ```
3. Create the configuration file `/etc/wireguard/wg0.conf`:
    ```
    [Interface]
    PrivateKey = <private key of the client>
    Address = 192.168.66.2/32
    DNS = 1.1.1.1

    [Peer]
    PublicKey = <public key of the server>
    Endpoint = <public ip of the server>:8999
    AllowedIPs = 0.0.0.0/0
    PersistentKeepalive = 25
    ```

    It is quite similar to the server configuration. The `DNS` line specifies the DNS resolver for the client. The `Endpoint` tells WireGuard where to connect. `AllowedIPs` configures which IP range will be forwarded to the VPN server.

    In this case, `0.0.0.0/0` means that all the traffic from the client will go through the VPN. If you only want to communicate within the VPN network, you can set `192.168.66.0/24`. `PersistentKeepalive` tells WireGuard to send a UDP packet every 25 seconds, this is useful if you are behind a NAT and you want to keep the connection alive.

    <Message type="important">
      If you decide to route all your traffic to the VPN server be sure to do the following on the server:
        - Add the following lines in the `[Interface]` section of the server (Replace `ens2` with your main network interface if it is not `ens2`):
          - `PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens2 -j MASQUERADE`
          - `PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens2 -j MASQUERADE`
    </Message>
4. Add the peer configuration to the server. Just add the following to your `/etc/wireguard/wg0.conf` on the server:
    ```
    [Peer]
    PublicKey = <public key of the client>
    AllowedIPs = 192.168.66.2/32 # the ip address in the VPN network of the client you just created
    ```

### Configuring the Android or iOS WireGuard client

You can download the official WireGuard Android client from Google Play, and the [official WireGuard iOS Client](https://apps.apple.com/us/app/wireguard/id1441195209?ls=1) from the iOS App Store (this guide will only cover Android, but the steps are the same).

There are two ways to configure the Android or iOS client. The easiest one is to follow the previous part and once the configuration file is done, export it with [qrencode](https://linux.die.net/man/1/qrencode) like this: `qrencode -t ansiutf8 < path/to/phone.conf`. Finally, scan the generated QR code with the WireGuard application.

For the second way, follow these steps:

1. Download and open the application and click the _+_ icon and select _Create from scratch_.
    <Lightbox image={image} alt="" />
2. Click _GENERATE_ to generate the key pair (copy the public key to use on the server). The rest is like the Linux client configuration, fill in the addresses, DNS servers, and name. Now you will need to add the server as a peer.
    <Lightbox image={image2} alt="" />
3. Click _ADD PEER_ and add the public key of the server, the public IP of the server, and the port on which it is listening. If you decide to route all the traffic through the VPN, read the _Important_ section above.
    <Lightbox image={image3} alt="" />
4. Add the following to the server's `/etc/wireguard/wg0.conf`:
    ```
    [Peer]
    PublicKey = <public key of the android client>
    AllowedIPs = 192.168.66.3/32 # the ip address in the VPN network of the client you just created
    ```

### Launching WireGuard server

Now that everything is configured, you can launch the WireGuard server with:

  ```bash
  wg-quick up wg0
  ```

Start the client with the same command:

  ```bash
  wg-quick up wg0
  ```

You can also enable the start of WireGuard at boot time with the following command:

  ```bash
  systemctl enable wg-quick@wg0.service
  ```

  You can check the connection with the `wg` command (client or server):

  ```bash
  # wg # on the client
  interface: wg0
    public key: <public key of the client>
    private key: (hidden)
    listening port: 57576
    fwmark: 0xca6c

  peer: <public key of the server>
    endpoint: <public IP of the server>:8999
    allowed ips: 0.0.0.0/0
    latest handshake: 50 seconds ago
    transfer: 8.35 KiB received, 18.00 KiB sent
    persistent keepalive: every 25 seconds

  # ping 192.168.66.1
  PING 192.168.66.1 (192.168.66.1) 56(84) bytes of data.
  64 bytes from 192.168.66.1: icmp_seq=1 ttl=64 time=3.50 ms
  64 bytes from 192.168.66.1: icmp_seq=2 ttl=64 time=4.53 ms
  --- 192.168.66.1 ping statistics ---
  2 packets transmitted, 2 received, 0% packet loss, time 3ms
  rtt min/avg/max/mdev = 3.499/4.015/4.532/0.520 ms

  # curl ifconfig.co
  <public IP of the server>
  ```

As you can see, you can ping the VPN server through the VPN and all your traffic is being routed through the VPN server.

For more information, you can check the [WireGuard website](https://www.wireguard.com/).

"WireGuard" is a registered trademark of [Jason A. Donenfeld](https://www.zx2c4.com/).