A python script that punches a UDP port and opens a Wireguard VPN on it to keep it open. For hosts behind a NAT this allows for TCP/UDP communication directly between two hosts without any portforwarding. It uses a STUN server that swaps hosts information around. This STUN server needs to be visible from the internet either with a public ip or port forwarding.
There are example config files for the STUN server, host A and host B in their respective folders.
- Configure the ip and port of the STUN server on the hosts config files as well as on the STUN server config file.
- Start
server.py
on the STUN server machine. - Run
puncher.py host_config.json
on one of the hosts. This will open a room called'test_room'
with password'room_password'
. - Run
puncher.py partner_config.json
on the other host. This will join the already existing room'test_room'
and start the punch process.
After the punch is finished, a wireguard config file will be generated based on the config file name used and wireguard will be setup with this config file automatically.
To stop the wireguard VPN, simply press Enter on both hosts.
If the host script is run without any arguments, the script will try to use a file called config.json
.
- It is advised that you change the private and public keys used in this example as well as the
security_key
and room information as they are all publicly available here on this repo.
{
"stun_server_addr": "IP of the STUN server",
"stun_server_port": "port of the matchmaking script running on the STUN server",
"wireguard": "can be either y or n. whether or not to use wireguard. this will enable using `private_key`, `public_key`, `subnet` and `wireguard_exe`",
"security_key": "server password, used on all packets sent",
"private_key": "peer private key generated by wireguard",
"user_data": {
"command": "can be either open or join. this will open or join a room in the matchmaking server",
"room_name": "room name",
"password": "room password",
"public_key": "peer public key generated by wireguard",
"subnet": "subnet to be used by both peers, the last byte from the ip should be an @ which will be replaced by either 1 or 2 for each peer eg: 10.100.100.@/24"
},
"wireguard_exe": "wireguard.exe path so the script can initialize and finalize the VPN",
}
{
"port": "port of the matchmaking script",
"security_key": "server password, used on all packets received by the hosts"
}
The script can be used with any application that runs on UDP. By setting the wireguard_exe
param to an empty string ''
the script will only punch the hole. By doing so the script will be compatible with any software that uses UDP after the punch script, keep in mind that the UDP port won't be open for long. You can also edit the script to use a predictable port by changing the line listen_port = randint(32768, 65535)
to something like listen_port = 23456
(if using a 'client'-'server' application, you only need to change this on the 'server'), keep in mind that this may reduce the reliability of the punch.
It is possible to use this script on linux hosts as well. Following the steps above you can set the wireguard_exe
param to an empty string ''
and run the VPN as such:
./puncher.py && sudo wg-quick up ./config_wg
To stop the wireguard VPN, you can run a command similar to:
sudo wg-quick down config_wg