Self-hosted ingress proxy & VPN tunnel. Securely exposes private local & Docker-based services to the Internet, with free, automatically renewable SSL certificates.
Powered by WireGuard, CoreDNS and Caddy
Features β’ Preparation β’ Quick Start β’ How it works β’ Security β’ Troubleshooting β’ Sponsorship
wireport is a self-hosted ingress proxy and VPN tunnel that securely exposes private local and Docker-based services to the Internet, with free, automatically renewable SSL certificates. Powered by WireGuard (secure networking), CoreDNS and Caddy (performant reverse proxy).
- Exposing local and Docker-based services running in a local network (e.g., on the local machine, on a corporate network, on a NAS, or on a home server) to the Internet
- Secure tunneling into remote development/staging/production environments to facilitate debugging and troubleshooting of remote Docker-based services
- SSL/TLS termination with 100% free and automated certificate provisioning and renewal
- Reverse proxy with support for HTTP(S) and TCP/UDP (Layer-4) (Caddy)
- Secure access to internal docker-based services and admin dashboards
- Secure VPN tunneling (WireGuard)
- Automatic service discovery and hostname resolution by Docker container names (CoreDNS)
- Multiplatform CLI (Linux, macOS, Windows β ARM64 & AMD64)
- Self-hosted and open-source
- High performance with a low memory footprint
- Quick and easy start in self-hosted mode in just two commands - no tinkering with docker/compose files
- GATEWAY β a Linux-based machine with Docker installed, a public IP address, and the following open ports: 80/tcp, 443/tcp, 4060/tcp, 51820/udp and 32420-32421/tcp+udp. This node acts as the ingress gateway and an entry point to your published services.
- CLIENT β any number of laptops/PCs that will connect to the WireGuard network to manage the ingress network and expose services from their local machines to the Internet.
- SERVER (optional) β one or more Linux-based machines (with Docker) that run the workloads you want to expose. These nodes join the same private WireGuard network, provided by the GATEWAY.
Before getting started with wireport, you need to prepare both your CLIENT and GATEWAY nodes. This section covers all the prerequisites and setup requirements for each node type.
- Installed WireGuard client - required for connecting to the VPN tunnel between GATEWAY, SERVER and CLIENT nodes of wireport (official WireGuard website)
- Installed wireport CLI
via Homebrew (macOS, Linux)
brew install MultionLabs/wireport/wireport
or
via scoop (Windows)
scoop bucket add wireport https://github.com/MultionLabs/scoop-wireport
scoop install wireport
or
from binaries (Linux, macOS, Windows)
Links to latest pre-built packages & unsigned binaries (Linux, macOS, Windows)
Platform | AMD64 | ARM64 |
---|---|---|
macOS (.pkg) | wireport-macos-amd64.pkg | wireport-macos-arm64.pkg |
macOS (.zip) | wireport-macos-amd64.zip | wireport-macos-arm64.zip |
Linux (.tar) | wireport-linux-amd64.tar | wireport-linux-arm64.tar |
Linux (.deb) | wireport-linux-amd64.deb | wireport-linux-arm64.deb |
Linux (.rpm) | wireport-linux-amd64.rpm | wireport-linux-arm64.rpm |
Windows | wireport-windows-amd64.zip | wireport-windows-arm64.zip |
Installing from a .deb
package on Ubuntu or Debian (amd64):
wget https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.deb && \
sudo dpkg -i ./wireport-linux-amd64.deb
Installing from an .rpm
package on Alma or Rocky (amd64):
wget https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.rpm && \
sudo rpm -ivh ./wireport-linux-amd64.rpm
Installing from a .tar
package (e.g., on Arch; amd64):
wget https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.tar && \
sudo tar -xvf wireport-linux-amd64.tar -C /
Since the binaries are not signed with commercial certificates, your operating system may prevent them from launching by default.
You will need to manually allow them.
When you try to launch the program, you may see a warning similar to:
Windows protected your PC
Windows Defender SmartScreen prevented an unrecognized app from starting.
To proceed:
- Click More info.
- Click Run anyway.
This will start the application despite the warning.
When you attempt to open the app or installer, you may see:
"wireport cannot be opened because the developer cannot be verified."
To allow it:
- Open Finder and locate the application or
.pkg
file. - Right-click (or Control-click) the file and select Open.
- You will see a similar warning, but this time it includes an Open button.
- Click Open to confirm you trust the file.
Alternatively, you can allow the app through System Preferences:
- Open Apple Menu > System Settings > Privacy & Security > General.
- You will see a message that the app was blocked.
- Click Allow Anyway.
- Then, try opening the app again.
Note:
- These steps are necessary only once per file.
- If you have any concerns about file integrity, consider verifying checksums or building binaries from the source code yourself.
- In enterprise environments, administrators can whitelist the binaries using Group Policy (Windows) or Gatekeeper settings (macOS).
Before bootstrapping your wireport gateway node, you need to ensure proper DNS configuration and gateway node firewall setup.
If your use case does not rely on DNS-names (e.g., you're publishing services on bare IP address of the gateway node and do not use free, automatically managed SSL certificates), you may skip the whole DNS configuration step.
Otherwise, for wireport to correctly expose your local services via publicly available domain names, as well as for you to make use of automatically managed free SSL certificates, you must configure DNS records pointing to your gateway's public IP address (replace 140.120.110.10
with your gateways's node public IP):
-
A Records: Create A records for each domain you plan to use with wireport, pointing to your gateway's public IP address
demo.example.com A 140.120.110.10 api.example.com A 140.120.110.10 *.example.com A 140.120.110.10 (wildcard for subdomains)
-
Propagation Time: DNS changes can take up to 48 hours to propagate globally, though most providers complete propagation within 15-30 minutes
-
Verification: You can verify DNS propagation using tools like:
nslookup demo.example.com dig demo.example.com
For wireport to operate correctly on your gateway node, the following ports must be open and accessible from the Internet on that gateway node:
Port | Protocol | Purpose | Required |
---|---|---|---|
22 | TCP | SSH access for wireport installation. If you use custom SSH port, make sure to open that custom port | β Required |
80 | TCP | HTTP traffic and free SSL certificate validation | β Required |
443 | TCP | HTTPS traffic | β Required |
4060 | TCP | wireport control channel | β Required |
51820 | UDP | WireGuard VPN tunnel | β Required |
32420-32421 | TCP/UDP | Reserved ports for exposed services | β Required |
Ubuntu/Debian (UFW):
sudo ufw allow 22,80,443,4060/tcp
sudo ufw allow 51820/udp
sudo ufw allow 32420:32421/tcp
sudo ufw allow 32420:32421/udp
sudo ufw enable
CentOS/RHEL (firewalld):
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=4060/tcp
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --permanent --add-port=32420-32421/tcp
sudo firewall-cmd --permanent --add-port=32420-32421/udp
sudo firewall-cmd --reload
Cloud Provider Firewalls:
- AWS: Configure Security Groups to allow the required ports
- GCP: Configure Firewall Rules in VPC
- Azure: Configure Network Security Groups
- DigitalOcean: Configure Cloud Firewall
- Docker Installation: The gateway must have Docker installed and running
- SSH Access: The SSH user must have sudo privileges for Docker operations
- Public IP: The gateway must have a public IP address accessible from the Internet
- Domain Ownership: You must own or control the domains you plan to use with wireport
Once GATEWAY and CLIENT node preparations are completed, the following two commands will help you bootstrap the gateway and expose your first service from your local machine to the Internet!
Run in your local terminal on your CLIENT machine:
wireport gateway up [email protected]:22
(replace SSH username, IP, and PORT with the real details of the GATEWAY machine)
This command outputs a WireGuard configuration -- import it into your WireGuard client on your CLIENT device and activate it before proceeding with the next command.
Sample output
π Enter SSH password:
π wireport Gateway Up
==========================
π‘ Connecting to gateway...
Gateway: [email protected]:22
Status: β
Connected
π Checking current status...
Status: β Not Running
π‘ Proceeding with installation...
π¦ Installing wireport...
Gateway: [email protected]:22
Status: β
Installation Completed
β
Verifying installation...
Status: β
Verified Successfully, Running
π wireport has been successfully installed and started on the gateway!
π Applying Client Join Token: eyJpZCI6IjMxMGIyYTQz...
# # # # # # # # # # # # # # # # # # # # # # #
# wireport config for WireGuard #
# # # # # # # # # # # # # # # # # # # # # # #
[Interface]
Address = 10.0.0.2/24
PrivateKey = CDCH09W1+x4P+aZ3OIF2dnEhvYOms2RtV2ReIHqa/0I=
DNS = 10.0.0.1
[Peer]
PublicKey = AfYB6BMUMYDcIojecg7H5jhnDNzqIf56rXJ74md1Rw4=
Endpoint = 140.120.110.10:51820
AllowedIPs = 172.16.0.0/12, 10.0.0.1/24
PersistentKeepalive = 15
‡ wireport WireGuard config has been dumped
β
Client Join Token Applied
β¨ Bootstrap process completed!
Advanced usage scenarios
Use SSH key with an empty passphrase and dump the WireGuard config straight to the file:
wireport gateway up [email protected]:22 --ssh-key-path ~/.ssh/id_rsa --ssh-key-pass-empty > ~/path/to/wireguard-config.conf
Important β firewall and other prerequisites
wireport gateway up
expects that:
- the following ports must be reachable on the target GATEWAY machine before you run the command:
- 22/tcp (SSH)
- 80/tcp and 443/tcp (HTTP/HTTPS)
- 4060/tcp (Wireport control channel)
- 51820/udp (WireGuard)
- 32420-32421/tcp+udp (reserved ports for exposing services with wireport)
Example with UFW:
sudo ufw allow 22,80,443,4060/tcp
sudo ufw allow 51820/udp
sudo ufw allow 32420:32421/tcp
sudo ufw allow 32420:32421/udp
sudo ufw enable
- Docker is installed on the target GATEWAY machine
- The account used for SSHing into the target GATEWAY machine has all the necessary permissions for managing Docker containers, images, and networks
wireport DOES NOT store SSH credentials
wireport relies on goph for handling SSH connections and executing commands on the target remote machines. The credentials are never stored by wireport and they only stay in the memory of your client device for the time of executing the commands (typically, a few seconds).
Run in your local terminal:
wireport service publish \
--local http://10.0.0.2:3000 \
--public https://demo.example.com:443
(assuming 10.0.0.2
is the IP address of your CLIENT device in wireport network & there is a DNS A-record for the domain demo.example.com
, pointing to your GATEWAY node's IP address)
π Congratulations! Your first local service running on port 3000 is now securely accessible on the Internet at https://demo.example.com/
. wireport automatically generates and renews SSL certificates for your domain.
Command and flags explained
This command supports different protocols (HTTP, HTTPS, TCP, UDP) and automatically provisions a free SSL certificate for the domain when an HTTPS-based URL with a domain name is specified in the --public parameter, provided that a correct A-record is set up in your domain provider's DNS settings and points to the GATEWAY machine.
- --local β address of the service on the machine where you run the command (or another CLIENT/SERVER node from the wireport-managed WireGuard network)
- --public β External protocol / hostname / port that will be reachable on the GATEWAY
If a service is supposed to be exposed using the public IP of the gateway node (e.g., to be available on 140.120.110.10
), don't specify the public IP itself in --public argument, but use 0.0.0.0
instead (e.g., tcp://0.0.0.0:32420)
Client Node Configuration is stored in ~/.wireport/<profile>
folder.
Here <profile>
equals default
, unless it's explicitly overridden with WIREPORT_PROFILE
environment variable (e.g., WIREPORT_PROFILE=dev wireport -v
).
When you run wireport gateway up
, the following happens:
- SSH Connection: wireport connects to your gateway machine via SSH
- Docker Installation Check: Verifies Docker is installed and accessible to the SSH user
- Container Deployment: Pulls wireport docker image (version matches your wireport CLI version) and starts
wireport-gateway
Docker container with:- WireGuard VPN server (port 51820/udp)
- Caddy reverse proxy (ports 80/tcp, 443/tcp)
- CoreDNS for service discovery (internal; not exposed to the Internet)
- wireport control plane API (port 4060/tcp; secure communication with TLS-encryption and mTLS-based auth)
- Network Setup: Creates a private WireGuard network (10.0.0.0/24)
- Certificate Generation: Creates client certificates for secure API communication and mTLS
- Configuration Storage: Stores all configuration in
~/.wireport-docker/gateway
on the gateway machine
When you run wireport server up
, the following happens:
- SSH Connection: wireport connects to your server machine via SSH
- Docker Installation Check: Verifies Docker is installed and accessible to the SSH user
- Join Token Generation: Creates a secure token for joining the wireport network
- Container Deployment: Pulls wireport docker image (version matches your wireport CLI version) and starts
wireport-server
Docker container with:- WireGuard VPN client
- Docker network integration
- Service discovery agent
- Network Integration: Connects the server to the wireport-managed WireGuard network, provided by the gateway node
- Configuration Storage: Stores all configuration in
~/.wireport-docker/server
on the server machine
Internet
β
[GATEWAY] β WireGuard VPN β [SERVER] β [Docker Containers]
β
WireGuard VPN
β
[CLIENT] β [Local Services]
- GATEWAY: Public entry point with reverse proxy and VPN server
- SERVER: Runs your workloads in Docker containers
- CLIENT: Manages the network and exposes local/server-based services
- All nodes: Connected via encrypted WireGuard VPN tunnel
Purpose | Command |
---|---|
Remove a public endpoint | wireport service unpublish -p https://demo.example.com:443 |
Adjust headers/timeouts | wireport service params new -p https://demo.example.com:443 --param-value 'header_up X-Tenant-Hostname {http.request.host}' |
Remove service parameters | wireport service params remove -p https://demo.example.com:443 --param-value 'header_up X-Tenant-Hostname {http.request.host}' |
List service parameters | wireport service params list -p https://demo.example.com:443 |
List all published services | wireport service list |
Create more CLIENTs | wireport client new |
Add a workload SERVER | wireport server up [email protected] |
Tear down a SERVER | wireport server down [email protected] |
Tear down a GATEWAY | wireport gateway down [email protected] |
Refer to wireport --help
for the full CLI reference.
- The gateway container runs with privileged access for network configuration
- All traffic is encrypted using WireGuard
- Control traffic is encrypted (TLS)
- HTTPS is configurable for secure web access to exposed services
If you encounter issues:
- Check service logs:
docker logs wireport-gateway
ordocker logs wireport-server
- Verify firewall status & make sure all required ports are open
- Check status of the WireGuard network inside the GATEWAY and SERVER wireport containers using
wg show
and other WireGuard commands - Check pingability of private services from inside GATEWAY, SERVER and CLIENT nodes
- If a private service is not reachable, make sure the container is running and check its logs; check whether the target container (in case of the SERVER workloads) is attached to the
wireport-net
Docker network (wireport agent manages this automatically).
Test commands for TCP & UDP forwarding
For testing UDP forwarding, on the SERVER node run:
docker run --rm -d --name udp-server alpine sh -c "apk add --no-cache socat && socat -v UDP-RECV:3000 STDOUT"
- this command will start a docker container, called
udp-server
.
Now, send some test UDP packets from your CLIENT device, e.g.:
echo "hello via UDP" | nc -u 10.0.0.3 3000
(for a test inside the wireport network)
or
echo "hello via UDP" | nc -u 140.120.110.10 32420
(for a test, involving publicly exposed services, e.g. wireport service publish --public udp://0.0.0.0:32420 --local udp://udp-server:3000
or so)
The logs of udp-server
container on your SERVER node should log the test data.
For testing TCP forwarding, on the SERVER node run:
docker run --rm -d --name tcp-server alpine sh -c "while true; do nc -lk -p 3000; done"
- this command will start a docker container, called
tcp-server
.
Now, send some test TCP packets from your CLIENT device, e.g.:
echo "hello via TCP" | nc 10.0.0.3 3000
(for a test inside the wireport network)
or
echo "hello via TCP" | nc 140.120.110.10 32420
(for a test, involving publicly exposed services, e.g. wireport service publish --public tcp://0.0.0.0:32420 --local tcp://tcp-server:3000
or so)
The logs of tcp-server
container on your SERVER node should log the test data.
If you find this project useful, please consider sponsoring the development via GitHub. Thank you!
Contributions are welcome! Please feel free to submit a Pull Request.