Translation(s): српски

(Simple) Private Tunnel VPN with WireGuard

If you own a Virtual Machine or Virtual Private Server, you can easily setup a VPN server with WireGuard on it to securely tunnel your internet traffic from your home or office.

Once connected to the VPN, outgoing traffic from your VPN client will appear as coming from your server.

There are multiple tutorials online describing how to achieve such a setup. This tutorial uses the default recommended tools for a server with Debian 10 or 11 : ifupdown and nftables. For configuration using other network tools, see WireGuard

Don't follow tutorials which recommend executing a random script downloaded from github. Execute commands step by step, and read the man pages of wg(8) and interfaces(5) if you want to know more.

WireGuard setup

Installation on server

#  echo 'deb buster-backports main' >> /etc/apt/sources.list

# apt install linux-image-amd64

# apt update
# apt install wireguard

$ /sbin/modinfo wireguard

Configuration on server

# mkdir /etc/wireguard/
# chmod 700 /etc/wireguard/
# cd /etc/wireguard/
# wg genkey | tee vpn-server-private.key | wg pubkey > vpn-server-public.key

# cat vpn-server-private.key

# cat > /etc/wireguard/server.conf << EOF
# define the  !WireGuard service
# contents of file vpn-server-private.key
PrivateKey = ...
# UDP service port
ListenPort = 55820

$ ip route ls default
default via dev ens5 proto dhcp src metric 1024

# cat > /etc/network/interfaces.d/wg0 << EOF
# activate on boot
auto wg0
# interface configuration
iface wg0 inet static
    pre-up ip link add wg0 type wireguard
    pre-up wg setconf wg0 /etc/wireguard/server.conf
    # route packages when the VPN interface is up
    post-up sysctl --write net.ipv4.ip_forward=1

    # and stop routing when stopping the VPN interface
    post-down sysctl --write net.ipv4.ip_forward=0
    post-down ip link del wg0

iface wg0 inet6 static
    address fc00:23:5::1/64
    # route packages when the VPN interface is up
    post-up sysctl --write net.ipv6.conf.all.forwarding=1
    # and stop routing when stopping the VPN interface
    post-down sysctl --write net.ipv6.conf.all.forwarding=0


# ifup wg0

# wg show wg0
interface: wg0
  public key: 2efuG9OYmMPQpbkJ8CVxGlvQflY6p1u+o4wjcgGII0A=
  private key: (hidden)
  listening port: 55820

WireGuard client setup

# mkdir /etc/wireguard/
# chmod 700 /etc/wireguard/
# cd /etc/wireguard/
# wg genkey | tee vpn-client-private.key | wg pubkey > vpn-client-public.key

cat > /etc/wireguard/wg0.conf << EOF
# Put here the content of vpn-client-private.key
PrivateKey = ...
Address =, fc00:23:5::2/64

# Put here the content of vpn-server-public.key created on the server
PublicKey = ...
Endpoint =

cat >> /etc/wireguard/server.conf << EOF
# Put here the content of vpn-client-public.key
PublicKey = ...
AllowedIPs =

# wg-quick up wg0

$ ping -c 5

Routing configuration

Now that we have the VPN working, we want to configure client and server, so that all client traffic is sent to the server by default, and the server masquerades the IP address of the client outgoing packets with its own address.

Server part

cat >> /etc/nftables.conf << EOF

add table wireguard-nat

table ip wireguard-nat {
        chain prerouting {
                type nat hook prerouting priority -100; policy accept;

        chain postrouting {
                type nat hook postrouting priority 100; policy accept;
                oifname "ens5" masquerade

systemctl enable --now nftables

# nft list tables
# nft list ruleset

Client part

# cat >> /etc/wireguard/wg0.conf << EOF
AllowedIPs =, ::/0

# wg-quick down wg0
# wg-quick up wg0

$ curl

GUI to start / stop wireguard on the client side

If using a Debian Desktop for your VPN client, you will have NetworkManager installed to manage your wireless connections. NetworkManager can also start / stop the WireGuard tunnel. For this you just need to export your wg-quick configuration wg0.conf into a new NetworkManager profile. See for details