{"id":15685572,"url":"https://github.com/riccardobl/hypergate","last_synced_at":"2026-02-25T03:12:30.725Z","repository":{"id":83709941,"uuid":"589727150","full_name":"riccardobl/hypergate","owner":"riccardobl","description":"Hypergate is a zero-configuration, peer-to-peer encrypted tunnel that enables easy communication between Docker containers and/or physical machines located anywhere, even behind NAT.","archived":false,"fork":false,"pushed_at":"2026-02-21T22:17:46.000Z","size":516,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-02-22T04:29:19.083Z","etag":null,"topics":["docker","holepunch","holepunching","hyperswarm","overlay-network","p2p"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/riccardobl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["riccardobl"],"custom":["https://getalby.com/p/rblb"]}},"created_at":"2023-01-16T19:47:06.000Z","updated_at":"2026-02-21T22:17:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"5483d038-5c33-4be4-bcc8-20a53b33c90c","html_url":"https://github.com/riccardobl/hypergate","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/riccardobl/hypergate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riccardobl%2Fhypergate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riccardobl%2Fhypergate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riccardobl%2Fhypergate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riccardobl%2Fhypergate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/riccardobl","download_url":"https://codeload.github.com/riccardobl/hypergate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riccardobl%2Fhypergate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29809230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T22:43:48.403Z","status":"online","status_checked_at":"2026-02-25T02:00:07.329Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["docker","holepunch","holepunching","hyperswarm","overlay-network","p2p"],"created_at":"2024-10-03T17:26:57.300Z","updated_at":"2026-02-25T03:12:30.717Z","avatar_url":"https://github.com/riccardobl.png","language":"TypeScript","funding_links":["https://github.com/sponsors/riccardobl","https://getalby.com/p/rblb"],"categories":[],"sub_categories":[],"readme":"# Hypergate\n\nHypergate is a peer-to-peer encrypted tunnel for exposing local services across NAT/firewalls using Hyperswarm.\n\nIt is designed to be mostly zero-conf:\n\n- run a `Service Provider` where your private services live\n- run a `Gateway` where you want ports exposed\n- share the same router secret\n\nThat is enough for the basic flow.\n\n\n- [Roles](#roles)\n- [Why Hypergate](#why-hypergate)\n- [Network Layout (at a glance)](#network-layout-at-a-glance)\n- [Quick Start](#quick-start)\n- [Docker Mode](#docker-mode)\n  - [Example: Cross-Host Docker Network + Public Gateway](#example-cross-host-docker-network--public-gateway)\n- [Advanced](#advanced)\n  - [Ingress Policy (Provider -\u003e Gateway)](#ingress-policy-provider---gateway)\n  - [Bandwidth Limiting (Gateway Ingress Shaping)](#bandwidth-limiting-gateway-ingress-shaping)\n  - [Fingerprint Resolver (Provider Side)](#fingerprint-resolver-provider-side)\n  - [Temporary “Unlimited” Override (Gateway)](#temporary-unlimited-override-gateway)\n- [Common CLI Options](#common-cli-options)\n- [Security Notes](#security-notes)\n- [License / Warranty](#license--warranty)\n\n## Roles\n\n- `Service Provider`: announces local services and accepts tunneled connections\n- `Gateway`: opens listening ports and forwards traffic to a provider\n- `Router secret`: shared secret that joins the same Hypergate mesh\n\nMultiple providers and gateways can coexist on the same router.\n\n## Why Hypergate\n\n- Expose services behind NAT\n- Bridge services across machines\n- Run a public gateway while keeping backends private\n- Work with Docker-discovered services\n\n## Network Layout (at a glance)\n\n| Single Provider \u0026 Gateway | Multiple Providers \u0026 Gateways |\n| ------------------------- | ----------------------------- |\n| ![Single Provider and Gateway](static/gateway-provider.jpg) | ![Multiple Providers and Gateways](static/multi-gateway-provider.jpg) |\n\nProviders are authoritative for route advertisements. Gateways consume those routes and expose the matching ports. If multiple providers advertise the same service/gate, Hypergate can select among them.\n\n## Quick Start\n\nGenerate a router secret:\n\n```bash\nhypergate --new\n```\n\nStart a provider:\n\n```bash\nhypergate --router \u003crouter-secret\u003e --provider services/http.json\n```\n\nStart a gateway:\n\n```bash\nhypergate --router \u003crouter-secret\u003e --gateway --listen 0.0.0.0\n```\n\nExample `services/http.json`:\n\n```json\n[\n  {\n    \"gatePort\": 8080,\n    \"serviceHost\": \"127.0.0.1\",\n    \"servicePort\": 8080,\n    \"protocol\": \"tcp\"\n  }\n]\n```\n\nThen connect to `\u003cgateway-host\u003e:8080`.\n\n\n\n## Docker Mode\n\nHypergate can discover Docker containers and register services automatically.\n\n\n| Docker Virtual Network |\n| ---------------------- |\n| ![Docker Virtual Network](static/virtual-network.jpg) |\n\nThis is one of the main zero-conf use cases: containers on different hosts can talk as if they were on the same Docker network, without manual port forwarding.\n\nDocker containers using `EXPOSE` are discovered automatically. You can also control exposure with labels.\n\nDocker labels:\n\n- `hypergate.EXCLUDE=\\\"true|false\\\"`\n- `hypergate.EXPOSE=\\\"port[:public port][/protocol]\\\"`\n- `hypergate.UNEXPOSE=\\\"port[/protocol]\\\"`\n\nExamples:\n\nProvider + Docker discovery:\n\n```bash\nhypergate --router \u003crouter\u003e --docker --provider --network hypergatenet\n```\n\nGateway + Docker helper:\n\n```bash\nhypergate --router \u003crouter\u003e --docker --gateway --listen 0.0.0.0 --network hypergatenet\n```\n\n### Example: Cross-Host Docker Network + Public Gateway\n\nScenario:\n\n- `MACHINE1` hosts MariaDB\n- `MACHINE2` hosts phpMyAdmin\n- `MACHINE3` exposes phpMyAdmin publicly\n\n1. Create router key\n\n```bash\ndocker run -it --rm hypergate --new\n```\n\n2. Start Service Provider on `MACHINE1`\n\n```bash\ndocker run -it --rm -u root --name=\"hypergate-sp-machine1\" \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  hypergate --router \u003crouter-key\u003e --docker --provider --network hypergatenet\n```\n\n3. Start MariaDB on `MACHINE1` and connect it to the Hypergate Docker network\n\n```bash\ndocker run -d --rm --name test-mysql \\\n  -e MYSQL_ROOT_HOST=% \\\n  -e MYSQL_DATABASE=wp \\\n  -e MYSQL_ROOT_PASSWORD=secretpassword \\\n  --label hypergate.EXPOSE=3306 \\\n  mysql\n\ndocker network connect hypergatenet test-mysql --alias mysql.hyper\n```\n\n4. Start Gateway on `MACHINE2`\n\n```bash\ndocker run -it --rm -u root --name=\"hypergate-gw-machine2\" \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  hypergate --router \u003crouter-key\u003e --docker --gateway --listen 0.0.0.0 --network hypergatenet\n```\n\n5. Start Service Provider on `MACHINE2`\n\n```bash\ndocker run -it --rm -u root --name=\"hypergate-sp-machine2\" \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  hypergate --router \u003crouter-key\u003e --docker --provider --network hypergatenet\n```\n\n6. Start phpMyAdmin on `MACHINE2` and connect it to the Hypergate Docker network\n\n```bash\ndocker run --rm --name test-phpmyadmin -d \\\n  -e PMA_HOST=mysql.hyper \\\n  --label hypergate.EXPOSE=80 \\\n  phpmyadmin\n\ndocker network connect hypergatenet test-phpmyadmin --alias phpmyadmin.hyper\n```\n\n7. Start public Gateway on `MACHINE3`\n\n```bash\ndocker run -it --rm -u root --name=\"hypergate-gw-machine3\" \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -p 8080:80 \\\n  hypergate --router \u003crouter-key\u003e --docker --gateway --listen 0.0.0.0 \\\n  --network hypergatenet --exposeOnlyServices phpmyadmin.hyper\n```\n\nTest:\n\n- Open `http://\u003cmachine3\u003e:8080`\n\n\n## Advanced\n\nThese are optional. You do not need them for normal usage.\n\n### Ingress Policy (Provider -\u003e Gateway)\n\nA provider can attach an ingress policy to routes so the gateway can:\n\n- allow/deny specific client IPs\n- apply bandwidth shaping per IP\n- tag matching clients with labels (included in connection fingerprint metadata)\n\nPass it with:\n\n```bash\nhypergate --router \u003crouter\u003e --provider services/http.json --ingressPolicy ingress.policy.example.json\n```\n\nMinimal example:\n\n```json\n{\n  \"defaults\": {\n    \"allow\": true,\n    \"bandwidthLimit\": { \"mbps\": 10, \"burstMbps\": 50 }\n  },\n  \"ips\": {\n    \"203.0.113.10\": {\n      \"bandwidthLimit\": null,\n      \"labels\": [\"trusted\"]\n    },\n    \"198.51.100.25\": {\n      \"allow\": false\n    }\n  }\n}\n```\n\nNotes:\n\n- First matching IP rule wins\n- If no rule matches, `defaults` is used\n- `expireAt` (optional, ms timestamp) can be used for temporary rules\n- IPv4, IPv6, CIDR, and `*` are supported\n\n#### Bandwidth Limiting (Gateway Ingress Shaping)\n\nWhen `bandwidthLimit` is set in the matched ingress rule:\n\n- traffic above the sustained limit is delayed (shaped)\n- if queued burst exceeds the configured burst budget, the channel is dropped\n\nFields:\n\n- `mbps`: sustained bandwidth\n- `burstMbps` (optional): burst capacity (defaults to `mbps`)\n\n### Fingerprint Resolver (Provider Side)\n\nThe provider can run a local HTTP resolver so backends (e.g. Nginx helpers/scripts) can map provider-side socket tuples back to original client metadata.\n\nDefaults:\n\n- host: `127.0.0.1`\n- port: `8080`\n- basic auth: disabled\n\nUseful options:\n\n- `--fingerprintResolverHost`\n- `--fingerprintResolverPort`\n- `--fingerprintResolverBasicAuth user:pass`\n\nEndpoints:\n\n- `GET /health`\n- `GET /resolve`\n\n### Temporary “Unlimited” Override (Gateway)\n\nThe gateway can optionally expose a local `/unlimited` endpoint for trusted machines.\n\nPurpose:\n\n- let trusted machines refresh a temporary per-IP ingress override\n- remove bandwidth limits for that caller IP for a short window\n\n\u003e [!NOTE]\n\u003e caller IP must match token IP\n\nEnable it with:\n\n```bash\nhypergate --router \u003crouter\u003e --gateway --listen 0.0.0.0 \\\n  --unlimitedSecret \"shared-secret\" \\\n  --unlimitedHost 127.0.0.1 \\\n  --unlimitedPort 8091\n```\n\nThe endpoint is intended for automation (e.g. `curl` loop on trusted hosts).\n\nCall it with `curl`:\n\n```bash\nSECRET='shared-secret'\nIP='203.0.113.10'\n\nTIMESTAMP=\"$(date +%s%3N)\"\nPAYLOAD=\"{\\\"timestamp\\\":${TIMESTAMP},\\\"ip\\\":\\\"${IP}\\\"}\"\n\nTOKEN=\"$(printf '%s' \"$PAYLOAD\" | openssl enc -aes-256-cbc -pbkdf2 -iter 10000 -md sha256 -salt -pass pass:$SECRET | openssl base64 -A | tr '+/' '-_' | tr -d '=')\" \n\ncurl \"http://127.0.0.1:8091/unlimited?payload=${TOKEN}\"\n```\n\nToken format is a single base64url string containing the OpenSSL `enc` output (`Salted__` header + salt + ciphertext), encrypted with `AES-256-CBC` + `PBKDF2`.\n\nSince the payload is encrypted and has replay protection it can be safely sent via http without additional transport security, as long as the secret is not leaked.\n\n## Common CLI Options\n\nProvider:\n\n- `--provider \u003cservices.json\u003e`\n- `--ingressPolicy \u003cjson|path|url\u003e` (repeatable, merged)\n- `--fingerprintResolverHost \u003cip\u003e`\n- `--fingerprintResolverPort \u003cport\u003e`\n- `--fingerprintResolverBasicAuth \u003cuser:pass\u003e`\n\nGateway:\n\n- `--gateway`\n- `--listen \u003cip\u003e`\n- `--unlimitedSecret \u003csecret\u003e`\n- `--unlimitedHost \u003cip\u003e`\n- `--unlimitedPort \u003cport\u003e`\n\nUse `hypergate --help` for the full list.\n\n\u003e [!NOTE]\n\u003e Environment variables also exist for these options (`HYPERGATE_*`).\n\n## Security Notes\n\n- Treat the router secret like a credential.\n- If loading ingress policy from URLs, use trusted sources.\n\n## License / Warranty\n\nExperimental software, no warranty.\n\nSee [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friccardobl%2Fhypergate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Friccardobl%2Fhypergate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friccardobl%2Fhypergate/lists"}