<!-- https://zunderlabs.com/docs/deploy/network-footprint · Markdown version of the page -->

# Network footprint and the firewall rule

Every connection Guard makes, which ones are optional, how to see them, and a firewall rule that enforces them.

:::note[Planned]
Guard 1.0's network behaviour as planned. Hostnames for the relay and telemetry are not fixed yet.
:::

## What Guard connects to

| Connection | Direction | When | Default |
|---|---|---|---|
| `api.hyperliquid.xyz:443` (HTTPS, WebSocket) | out | paper and mainnet: prices, account, orders | on |
| `api.hyperliquid-testnet.xyz:443` | out | testnet | on in testnet only |
| DNS | out | to resolve the above | on |
| `127.0.0.1:8547` | in, from your machine | your bot | on |
| the relay (WebSocket) | out | TradingView alerts, browser Guard | **off** |
| telemetry heartbeat (version, venue, number of vetoes) | out | counting installs | **off** |

Nothing else. No update check, no crash reporter, no analytics. The relay and telemetry are off until you switch them on in `guard.toml`.

Zunder's own executor already behaves this way on the trading side: it goes to the configured network's URL only, refuses plain HTTP and follows no redirects (`docs/testnet.md`).

## See it

```sh
# Linux
sudo ss -tnp | grep zunder-guard
# macOS
sudo lsof -nP -i -a -c zunder-guard
```

## Enforce it on Linux

The installer runs Guard as its own user, `zunder-guard`. With nftables, that user may reach DNS and port 443, and nothing else:

```sh
sudo nft add table inet zunder
sudo nft add chain inet zunder out '{ type filter hook output priority 0; }'
sudo nft add rule inet zunder out meta skuid zunder-guard oif lo accept
sudo nft add rule inet zunder out meta skuid zunder-guard udp dport 53 accept
sudo nft add rule inet zunder out meta skuid zunder-guard tcp dport 53 accept
sudo nft add rule inet zunder out meta skuid zunder-guard tcp dport 443 accept
sudo nft add rule inet zunder out meta skuid zunder-guard counter drop
```

The `counter` on the last rule counts every packet Guard tried to send elsewhere. It should stay at zero:

```sh
sudo nft list chain inet zunder out
```

**What this does not prove.** A port rule cannot tell `api.hyperliquid.xyz` from any other server on port 443. Hyperliquid's addresses are not published as fixed, so pinning IPs is fragile. To restrict by hostname, put Guard behind an allow-listing proxy, or use an application firewall (on macOS, for example, LuLu or Little Snitch) with a rule for `zunder-guard` that allows only Hyperliquid's hostnames.

## Inbound

Guard opens no port to the outside. If `ss -tlnp` shows Guard listening on anything but `127.0.0.1` (or the private address you configured), stop it and check `guard.toml`.
