[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81698":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":15,"starSnapshotCount":15,"syncStatus":14,"lastSyncTime":27,"discoverSource":28},81698,"hysteria-realm-server","apernet\u002Fhysteria-realm-server","apernet","Rendezvous server for Hysteria Realms","",null,"Go",58,10,2,0,4,6,9,12,52.02,false,"master",[],"2026-06-12 04:01:34","# Hysteria Realm Server\n\nA rendezvous server for **Hysteria Realms**, the P2P feature of [Hysteria 2](https:\u002F\u002Fgithub.com\u002Fapernet\u002Fhysteria).\n\nIt coordinates UDP hole punching between Hysteria servers and clients so users can host Hysteria servers from behind NAT or firewalls. No port forwarding, no public IP required.\n\n## How it works\n\n1. A Hysteria server registers a realm with the rendezvous server, advertising its STUN-discovered UDP address(es).\n2. A Hysteria client looks up the realm. The rendezvous pushes the client's address(es), punch nonce, and punch obfuscation key to the server over its SSE stream, and waits.\n3. The Hysteria server runs a fresh STUN, posts the just-discovered addresses back via `\u002Fv1\u002F{id}\u002Fconnects\u002F{nonce}`, and the rendezvous returns those to the client. If the server doesn't post within a few seconds, the rendezvous falls back to the addresses cached at registration time.\n4. Both sides simultaneously send UDP packets toward each other, punching holes in their respective NATs.\n5. Once a hole is open, Hysteria's regular QUIC handshake proceeds over the direct connection.\n\nThe rendezvous server only mediates introductions. **No traffic is relayed.** Once peers are connected, the rendezvous is out of the loop.\n\n## Build\n\n```bash\ngo build -o hysteria-realm-server\n```\n\n## Run\n\n```bash\nHYSTERIA_REALM_TOKEN=your-secret-token \\\nHYSTERIA_REALM_LISTEN=:8443 \\\nHYSTERIA_REALM_CERT=\u002Fpath\u002Fto\u002Fcert.pem \\\nHYSTERIA_REALM_KEY=\u002Fpath\u002Fto\u002Fkey.pem \\\n.\u002Fhysteria-realm-server\n```\n\nEquivalent CLI flags are also supported:\n\n```bash\n.\u002Fhysteria-realm-server \\\n  --token your-secret-token \\\n  --listen :8443 \\\n  --cert \u002Fpath\u002Fto\u002Fcert.pem \\\n  --key \u002Fpath\u002Fto\u002Fkey.pem\n```\n\nIf `HYSTERIA_REALM_CERT` and `HYSTERIA_REALM_KEY` are unset, the server runs over plain HTTP.\n\n## Configuration\n\n| Variable                              | Default                            | Description                                                                                  |\n| ------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------- |\n| `HYSTERIA_REALM_LISTEN`               | `:8443`                            | Address to listen on                                                                         |\n| `HYSTERIA_REALM_TOKEN`                | *REQUIRED*                         | Shared bearer token for realm registration and connection                                    |\n| `HYSTERIA_REALM_CERT`                 | *(none)*                           | Path to TLS certificate                                                                      |\n| `HYSTERIA_REALM_KEY`                  | *(none)*                           | Path to TLS private key                                                                      |\n| `HYSTERIA_REALM_DEBUG`                | `false`                            | Enable debug logs for registration, sessions, and punches                                    |\n| `HYSTERIA_REALM_MAX_REALMS`           | `65536`                            | Maximum total number of registered realms. `0` disables the limit.                           |\n| `HYSTERIA_REALM_MAX_REALMS_PER_IP`    | `4`                                | Maximum realms per client IP. `0` disables the limit.                                        |\n| `HYSTERIA_REALM_TRUSTED_PROXY_HEADER` | *(none)*                           | Header to read the real client IP from when behind a reverse proxy or CDN (e.g. `X-Forwarded-For`, `CF-Connecting-IP`). Empty means use the connecting socket address. |\n| `HYSTERIA_REALM_NAME_PATTERN`         | `^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$` | Regex realm names must match.                                                                |\n\nCLI flags with the same meaning are available: `--listen`, `--token`, `--cert`, `--key`, `--debug`, `--max-realms`, `--max-realms-per-ip`, `--trusted-proxy-header`, and `--realm-name-pattern`. Flags override environment variables.\n\nWhen `HYSTERIA_REALM_TRUSTED_PROXY_HEADER` is set, the server takes the leftmost comma-separated value of that header as the client IP, falling back to the socket address if the header is missing or unparseable. Only enable this when the server is actually behind a trusted proxy that strips\u002Fsets the header — otherwise clients can spoof their IP and bypass the per-IP limit.\n\nRequest bodies are capped at 4 KiB.\n\n## Limitations\n\n- **In-memory only.** All state is lost on restart. Active realms must re-register.\n- **Single shared token.** Every realm uses the same token. Only suitable for self-hosted, trusted-group deployments. More sophisticated third-party implementations are welcome.\n\n## API\n\nAll endpoints use `Authorization: Bearer ...`. Realm names in `{id}` must match `HYSTERIA_REALM_NAME_PATTERN`; an invalid name returns `400 bad_request`.\n\nErrors are returned as JSON: `{\"error\": \"\u003Ccode>\", \"message\": \"\u003Chuman-readable>\"}`. Notable codes:\n\n| Status | Code                  | Cause                                                  |\n| ------ | --------------------- | ------------------------------------------------------ |\n| 400    | `bad_request`         | Invalid JSON, invalid addresses\u002Fnonce\u002Fobfs, bad name   |\n| 401    | `invalid_token`       | Missing or wrong bearer token                          |\n| 404    | `realm_not_found`     | `connect` to a realm that is not registered            |\n| 404    | `attempt_not_found`   | `connects\u002F{nonce}` post for an unknown \u002F expired nonce |\n| 409    | `realm_taken`         | Registering a realm name that is already in use        |\n| 429    | `realm_limit_reached` | Global realm limit reached                             |\n| 429    | `ip_limit_reached`    | Per-IP realm limit reached                             |\n| 503    | `rate_limited`        | Server's punch event buffer or pending-attempts cap is full |\n\n### `POST \u002Fv1\u002F{id}`\n\nRegister a Realm. Uses `HYSTERIA_REALM_TOKEN`.\n\nRequest:\n\n```json\n{\n  \"addresses\": [\"203.0.113.10:4433\"]\n}\n```\n\nResponse:\n\n```json\n{\n  \"session_id\": \"session-token\",\n  \"ttl\": 60\n}\n```\n\n### `GET \u002Fv1\u002F{id}\u002Fevents`\n\nOpen the Realm server's SSE stream. Uses `session_id`.\n\nEvents:\n\n```text\nevent: punch\ndata: {\"addresses\":[\"198.51.100.20:4433\"],\"nonce\":\"...\",\"obfs\":\"...\"}\n```\n\n```text\nevent: heartbeat_ack\ndata: {\"ttl\":60}\n```\n\n`punch` is emitted on every `connect` request for this realm. `heartbeat_ack` is emitted on every successful `heartbeat` and lets clients confirm the SSE stream is still healthy.\n\n### `POST \u002Fv1\u002F{id}\u002Fheartbeat`\n\nRefresh the session TTL. Uses `session_id`. It may also include replacement Realm addresses:\n\n```json\n{\n  \"addresses\": [\"203.0.113.11:4433\"]\n}\n```\n\nIf `addresses` is omitted, only the TTL is refreshed. If present, the Hysteria Realm Server validates and replaces the stored addresses for that Realm.\n\nResponse:\n\n```json\n{\n  \"ttl\": 60\n}\n```\n\n### `DELETE \u002Fv1\u002F{id}`\n\nDeregister a Realm immediately. Uses `session_id`.\n\nResponse: `204 No Content`.\n\n### `POST \u002Fv1\u002F{id}\u002Fconnect`\n\nRequest a connection to a Realm. Uses `HYSTERIA_REALM_TOKEN`.\n\n```json\n{\n  \"addresses\": [\"198.51.100.20:4433\"],\n  \"nonce\": \"00112233445566778899aabbccddeeff\",\n  \"obfs\": \"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\"\n}\n```\n\n- `nonce` is 16 random bytes encoded as 32 lowercase or uppercase hex characters.\n- `obfs` is a 32-byte random key encoded as 64 lowercase or uppercase hex characters, used by peers to obfuscate UDP punch packets.\n\nThe Hysteria Realm Server forwards `addresses`, `nonce`, and `obfs` unchanged in the Realm server's `punch` SSE event, then **blocks the request for up to 10 seconds** waiting for the Realm server to post fresh addresses via `\u002Fv1\u002F{id}\u002Fconnects\u002F{nonce}`. If the post arrives, those fresh addresses are returned to the client; if it doesn't (legacy server, STUN failure, etc.), the registered cached addresses are returned instead. The response always echoes `nonce` and `obfs`:\n\n```json\n{\n  \"addresses\": [\"203.0.113.10:4433\"],\n  \"nonce\": \"00112233445566778899aabbccddeeff\",\n  \"obfs\": \"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff\"\n}\n```\n\n### `POST \u002Fv1\u002F{id}\u002Fconnects\u002F{nonce}`\n\nPosted by the Realm server in response to a `punch` SSE event, with the addresses it just discovered via a fresh STUN. Uses `session_id`. The `{nonce}` path segment must match the `nonce` from the SSE event.\n\n```json\n{\n  \"addresses\": [\"203.0.113.10:4433\"]\n}\n```\n\nResponse: `204 No Content`. Returns `404 attempt_not_found` if the rendezvous has no in-flight `connect` for this nonce.\n","Hysteria Realm Server 是一个用于 Hysteria Realms 的会合服务器，支持 P2P 功能。该项目使用 Go 语言编写，通过协调 Hysteria 服务器与客户端之间的 UDP 打洞技术，使用户能够在 NAT 或防火墙后托管 Hysteria 服务器，无需端口转发或公网 IP。其核心功能包括自动发现和共享 UDP 地址、生成打洞密钥，并在双方之间建立直接连接。一旦连接成功，该服务器不再参与数据传输过程。Hysteria Realm Server 适用于需要在受限网络环境中实现安全且高效的点对点通信场景，如家庭网络或企业内部网络中的文件共享、远程访问等应用。","2026-06-11 04:06:01","CREATED_QUERY"]