fly.io wireguard vpn server

diy vpn server on wireguard

SEAN K.H. LIAO

fly.io wireguard vpn server

diy vpn server on wireguard

fly.io and wireguard

fly.io is a compute platform that runs your apps from container images as micro vms on firecracker. Their have docs on how their private networking uses wireguard, and an interesting blog post on embedding wireguard into their CLI.

But what I want is a vpn server that will forward all my traffic, not just access internal services on fly.io. So, back to DIY then. Fortunately, they do mention that their kernels are wireguard enabled.

build the image

Let's start with a Dockerfile, we'll want the wireguard tools and an script:

1FROM alpine
2
3RUN apk update && \
4    apk add --no-cache \
5        wireguard-tools
6
7COPY run.sh .
8ENTRYPOINT [ "/run.sh" ]

And for our script:

 1#!/bin/sh
 2
 3set -ex
 4
 5# ip forwarding, not strictly necessary I think?
 6cat << EOF > /etc/sysctl.d/forward.conf
 7net.ipv4.ip_forward = 1
 8net.ipv4.conf.all.forwarding = 1
 9net.ipv6.conf.all.forwarding = 1
10EOF
11
12sysctl -p /etc/sysctl.d/forward.conf
13
14# wireguard config
15cat << EOF > /etc/wireguard/wg0.conf
16[Interface]
17Address = 192.168.100.4/24
18ListenPort = 51820
19PrivateKey = ${WIREGUARD_PRIVATE_KEY}
20
21# NAT the clients, we don't allocate extra ip addresses for them
22PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;iptables -A FORWARD -o %i -j ACCEPT
23PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;iptables -D FORWARD -o %i -j ACCEPT
24
25[Peer]
26# eevee
27PublicKey = ......
28AllowedIPs = ......
29EOF
30
31# bring up wireguard
32wg-quick up wg0
33
34# never exit
35while true; do
36    wg show
37    sleep 60
38done

deploy the app

We'll need the app definition

 1# choose a globally unique name
 2app = "app-name"
 3
 4# build from our dockerfile
 5[build]
 6  dockerfile = "Dockerfile"
 7
 8  # expose the wireguard port
 9[[services]]
10  internal_port = 51820
11  protocol = "udp"
12  [[services.ports]]
13    port = 51820

Some commands to setup the app:

1$ flyctl apps create app-name
2$ wg genkey | tee /dev/stderr | wg pubkey
3$ flyctl secrets set WIREGUARD_PRIVATE_KEY=$first_line_from_previous_command
4$ flyctl deploy
5$ flyctl ips list

Then setup clients to connect

1[WireGuardPeer]
2PublicKey = ...
3Endpoint = ...:51820
4PersistentKeepalive = 30
5AllowedIPs = ...