Alpine Linux set up WireGuard VPN server

How do I install and set up WireGuard VPN server on an Alpine Linux cloud server? How can I configure Alpine Linux as the WireGuard VPN server? How can I configure snat to route all VPN traffic on my Alpine Linux?

Tutorial details
Difficulty Advanced (rss)
Root privileges Yes
Requirements Alpine Linux
Time 20m
WireGuard is a free, open-source advanced, and high-speed VPN with state-of-the-art cryptography. It is quicker and simpler as compared to IPSec and OpenVPN implementations. It was initially released for the Linux kernel, but it is getting cross-platform support for other operating systems. This page explains how to install and set up WireGuard VPN on the Alpine Linux cloud server.

Procedure: Alpine Linux set up WireGuard VPN server

Our sample setup includes a simple peer connection between a cloud server running Alpine Linux server, and a CentOS/Ubuntu/Debian Linux desktop client. You can use iOS/Android mobile clients too. The steps are as follows for installing and configuring WireGuard on Alpine Linux as a VPN server.

Please note that [root@alpine-linux ~]# OR {vivek@client:~ }$ is my shell prompt and is not part of actual commands. In other words, you need to copy and paste command after my shell prompt.

Step 1 – Update your system

Run the apk command to install Alpine Linux security updates:
[root@alpine-linux ~]# apk update
[root@alpine-linux ~]# apk upgrade

Outputs:

fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz
v3.12.0-373-gddde33ae67 [http://dl-cdn.alpinelinux.org/alpine/v3.12/main]
v3.12.0-372-g0452e24486 [http://dl-cdn.alpinelinux.org/alpine/v3.12/community]
OK: 12744 distinct packages available

Step 2 – Installing a WireGuard VPN server on Alpine Linux LTS

To find Linux kernel version, run:
[root@alpine-linux ~]# uname -mrs
Linux 5.4.43-1-virt x86_64

For virt kernel use the wireguard-virt package and for lts kernel use the wireguard-lts package. In other words, setting up a WireGuard VPN server on Alpine Linux server, enter:
[root@alpine-linux ~]# apk add wireguard-tools wireguard-virt

Step 3 – Configuring WireGuard server

First we need to create a private and public key pair for the WireGuard server. Let us cd into /etc/wireguard using the cd command:
[root@alpine-linux ~]# cd /etc/wireguard/
Execute the following umask command along with wg command:
[root@alpine-linux ~]# umask 077; wg genkey | tee privatekey | wg pubkey > publickey
To view keys created use the cat command and ls command:
[root@alpine-linux ~]# ls -l privatekey publickey
[root@alpine-linux ~]# cat privatekey
## Please note down the private key ##
[root@alpine-linux ~]# cat publickey

Set Up WireGuard VPN on Alpine Linux by Editing wg0.conf

Edit or update the /etc/wireguard/wg0.conf file as follows:
[root@alpine-linux ~]# nano /etc/wireguard/wg0.conf
## OR ##
[root@alpine-linux ~]# vi /etc/wireguard/wg0.conf

Append the following config directives:

## Set Up WireGuard VPN on Alpine Linux By Editing/Creating wg0.conf File ##
[Interface]
## My VPN server port ##
ListenPort = 31194
 
## VPN server's private key i.e. /etc/wireguard/privatekey ##
PrivateKey = 2IHAoIOz+tWxRZ4oRlI1xHiD5FADVBTKOePnLSZNSkw=
 
[Peer]
## Desktop/client VPN public key (created in step # 6) ##
PublicKey = d7TRyBXIX0I3sC/tPOqrIpNAGwEt2bW43QXKK4cEeGw=
 
## client VPN IP address (note  the /32 subnet) ##
AllowedIPs = 192.168.20.2/32

Save and close the file when using vim text editor.

Step 4 – Set up Awall firewall rules

I am assuming that you have Awall configured on Alpine Linux

Open UDP 31194 port using the following config file

[root@alpine-linux ~]# cat /etc/awall/private/custom-services.json
Let us define WireGuard and Squid server port on Alpine Linux for Awall:

{
    "service": {
        "wireguard": [
            { "proto": "udp", "port": 31194 }
        ],
        "squid": [
            { "proto": "tcp", "port": 3128 }
        ]
    }
}

Update Awall config

Next update your main config file to enable routing and other stuff. In my case:
[root@alpine-linux ~]# cat /etc/awall/optional/cloud-server.json
Add/edit with import custom-services and policy for WireGuard and Internet zone as follows:

{
  "description": "Default awall policy to protect Cloud server",
  "import": "custom-services",
  "variable": { "internet_if": "eth0"},
  "zone": {
    "internet": { "iface": "$internet_if" },
    "vpn": { "iface": "wg0" }
  },
  "policy": [
    { "in": "internet", "action": "drop" },
    { "in": "vpn", "out": "internet", "action": "accept" },
    { "out": "vpn", "in": "internet", "action": "accept" },
    { "action": "reject" }
  ],
  "snat": [ { "out": "internet", "src": "192.168.20.1/24" } ]
}

Save and close the file and then open WireGuard port:
[root@alpine-linux ~]# cat /etc/awall/optional/wireguard.json

{
    "description": "Allow incoming WireGuard UDP port 31194",
    "filter": [
        {
            "in": "internet",
            "out": "_fw",
            "service": "wireguard",
            "action": "accept"
        }
    ]
}

Accept incoming traffic on WireGuard VPN port from WG0 sub/net

[root@alpine-linux ~]# cat /etc/awall/optional/vpntraffic.json
Sample config:

{
    "description": "Allow VPN traffic for selected ports",
    "filter": [
        {
            "in": "vpn",
            "out": "_fw",
            "service": [ "ssh", "dns", "squid", "ping" ],
            "action": "accept",
	    "src": "192.168.20.1/24"
        }
    ]
}

Activate all Awall firewall rule as follows

Run:
[root@alpine-linux ~]# awall list
[root@alpine-linux ~]# awall enable wireguard
[root@alpine-linux ~]# awall enable vpntraffic
[root@alpine-linux ~]# awall activate
## VERIFY that port opened ##
[root@alpine-linux ~]# iptables -S | grep 31194
[root@alpine-linux ~]# ip6tables -S | grep 31194

Allow forwarding of IP packets

Edit the /etc/conf.d/iptables file:
[root@alpine-linux ~]# vi /etc/conf.d/iptables
Find:
IPFORWARD="no"
Update as follows:
IPFORWARD="yes"
Save and close the file. Make sure we activate IP forwarding:
[root@alpine-linux ~]# rc-service iptables restart
[root@alpine-linux ~]# rc-service ip6tables restart
[root@alpine-linux ~]# sysctl net.ipv4.ip_forward

Value 1 indicating that Alpine Linux is now acting as a router:

net.ipv4.ip_forward = 1

Step 5 – Enable and start WireGuard service

Make sure bash installed on Alpine Linux as needed by /etc/network/interfaces:
[root@alpine-linux ~]# apk add bash
Edit the /etc/network/interfaces, run:
[root@alpine-linux ~]# vi /etc/network/interfaces
Append config options for wg0 so that it will start automatically when Alpine Linux boots:

# WireGuard interface with private IP #
auto wg0
iface wg0 inet static
	address 192.168.20.1
	netmask 255.255.255.0
	pre-up ip link add dev wg0 type wireguard
	pre-up wg setconf wg0 /etc/wireguard/wg0.conf
	post-up ip route add 192.168.20.1/24 dev wg0
	post-down ip link delete wg0

Use the ip command or ifconfig command to start WireGuard interface called wg0 manually. It is a one-time, reboot-less option else rebooting the Linux box to activate WiregGuard from /etc/network/interfaces file:
[root@alpine-linux ~]# ip link add dev wg0 type wireguard
[root@alpine-linux ~]# wg setconf wg0 /etc/wireguard/wg0.conf
[root@alpine-linux ~]# ifconfig wg0 192.168.20.1 netmask 255.255.255.0
[root@alpine-linux ~]# ip route add 192.168.20.1/24 dev wg0
[root@alpine-linux ~]# ifconfig wg0 up

We can take down wg0 as follows:
[root@alpine-linux ~]# ifconfig wg0 down
Verify that WireGuard is up and running using the ss command/netstat command/lsmod command along with the grep command:
[root@alpine-linux ~]# netstat -tulpn | grep 31194
## OR ##
[root@alpine-linux ~]# ss -tulpn | grep 31194
[root@alpine-linux ~]# lsmod | grep -i wireguard
## See routing and interface information ##
[root@alpine-linux ~]# ifconfig wg0
[root@alpine-linux ~]# rounte -n

Step 6 – Wireguard VPN client configuration

The procedure for installing and configuring a VPN client is the same as setting up the server. Let us install the client on Ubuntu Linux LTS desktop:
{vivek@client:~ }$ apt install wireguard
Next we need create VPN client config on Linux desktop client:
{vivek@client:~ }$ sh -c 'umask 077; touch /etc/wireguard/wg0.conf'
{vivek@client:~ }$ sudo -i
{vivek@client:~ }$ cd /etc/wireguard/
{vivek@client:~ }$ umask 077; wg genkey | tee privatekey | wg pubkey > publickey
{vivek@client:~ }$ ls -l publickey privatekey
## Note down the privatekey ##
{vivek@client:~ }$ cat privatekey

Edit the /etc/wireguard/wg0.conf file:
{vivek@client:~ }$ nano /etc/wireguard/wg0.conf
## OR ##
{vivek@client:~ }$ vi /etc/wireguard/wg0.conf

Append the following directives:

[Interface]
## This Desktop/client's private key ##
PrivateKey = yK3iYrAN6p3OjqO7i1EZHOFpjRwsW+KoSnYqVKWYJWQ=
 
## Client ip address ##
Address = 192.168.20.2/24
 
[Peer]
## Alpine Linux  server public key ##
PublicKey = jrmb57ih/aiW/a3/eLWP4Aq4av2UkcQyDpTkVaHq0ks=
 
## set ACL and turn on VPN routing ##
AllowedIPs = 0.0.0.0/0  
 
## Your Alpine Linux  LTS server's public IPv4/IPv6 address and port ##
Endpoint = 172.105.63.200:31194
 
##  Key connection alive ##
PersistentKeepalive = 20

Enable and start VPN client/peer connection, run:
{vivek@client:~ }$ systemctl enable wg-quick@wg0
{vivek@client:~ }$ systemctl start wg-quick@wg0
{vivek@client:~ }$ systemctl status wg-quick@wg0

Step 7 – Verification

That is all, folks. By now, both Alpine Linux server and clients must be connected securely using a peer-to-peer VPN called WireGuard. Let us test the connection. Type the following ping command/ip command on your client machine/desktop system:
{vivek@client:~ }$ ping -c 4 192.168.20.1
{vivek@client:~ }$ sudo wg
{vivek@client:~ }$ ip r

Check or find your public IP address from command line on a Linux desktop. You must get your VPN servers IP address:
$ dig TXT +short o-o.myaddr.l.google.com @ns1.google.com
$ dig +short myip.opendns.com @resolver1.opendns.com
$ curl checkip.amazonaws.com

Conclusion

Congratulation! You just learned about setting up a WireGuard VPN server on Alpine Linux and peer (client machine) on both Alpine Linux/Ubuntu Linux desktop. I strongly suggest that you read WireGuard project documentation.

This entry is 6 of 6 in the WireGuard moden Linux/Unix/*BSD VPN Tutorial series. Keep reading the rest of the series:
  1. Ubuntu 20.04 set up WireGuard VPN server
  2. CentOS 8 set up WireGuard VPN server
  3. Debian 10 set up WireGuard VPN server
  4. WireGuard Firewall Rules in Linux
  5. Wireguard VPN client in a FreeBSD jail
  6. Alpine Linux set up WireGuard VPN server
🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
5 comments… add one
  • Anonymous Oct 8, 2020 @ 23:06

    How can I restart WireGuard service when I added a new VPN client?

    • 🐧 Vivek Gite Oct 9, 2020 @ 7:45

      Take down interface and bring it back:
      ifconfig wg0 down \
      && ip link delete wg0 \
      && ip link add dev wg0 type wireguard \
      && wg setconf wg0 /etc/wireguard/wg0.conf \
      && ifconfig wg0 $YOUR_IP netmask $SUB_NET up \
      && ip route add $YOUR_ROUTE dev wg0

      Connect from Peer (VPN clinet) and verify it with:
      wg

  • AppU Oct 9, 2020 @ 7:50

    Hey,

    Instead of using the wg command in /etc/network/interfaces we can use wg-quick[1].

    auto wg0
    iface wg0 inet static
    	address 192.168.20.1
    	netmask 255.255.255.0
    	post-up wg-quick up /etc/wireguard/wg0.conf
    	post-down wg-quick down /etc/wireguard/wg0.conf

    This will be easy when we add new clients. We can add address in wg0.conf too.
    [1]https://manpages.debian.org/unstable/wireguard-tools/wg-quick.8.en.html

  • Zia Oct 13, 2020 @ 8:50

    Hi Vivek,
    So I ran the apk upgrade
    apk upgrade
    My wireguard server and linux kernel has been updated by Alpine:

    (1/2) Upgrading linux-virt (5.4.43-r1 -> 5.4.70-r0)
    (2/2) Upgrading wireguard-virt (5.4.43-r1 -> 5.4.70-r0)
    Executing busybox-1.31.1-r19.trigger
    Executing kmod-27-r0.trigger
    Executing mkinitfs-3.4.5-r3.trigger
    ==> initramfs: creating /boot/initramfs-virt
    Executing grub-2.04-r1.trigger
    Generating grub configuration file ...
    Found linux image: /boot/vmlinuz-virt
    Found initrd image: /boot/initramfs-virt
    done
    Executing syslinux-6.04_pre1-r6.trigger
    /boot is device /dev/sda
    extlinux: no previous syslinux boot sector found
    OK: 382 MiB in 200 packages

    My questions to you: Do i need to reboot the box to get wireguard updates? what will happen to my wg0.conf config files? do i need to recreate those config again on the server? would appreciate reply.

    • 🐧 Vivek Gite Oct 13, 2020 @ 8:54

      Yes, reboot the Alpine Linux server to get an updated version of Linux kernel including WireGuard.

      No need to create config files. Old files will load automatically.

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.