OpenVPN and WireGuard server on GitHub Actions: representative NAT traversal case
It's not possible to run server software on GitHub Actions using regular methods: the worker virtual machine is placed behind Network Address Translation (NAT), which prevents it from receiving direct inbound TCP/UDP connections.
This repository consists of GitHub Actions jobs for OpenVPN and WireGuard VPN servers which traverse NAT, making possible to establish VPN connection to the Actions worker machine directly, without any additional tunnel, third-party service, or port forwarding software.
This is a step-by-step, thoroughly documented practical UDP NAT traversal showcase using GitHub Actions with OpenVPN/WireGuard servers as an example, with only stock software from Ubuntu repositories.
NAT used on GitHub Actions is one of the most common ones: it's not the friendliest and not the ugliest.
Independent Mapping, Port Dependent Filter, random port, will hairpin
Once you learn the traversal principle used in this repository, you'll understand the general idea behind any modern NAT traversal implementation.
It is assumed that you run Linux.
authorized_keys
file, git commit itstun-client
by hanpfei installed (apt install stun-client
on Debian/Ubuntu, dnf install stun
on Fedora), as well as openvpn
and/or wireguard
./run.sh openvpn
for OpenVPN server or ./run.sh wireguard
for WireGuard serverPrint OpenVPN connection string
or Print WireGuard configuration file
for VPN connection instructionsssh [email protected]
to connect to your Actions workerNOTE: your IP address will be visible in the commit history for everyone. Set the repository as private if you find this inappropriate for your threat model.
The Action jobs (openvpn, wireguard) in this repository:
nping
until the client is connectedThe client-side run.sh script:
Yes, it bypasses NAT for UDP traffic of GitHub Actions worker running on Microsoft Azure infrastructure behind NAT of the following type:
Independent Mapping, Port Dependent Filter, random port, will hairpin
You will be able to connect to WireGuard/OpenVPN server running on your Actions worker directly, which is not possible otherwise.
Yes, you can connect to it if you're behind the most common NAT with "Independent Mapping" characteristics, either port-preserving or non-port-preserving (random port).
run.sh
script will do everything for you, including NAT type identification.
The cone/port-restricted/symmetric NAT nomenclature is a bit outdated and does not describe all the NAT types found on the real Internet precisely.
Actions worker is placed after port-restricted NAT (which also does not preserve the source port).
For NAT type identification, refer to RFC4787 and RFC5128
The Actions workflow files (jobs) has detailed comments for each step, read it for openvpn and wireguard
General NAT traversal information:
Even more detailed writeup, covering all NAT aspects, will follow later.