Wireguard in Alpine Linux
Setting up Wireguard in an Alpine Linux Container
One of the more config-sensitive services in a system container (in this case, an Incus-configured LXC) is networking. And although the networking is a bit unusual on a system with VPN, it's not that tricky.
Here are the steps to get Wireguard installed in an Incus LXC container, reverse-engineered from my currently deployed wireguard container's history.
apk add wireguard-tools-wg-quick libqrencode-tools
mkdir /etc/wireguard
cd /etc/wireguard/
umask 077
wg genkey | tee server.privatekey | wg pubkey > server.publickey
vi wg0.conf
Add the following config to wg0.conf:
[Interface]
Address = <some.ip/24>
PrivateKey = <server.privatekey>
ListenPort = 51820
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 = <server.publickey>
AllowedIPs = <some.net/24>
The ip and subnet are the transit subnet that allows a vpn to act as a gateway into and out of your network, they sit between public and private networks. Now generate the public and private key pair for the client:
wg genkey | tee mobile-privatekey | wg pubkey > mobile-publickey
vi mobile.conf
Add the following to your mobile.conf:
[Interface]
PrivateKey = <mobile-privatekey>
Address = <some.subnet/24>
DNS = <internal dns servers separated by spaces>
[Peer]
PublicKey = <mobile-publickey>
Endpoint = <host.or.publicip:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
Let's recap:
- Installed some packages
- Generated server keys
- Generated server config
- Generated mobile client keys
- Generated mobile client configs
Now we need to:
- Enable ipv4 forwarding
- Create an rc-service entry to have the vpn come up after each reboot
Let's add ipv4 forwarding to sysctl:
echo net.ipv4.ip_forward=1 | tee -a /etc/sysctl.conf && sysctl -p
This actually has an issue where it doesn't activate after a reboot unless sysctl -p runs. I know there's an easy fix to this, but for now I'll include the command in the start portion of the wg-quick-wg0 service. Let's generate a qr code of your new mobile.conf config. Create /etc/init.d/wg-quick-wg0 and add the following:
#!/sbin/openrc-run
description="wg-quick wg0"
depend() {
need net
need localmount
}
start() {
sysctl -p
wg-quick up wg0
}
stop() {
wg-quick down wg0
}
Now make the service active and part of the startup routine:
chmod a+x /etc/init.d/wg-quick-wg0
rc-update add wg-quick-wg0
re-service wg-quick-wg0 restart
Generate a qr code for the mobile config:
qrencode -t ansiutf8 < mobile.conf
You should have a nice qr code in your terminal (scan it all you want, it's not a gateway to my network):
Check that the wireguard interface wg0 is up and running, you should see something like this:
Import the qr code from earlier into your mobile Wireguard client and activate the config. That's it.