add etrelay UDP relay + etmasters script + update README

This commit is contained in:
rmanach
2026-09-26 15:11:44 +02:00
parent 002289fd35
commit 6ab4218601
22 changed files with 1109 additions and 9 deletions
+77
View File
@@ -0,0 +1,77 @@
# etrelay
UDP relay + master heartbeat for the Wolfenstein: Enemy Territory server, running on the front server (replaces its UDP 27960 DNAT rule / nginx `stream` block).
```
players / masters ──> front :27960 (etrelay) ══wg══> <wg-peer>:27960 (nginx stream) ──> ET <et-server>:27960
```
- **Proxy**: one upstream socket per client address, packets forwarded as-is both ways, session dropped after 2 min of silence.
- **Heartbeat**: every 5 min, `getinfo` to the ET server; if it answers, `heartbeat EnemyTerritory-1` to the masters **from the public socket**. When it stops answering, one `heartbeat ETFlatline-1`.
Masters check (`getChallenge`, `getInfo`) the address the heartbeat came from: the public `:27960`. Those packets go through the relay like any client, the ET server answers them, and the master lists the front public address.
How it works in detail, with diagrams: [ENGINE.md](ENGINE.md).
## Usage
```bash
etrelay <UPSTREAM> [--listen 0.0.0.0:27960] [--master host:port]... [--debug]
```
Default masters: `etmaster.idsoftware.com:27950` (id Software, the one ET 2.60b clients query) and `etmaster.net:27950` (ET: Legacy community). Passing `--master` replaces both.
`--debug` logs sessions (open/close, packet counts), connectionless packets by command name only (`getinfo`, `getstatus`, `connect`...: no arguments, `connect` carries the userinfo), probes and heartbeats. In-game packets are only counted.
```
probe <wg-peer>:27960: up
ET server <wg-peer>:27960 is up
heartbeat EnemyTerritory-1 -> etmaster.net:27950 (198.51.100.10:27950)
session + 198.51.100.10:27950 (2 active)
198.51.100.10:27950 -> ET getChallenge (27 B)
198.51.100.10:27950 <- ET challengeResponse (32 B)
198.51.100.10:27950 -> ET getInfo (22 B)
198.51.100.10:27950 <- ET infoResponse (303 B)
session - <player>:27960: 5321 packets to ET, 4876 from ET
```
Deploy with it: `make deploy HOST=<front> UPSTREAM=<wg-peer>:27960 ARGS=--debug`, back to normal without `ARGS`.
## Build
```bash
make build # dynamic (glibc)
make static # static (musl), runs on any x86_64 Linux
make release # both
```
Artifacts land in `dist/`, named `<name>-v<version>-<target triple>` with a `.sha256` checksum:
```
dist/etrelay-v0.1.0-x86_64-unknown-linux-gnu # dynamic
dist/etrelay-v0.1.0-x86_64-unknown-linux-musl # static
```
## Deploy
1. Relay (static binary + systemd unit on the front, `HOST` is its SSH host): `make deploy HOST=<front> UPSTREAM=<wg-peer>:27960`
2. Front: remove what captured UDP 27960 before etrelay, or players bypass it:
- the DNAT rule (`PostUp`/`PostDown` in `/etc/wireguard/wg0.conf`, then `wg-quick down wg0 && wg-quick up wg0`); `iptables -t nat -S | grep 27960` must print nothing
- the nginx `stream` block (`proxy/nginx/nginx.conf` in the `pve` repo): `make -C proxy deploy-nginx` from there
3. ET server `server.cfg`: stop its own heartbeats, they leave through the home box with the wrong IP:
```
set sv_master1 ""
set sv_master2 ""
set sv_master3 ""
set sv_master4 ""
set sv_master5 ""
```
## Check
```bash
make logs HOST=<front> # "ET server ... is up"
ssh <front> tcpdump -ni any udp port 27950 # heartbeat out, getChallenge/getInfo in, answers out
```
The server then shows up on the master (in-game server browser).