Getting started
How an Orbit account is organised, what lives where in the console, and the shortest path from signing in to serving a name from our network.
A connector on your server opens a connection to a landing point we run and keeps it open. Requests arrive over that connection. Your server accepts nothing from the internet, and its address appears nowhere.
Hiding an origin behind a CDN only works if the origin also refuses everybody who did not come through the CDN. That is a firewall rule that has to be kept correct forever, and an address that leaks once — an old DNS record, a mail header, a certificate transparency log — stays leaked.
A tunnel removes the question. There is no inbound port to protect, so there is no rule to get wrong, and an address that leaks reaches a server that will not answer it.
http://127.0.0.1:8080.curl -fsSL https://dash.yunzheng.space/assets/orbit-link-linux-amd64 -o /usr/local/bin/orbit-link
chmod +x /usr/local/bin/orbit-linkorbit-link --token lnk_… --endpoint 203.0.113.4:7844 --fingerprint sha256:… --local http://127.0.0.1:8080Builds are published for Linux (x86-64, arm64 and ARMv7), macOS (Apple silicon and Intel) and Windows. The console links all of them.
[Unit]
Description=Orbit Link connector
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/orbit-link --token lnk_… --endpoint … --fingerprint … --local http://127.0.0.1:8080
Restart=always
RestartSec=5
DynamicUser=yes
StateDirectory=orbit-link
[Install]
WantedBy=multi-user.targetThe connector is published as a container image for Linux x86-64, arm64 and ARMv7. The image holds the same signed build as the downloads, runs as a non-root user on a read-only file system, and needs no shell.
# orbit-link.env (chmod 600 orbit-link.env)
ORBIT_LINK_TOKEN=lnk_…
ORBIT_LINK_ENDPOINT=203.0.113.4:7844
ORBIT_LINK_FINGERPRINT=…
ORBIT_LINK_LOCAL=http://127.0.0.1:8080docker run -d --name orbit-link --restart unless-stopped --env-file orbit-link.env --network host \
--read-only --cap-drop ALL --security-opt no-new-privileges \
cr.yunzheng.space/orbit-link:1.3.0Inside a container, 127.0.0.1 is the container itself. --network host lets the connector reach a service on the host; to reach another container, use its name instead.
services:
app:
image: your-app-image
orbit-link:
image: cr.yunzheng.space/orbit-link:1.3.0
restart: unless-stopped
env_file: orbit-link.env
environment:
ORBIT_LINK_LOCAL: http://app:8080
read_only: true
cap_drop: [ALL]
security_opt: [no-new-privileges:true]
depends_on: [app]ORBIT_LINK_TOKEN_FILE to its path.1.3.0), a minor line (1.3) and latest; to upgrade, change the tag.docker stop the connector finishes the requests in flight, for up to 8 seconds (ORBIT_LINK_DRAIN), before it exits.Two Helm charts are published. orbit-link runs the connector for one tunnel as a Deployment. orbit-link-controller publishes Ingresses and Gateway API routes: each hostname you declare in the cluster is served through Orbit Link, with no inbound port and no load balancer.
# orbit-link-values.yaml (chmod 600 orbit-link-values.yaml)
tunnel:
token: lnk_…
endpoint: "203.0.113.4:7844"
fingerprint: "…"
local: http://my-app.default.svc.cluster.local:8080
helm install orbit-link oci://cr.yunzheng.space/charts/orbit-link \
--namespace orbit-link --create-namespace -f orbit-link-values.yamlkubectl create namespace orbit-link
kubectl -n orbit-link create secret generic orbit-api --from-file=token=./orbit-api-token
helm install orbit-link oci://cr.yunzheng.space/charts/orbit-link-controller -n orbit-link \
--set clusterName=my-cluster --set orbit.existingSecret=orbit-apiapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
spec:
ingressClassName: orbit-link
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80orbit-link, and HTTPRoutes attached to a Gateway of GatewayClass orbit-link, are published. Host and path rules (Prefix and Exact) are honoured.kubectl describe shows events for each hostname: published, already in use, or over the plan's limit.helm uninstall removes everything the controller created.The current connector is 1.3.0 (2026-09-28). Download it for Linux x86-64, Linux arm64, Linux ARMv7, macOS Apple silicon, macOS Intel or Windows x86-64. orbit-link --version prints the version you have.
From 1.1.0 the connector keeps itself up to date. It checks for a new version when it starts and every few hours, installs only builds signed with our release key, tries each new build before switching to it, and goes back to the previous build if the new one cannot bring the tunnel up. Under systemd it stages updates in its StateDirectory; run by hand, it replaces its own file when it may.
--no-update (or set ORBIT_LINK_NO_UPDATE=1). The console marks tunnels whose connector is older than the current version. A 1.0.0 connector does not update itself: replace it once with the current build.The connector dials an address, not a hostname, so there is no name for a public certificate to vouch for. Instead it pins the landing point's public key: the fingerprint on the command line is a SHA-256 of that key, and the connector refuses to talk to anything that does not present it.
The credential goes the other way: the landing point checks it and accepts the tunnel. A wrong credential and a tunnel that does not exist are refused identically — the difference between them is precisely what somebody guessing would like to learn.
The connector prefers QUIC on UDP 7844 and falls back to TCP on the same port. On a network that drops UDP entirely, add --tcp to skip straight to the fallback rather than waiting for QUIC to give up.
Only outbound connections are needed in both cases. Nothing ever dials your server.
No. That is the point. It needs to be able to make an outbound connection, which is all a home connection or a container on a private network can usually do.
The tunnel goes away and the site behind it becomes unreachable. There is deliberately no public fallback address: keeping one would reintroduce exactly the leak the product exists to prevent. Run the connector under a supervisor — the console gives you a systemd unit.
Yes. Several Shield hostnames can pull from the same tunnel; the connector forwards them all to the same local address, and your own server decides what to do with each Host header.
Link is switched on per platform. If the console says it is not switched on yet, the address pool has not been assigned — ask support.
How an Orbit account is organised, what lives where in the console, and the shortest path from signing in to serving a name from our network.
Add a zone, point your registrar at our name servers, manage records: weighted answers, health-checked records, ALIAS at the apex, zone-file import.
Delegate the whole domain, delegate one hostname, or add a CNAME and leave your DNS where it is. What each one costs you and when to pick it.