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.
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
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 = ...