{"id":29354207,"url":"https://github.com/multionlabs/wireport","last_synced_at":"2025-07-09T03:11:41.101Z","repository":{"id":299390661,"uuid":"968349127","full_name":"MultionLabs/wireport","owner":"MultionLabs","description":"Self-hosted ingress proxy \u0026 VPN tunnel. Securely exposes private local \u0026 Docker-based services to the Internet, with free, automatically renewable SSL certificates.","archived":false,"fork":false,"pushed_at":"2025-07-07T12:25:58.000Z","size":1416,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-07T12:38:14.387Z","etag":null,"topics":["caddy","coredns","docker-proxy","ingress","ingress-proxy","ingress-service","kubernetes-alternative","ngrok-alternative","ngrok-replacement","reverse-proxy","self-hosted","ssl-certificates","subnet-proxy","tunnel-proxy","tunneling","vpn","wireguard"],"latest_commit_sha":null,"homepage":"https://github.com/MultionLabs/wireport","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MultionLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-17T23:50:23.000Z","updated_at":"2025-07-07T12:26:01.000Z","dependencies_parsed_at":"2025-06-16T10:33:38.915Z","dependency_job_id":"01786081-b829-4e79-b52c-c63d9ea9d89c","html_url":"https://github.com/MultionLabs/wireport","commit_stats":null,"previous_names":["multionlabs/wireport"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/MultionLabs/wireport","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultionLabs%2Fwireport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultionLabs%2Fwireport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultionLabs%2Fwireport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultionLabs%2Fwireport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MultionLabs","download_url":"https://codeload.github.com/MultionLabs/wireport/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MultionLabs%2Fwireport/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264384389,"owners_count":23599612,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caddy","coredns","docker-proxy","ingress","ingress-proxy","ingress-service","kubernetes-alternative","ngrok-alternative","ngrok-replacement","reverse-proxy","self-hosted","ssl-certificates","subnet-proxy","tunnel-proxy","tunneling","vpn","wireguard"],"created_at":"2025-07-09T03:11:40.268Z","updated_at":"2025-07-09T03:11:41.089Z","avatar_url":"https://github.com/MultionLabs.png","language":"Go","funding_links":["https://github.com/sponsors/maxskorr"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/wireport-with-slogan.png\" alt=\"wireport logo\" width=\"200\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\" style=\"color:#23132d\"\u003e\n  wireport\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eSelf-hosted ingress proxy \u0026 VPN tunnel. Securely exposes private local \u0026 Docker-based services to the Internet, with free, automatically renewable SSL certificates.\u003c/strong\u003e\u003cbr /\u003e\n  Powered by WireGuard, CoreDNS and Caddy\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#features\"\u003eFeatures\u003c/a\u003e •\n  \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e •\n  \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e •\n  \u003ca href=\"#security-considerations\"\u003eSecurity\u003c/a\u003e •\n  \u003ca href=\"#troubleshooting\"\u003eTroubleshooting\u003c/a\u003e •\n  \u003ca href=\"#sponsorship\"\u003eSponsorship\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n[![Sponsor me on GitHub](https://img.shields.io/badge/Sponsor-💖-pink?style=for-the-badge)](https://github.com/sponsors/maxskorr)  \n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)\n[![Platform](https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey.svg?style=for-the-badge)](https://github.com/MultionLabs/wireport/releases)\n[![Architecture](https://img.shields.io/badge/Architecture-AMD64%20%7C%20ARM64-lightgrey.svg?style=for-the-badge)](https://github.com/MultionLabs/wireport/releases)\n\n\u003c/div\u003e\n\n---\n\n**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).\n\n- 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\n- Secure tunneling into remote development/staging/production environments to facilitate debugging and troubleshooting of remote Docker-based services\n\n## Features\n\n- SSL/TLS termination with **100% free and automated certificate provisioning and renewal**\n- **Reverse proxy** with support for HTTP(S) and TCP/UDP (Layer-4) (Caddy)\n- **Secure VPN tunneling** (WireGuard)\n- Automatic **service discovery and hostname resolution by Docker container names** (CoreDNS)\n- **Multiplatform CLI** (Linux, macOS, Windows — ARM64 \u0026 AMD64)\n- **Self-hosted** and **open-source**\n- **High performance** with a **low memory footprint**\n- [Quick and easy start](#quick-start) in self-hosted mode in just **two commands** - no tinkering with docker/compose files\n\n## Key Concepts\n\n- **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.\n- **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.\n- **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.\n\n| ![wireport - ingress proxy and VPN tunnel](assets/wireport-ingress-proxy-vpn-tunnel.png) |\n|:--:|\n| *wireport - ingress proxy and VPN tunnel* |\n\n| ![wireport - docker service discovery \u0026 hostname resolution by container name](assets/wireport-docker-service-discovery.png) |\n|:--:|\n| *wireport - docker service discovery \u0026 hostname resolution by container name* |\n\n## Installation\n\n\n**via Homebrew (macOS, Linux)**\n\n```bash\nbrew install MultionLabs/wireport/wireport\n```\n\nor\n\n**via scoop (Windows)**\n\n```bash\nscoop bucket add wireport https://github.com/MultionLabs/scoop-wireport\nscoop install wireport\n```\n\nor\n\n**from binaries (Linux, macOS, Windows)**\n\n\u003cdetails\u003e\n\u003csummary\u003eLinks to latest pre-built packages \u0026 unsigned binaries (Linux, macOS, Windows)\u003c/summary\u003e\n\n| Platform | AMD64 | ARM64 |\n|:---------|:------|:------|\n| **macOS (.pkg)** | [wireport-macos-amd64.pkg](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-macos-amd64.pkg) | [wireport-macos-arm64.pkg](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-macos-arm64.pkg) |\n| **macOS (.zip)** | [wireport-macos-amd64.zip](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-macos-amd64.zip) | [wireport-macos-arm64.zip](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-macos-arm64.zip) |\n| **Linux (.tar)** | [wireport-linux-amd64.tar](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.tar) | [wireport-linux-arm64.tar](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-arm64.tar) |\n| **Linux (.deb)** | [wireport-linux-amd64.deb](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.deb) | [wireport-linux-arm64.deb](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-arm64.deb) |\n| **Linux (.rpm)** | [wireport-linux-amd64.rpm](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.rpm) | [wireport-linux-arm64.rpm](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-arm64.rpm) |\n| **Windows** | [wireport-windows-amd64.zip](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-windows-amd64.zip) | [wireport-windows-arm64.zip](https://github.com/MultionLabs/wireport/releases/latest/download/wireport-windows-arm64.zip) |\n\nInstalling from a `.deb` package on Ubuntu or Debian (amd64):\n\n```bash\nwget https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.deb \u0026\u0026 \\\nsudo dpkg -i ./wireport-linux-amd64.deb\n```\n\nInstalling from an `.rpm` package on Alma or Rocky (amd64):\n\n```bash\nwget https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.rpm \u0026\u0026 \\\nsudo rpm -ivh ./wireport-linux-amd64.rpm\n```\n\nInstalling from a `.tar` package (e.g., on Arch; amd64):\n\n```bash\nwget https://github.com/MultionLabs/wireport/releases/latest/download/wireport-linux-amd64.tar \u0026\u0026 \\\nsudo tar -xvf wireport-linux-amd64.tar -C /\n```\n\n### ⚠️ Running Unsigned Binaries on macOS and Windows\n\nSince the binaries are **not signed with commercial certificates**, your operating system may prevent them from launching by default.  \nYou will need to manually allow them.\n\n---\n\n### 🪟 On Windows\n\nWhen you try to launch the program, you may see a warning similar to:\n\n\u003e **Windows protected your PC**  \n\u003e Windows Defender SmartScreen prevented an unrecognized app from starting.\n\nTo proceed:\n\n1. Click **More info**.\n2. Click **Run anyway**.\n\nThis will start the application despite the warning.\n\n---\n\n### 🍎 On macOS\n\nWhen you attempt to open the app or installer, you may see:\n\n\u003e \"**wireport** cannot be opened because the developer cannot be verified.\"\n\nTo allow it:\n\n1. Open **Finder** and locate the application or `.pkg` file.\n2. **Right-click** (or Control-click) the file and select **Open**.\n3. You will see a similar warning, but this time it includes an **Open** button.\n4. Click **Open** to confirm you trust the file.\n\nAlternatively, you can allow the app through **System Preferences**:\n\n1. Open **Apple Menu \u003e System Settings \u003e Privacy \u0026 Security \u003e General**.\n2. You will see a message that the app was blocked.\n3. Click **Allow Anyway**.\n4. Then, try opening the app again.\n\n---\n\n**Note:**\n- These steps are necessary **only once per file**.\n- If you have any concerns about file integrity, consider [verifying checksums](https://github.com/MultionLabs/wireport/releases) or building binaries from the source code yourself.\n- In enterprise environments, administrators can whitelist the binaries using Group Policy (Windows) or Gatekeeper settings (macOS).\n\n\u003c/details\u003e\n\n## Quick Start\n\nYou're **two commands** away from exposing your first service **from your local machine to the Internet**!\n\n#### 1. Bootstrap a GATEWAY node\n\nRun in your local terminal:\n\n```bash\nwireport gateway up sshuser@140.120.110.10:22\n```\n\n*(replace SSH username, IP, and PORT with the real details of the GATEWAY machine)*\n\nThis command outputs a WireGuard configuration -- **import it into your WireGuard client** on your CLIENT device and **activate it** before proceeding with the next command.\n\n\u003cdetails\u003e\n\u003csummary\u003eSample output\u003c/summary\u003e\n\n```\n🔒 Enter SSH password:\n🚀 wireport Gateway Up\n==========================\n\n📡 Connecting to gateway...\n   Gateway: sshuser@140.120.110.10:22\n   Status: ✅ Connected\n\n🔍 Checking current status...\n   Status: ❌ Not Running\n   💡 Proceeding with installation...\n\n📦 Installing wireport...\n   Gateway: sshuser@140.120.110.10:22\n   Status: ✅ Installation Completed\n\n✅ Verifying installation...\n   Status: ✅ Verified Successfully, Running\n   🎉 wireport has been successfully installed and started on the gateway!\n\n   🔑 Applying Client Join Token: eyJpZCI6IjMxMGIyYTQz...\n\n# # # # # # # # # # # # # # # # # # # # # # #\n#       wireport config for WireGuard       #\n# # # # # # # # # # # # # # # # # # # # # # #\n\n[Interface]\nAddress = 10.0.0.2/24\nPrivateKey = CDCH09W1+x4P+aZ3OIF2dnEhvYOms2RtV2ReIHqa/0I=\nDNS = 10.0.0.1\n\n[Peer]\nPublicKey = AfYB6BMUMYDcIojecg7H5jhnDNzqIf56rXJ74md1Rw4=\nEndpoint = 140.120.110.10:51820\nAllowedIPs = 172.16.0.0/12, 10.0.0.1/24\nPersistentKeepalive = 15\n\n⤵ wireport WireGuard config has been dumped\n\n   ✅ Client Join Token Applied\n\n✨ Bootstrap process completed!\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eAdvanced usage scenarios\u003c/summary\u003e\n\nUse SSH key with an empty passphrase and dump the WireGuard config straight to the file:\n\n```bash\nwireport gateway up sshuser@140.120.110.10:22 --ssh-key-path ~/.ssh/id_rsa --ssh-key-pass-empty \u003e ~/path/to/wireguard-config.conf\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eImportant – firewall and other prerequisites\u003c/strong\u003e\u003c/summary\u003e\n\n`wireport gateway up` expects that:\n\n1) the following ports must be reachable on the target GATEWAY machine *before* you run the command:\n\n* 22/tcp (SSH)\n* 80/tcp and 443/tcp (HTTP/HTTPS)\n* 4060/tcp (Wireport control channel)\n* 51820/udp (WireGuard)\n* 32420-32421/tcp+udp (reserved ports for exposing services with wireport)\n\nExample with UFW:\n\n```bash\nsudo ufw allow 22,80,443,4060/tcp\nsudo ufw allow 51820/udp\nsudo ufw allow 32420:32421/tcp\nsudo ufw allow 32420:32421/udp\nsudo ufw enable\n```\n\n2) Docker is installed on the target GATEWAY machine\n3) The account used for SSHing into the target GATEWAY machine has all the necessary permissions for managing Docker containers, images, and networks\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003ewireport \u003cstrong\u003eDOES NOT\u003c/strong\u003e store SSH credentials\u003c/summary\u003e\n\nwireport relies on [goph](https://github.com/melbahja/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).\n\u003c/details\u003e\n\n#### 2. Expose a local service to the Internet\n\nRun in your local terminal:\n\n```bash\nwireport service publish \\\n  --local  http://10.0.0.2:3000 \\\n  --public https://demo.example.com:443\n```\n(assuming `10.0.0.2` is the IP address of your CLIENT device in wireport network \u0026 there is a DNS A-record for the domain `demo.example.com`, pointing to your GATEWAY node's IP address)\n\n🎉 **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.\n\n\u003cdetails\u003e\n\u003csummary\u003eCommand and flags explained\u003c/summary\u003e\n\nThis 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.\n\n* **--local** – address of the service **on the machine where you run the command** (or another CLIENT/SERVER node from the wireport-managed WireGuard network)\n* **--public** – External protocol / hostname / port that will be reachable on the GATEWAY\n\nIf 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**)\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eImportant - DNS config and other prerequisites\u003c/strong\u003e\u003c/summary\u003e\n\n1) For the service to become available over the given public URL, there must be a respective `A`-record in the DNS settings of your domain name provider, pointing to the target **GATEWAY** machine's IP address.\n\n2) After bootstrapping the GATEWAY node with the `wireport gateway up ...` command, you should add the respective WireGuard tunnel on your local machine\n\n3) There must be a service running and accessible at the address specified in the `--local` flag provided to the `wireport service publish` command (this can be on any CLIENT or SERVER node in the wireport-managed WireGuard network)\n\n4) The following ports are available for exposure on the GATEWAY machine (public URL of the exposed service): 80, 443\n\n\u003c/details\u003e\n\n---\n\n## Other useful commands\n\n| Purpose | Command |\n|:--------|:--------|\n| Remove a public endpoint | `wireport service unpublish -p https://demo.example.com:443` |\n| Adjust headers/timeouts | `wireport service params new -p https://demo.example.com:443 --param-value 'header_up X-Tenant-Hostname {http.request.host}'` |\n| Create more CLIENTs | `wireport client new` |\n| Add a workload SERVER | `wireport server up sshuser@140.120.110.10` |\n| Tear down a SERVER | `wireport server down sshuser@140.120.110.10` |\n| Tear down a GATEWAY | `wireport gateway down sshuser@140.120.110.10` |\n\nRefer to `wireport --help` for the full CLI reference.\n\n## Security Considerations\n\n- The gateway container runs with privileged access for network configuration\n- All traffic is encrypted using WireGuard\n- Control traffic is encrypted (TLS)\n- HTTPS is configurable for secure web access to exposed services\n\n## Troubleshooting\n\nIf you encounter issues:\n1. Check service logs: `docker logs wireport-gateway` or `docker logs wireport-server`\n2. Verify firewall status \u0026 make sure all required ports are open\n3. Check status of the WireGuard network inside the GATEWAY and SERVER wireport containers using `wg show` and other WireGuard commands\n4. Check pingability of private services from inside GATEWAY, SERVER and CLIENT nodes\n5. 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).\n\n\u003cdetails\u003e\n\u003csummary\u003eTest commands for TCP \u0026 UDP forwarding\u003c/summary\u003e\n\nFor testing UDP forwarding, on the SERVR node run:\n\n```bash\ndocker run --rm -d --name udp-server alpine sh -c \"apk add --no-cache socat \u0026\u0026 socat -v UDP-RECV:3000 STDOUT\"\n```\n\n- this command will start a docker container, called `udp-server`.\n\nNow, send some test UDP packets from your CLIENT device, e.g.:\n\n```bash\necho \"hello via UDP\" | nc -u 10.0.0.3 3000\n```\n(for a test inside the wireport network)\n\nor\n\n```bash\necho \"hello via UDP\" | nc -u 140.120.110.10 32420\n```\n(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)\n\nThe logs of `udp-server` container on your SERVER node should log the test data.\n\nFor testing UDP forwarding, on the SERVER node run:\n\n```bash\ndocker run --rm -d --name tcp-server alpine sh -c \"while true; do nc -lk -p 3000; done\"\n```\n\n- this command will start a docker container, called `tcp-server`.\n\nNow, send some test TCP packets from your CLIENT device, e.g.:\n\n```bash\necho \"hello via TCP\" | nc 10.0.0.3 3000\n```\n(for a test inside the wireport network)\n\nor\n\n```bash\necho \"hello via TCP\" | nc 140.120.110.10 32420\n```\n(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)\n\nThe logs of `tcp-server` container on your SERVER node should log the test data.\n\n\u003c/details\u003e\n\n## Sponsorship\n\nIf you find this project useful, please consider [sponsoring the development via GitHub](https://github.com/sponsors/maxskorr). Thank you!\n\n## License\n\n[MIT](LICENSE.txt)\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultionlabs%2Fwireport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmultionlabs%2Fwireport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultionlabs%2Fwireport/lists"}