Wheelhouse docs

Ports and listeners#

A router's attack surface is the list of things listening on it, so this is that list, for a box that has just finished the interactive install with the firewall box left checked. Two of the rows need saying out loud: the agent binds every interface, including the WAN, and the router's own API is pinned to loopback where only the agent can reach it.

After an interactive install#

PortServiceBound toReachable from
8443/tcpThe Wheelhouse agent: web UI and HTTP API0.0.0.0every interface, including the WANwhatever the firewall lets through
443/tcpThe router's own HTTPS and REST API127.0.0.1 onlythe agent, and root on the box
53/udp, 53/tcpThe DNS forwarderthe LAN addressthe LAN subnet only (allow-from)
67/udpThe DHCP serverthe LAN interfacethe LAN
123/udpNTP, client and serverloopback, link-local and the RFC 1918 ranges (allow-client)
22/tcpSSHnot configurednothing

SSH is genuinely absent: neither the image's default configuration nor the installer writes service ssh, so a freshly installed router has no SSH at all and the console is the only shell. Every remote procedure in this documentation that uses ssh needs you to turn it on first.

bash
show configuration commands | match 'service ssh'

8443, and what keeps it off the internet#

The shipped systemd unit passes --addr 0.0.0.0:8443 and --tls-self-signed. Nothing but the firewall keeps the management UI off the internet. The installer's firewall writes a default-drop input filter for both address families that accepts from the LAN, from loopback, ICMP, the DHCP or DHCPv6 client port on the WAN, and from a management prefix if you named one — and nothing else. It does not open 8443 from the WAN.

An empty answer to this, on a box with a WAN, is an emergency rather than a preference:

bash
show configuration commands | match firewall

The certificate is self-signed unless you supply one. The agent logs a warning at start if it is serving on a non-loopback address with no certificate at all, naming the three fixes: --tls-cert/--tls-key, --tls-self-signed, or a TLS proxy in front.

443, and why it is loopback#

wheelhouse-firstboot.service mints a random 40-character API key for the agent, enables the REST endpoints, and commits set service https listen-address 127.0.0.1. The router's own API stops being a network service; the agent is the management surface. See What first boot does.

The developer install#

install/install.sh binds 127.0.0.1:8090 by default (BIND_ADDR, or --bind-addr), with no TLS unless you configure a certificate. It is the lab path, not the product — if a document's address does not answer, this is usually why. Appliance is 8443, developer install is 8090.

The agent's own default#

With no flags at all, --addr is 127.0.0.1:8090. Only the shipped unit moves it to 0.0.0.0:8443. Running the binary by hand therefore listens on loopback until you say otherwise, which is the right default for a program that can reconfigure a router.

What the agent connects out to#

DestinationWhenWhy
--api-url, https://127.0.0.1 by defaultconstantlyEvery read and every commit.
--license-server, https://license.rhymelikedi.me by default20 s after start, then daily; hourly after a failureLicence refresh. --license-server '' disables it entirely and the agent runs on the offline path.
--oidc-issueronly when single sign-on is configuredDiscovery, and the token exchange on each sign-on.
An app's address and portwhen an installed app declares a health probeA TCP connect, plus one HTTP GET if the catalogue entry gives a path. Never an app-specific API call.
The routers in --fleet-configwhen fleet mode is onConcurrent health, version and configuration reads.

Nothing else. The agent does not phone home, does not fetch an update index, and does not report telemetry — nothing in it reads the release channel.

Container image pulls go out from the router, not from the agent: POST /api/apps/pull asks the router's API to pull, and the router's container runtime does the fetching.

App ports#

An installed app's ports come from its catalogue entry and from what you chose at install. Container apps get an address on the container network — 10.99.0.0/24 by default, declared as network: apps in the catalogue — and are reachable from the router; a host_network app binds the router's own interfaces directly, which is why the install plan warns about it in those words. Per-app ports are on The catalogue.

Checking a running box#

bash
# From the console:
sudo ss -tulpen | grep -v 127.0.0.1

# Or from the agent, which reports the same thing the router sees:
curl -sk "$R/api/services" -H "Authorization: Bearer $T"

See also#

Checked against#

packaging/wheelhouse-agent.service, packaging/firstboot.sh, packaging/wheelhouse-install, packaging/iso/wheelhouse.toml, agent/main.go (registerFlags, runDaemon, isLoopback), agent/license.go (runLicenseRefresher), agent/catalog.go (probeApp), agent/catalog.json, install/install.sh, docs/security.md "The default posture", docs/deploy.md.

Updated 2026-09-02 ports network security