Poll and display Starlink dish telemetry from an SD-WAN network appliance.
Starlink dishes expose a gRPC API at 192.168.100.1:9200. This script queries
that API through a specified WAN interface and displays dish statistics including
signal quality, obstructions, throughput, latency, and device information.
Designed for Debian and OpenSUSE based x86 network appliances where Starlink is one of multiple WAN uplinks.
| Tool | Purpose | Install |
|---|---|---|
grpcurl |
gRPC client for querying the dish | See below |
jq |
JSON parsing | apt install jq / zypper install jq |
ip |
Interface and routing (iproute2) | Pre-installed on most distros |
# Download static binary (recommended for appliances)
curl -sSL https://github.com/fullstorydev/grpcurl/releases/latest/download/grpcurl_$(uname -s)_$(uname -m).tar.gz \
| tar -xz -C /usr/local/bin grpcurl
# Or via Go
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest./starlink.sh [OPTIONS]
Options:
-i IFACE Network interface connected to Starlink (e.g. eth1)
-d Daemon mode: continuously refresh stats
-n SECS Poll interval in seconds for daemon mode (default: 2)
-j Output raw JSON instead of formatted display
-a ADDR Dish IP address (default: 192.168.100.1)
-p PORT Dish gRPC port (default: 9200)
-v Verbose output
-h Show help
# One-shot statistics via a specific interface
./starlink.sh -i eth1
# Daemon mode with real-time refresh every 2 seconds
./starlink.sh -i eth1 -d
# Daemon mode with 5 second intervals
./starlink.sh -i eth1 -d -n 5
# Raw JSON output (for piping to other tools / monitoring)
./starlink.sh -i eth1 -j
# Use default routing (no interface pinning)
./starlink.sh
# Verbose mode for debugging connectivity
./starlink.sh -i eth1 -v-
Interface routing (
-i): When an interface is specified, the script adds a/32host route to192.168.100.1via that interface, ensuring the gRPC traffic reaches the Starlink dish even if the default route points elsewhere. The route is cleaned up on exit. -
gRPC query: Uses
grpcurlto callSpaceX.API.Device.Device/Handlewith agetStatusrequest. The dish responds with a JSON payload containing all telemetry data. -
Display: Parses the JSON and presents a formatted dashboard with color-coded quality indicators (green/yellow/red thresholds for latency, packet drop, signal quality, etc.).
| Category | Fields |
|---|---|
| Device | ID, hardware version, software version, country, state, uptime, ethernet speed |
| Signal | SNR (dB), boresight azimuth/elevation |
| Throughput | Download (bps), Upload (bps) — auto-scaled to Kbps/Mbps/Gbps |
| Latency | PoP ping (ms), packet drop rate (%) |
| Obstructions | Currently obstructed, fraction obstructed, time obstructed, wedge breakdown |
| Alerts | Active dish alerts (motors stuck, thermal throttle, roaming, etc.) |
| Software | Update state |
For integration into monitoring pipelines, use the -j flag to get raw JSON
output suitable for ingestion by tools like Prometheus (via node_exporter
textfile collector), Telegraf, Zabbix, or similar.
# Example: write metrics to a file every 30s for Prometheus textfile collector
while true; do
./starlink.sh -i eth1 -j | ./json_to_prom.sh > /var/lib/node_exporter/starlink.prom.$$
mv /var/lib/node_exporter/starlink.prom.$$ /var/lib/node_exporter/starlink.prom
sleep 30
doneThe Starlink dish management interface is at 192.168.100.1 on a dedicated
subnet. Depending on your setup:
- With Starlink router: The appliance WAN port gets a DHCP address from the
Starlink router. The dish at
192.168.100.1is reachable through the router's internal network. - Bypass / passthrough mode: The appliance gets a CGNAT address directly.
The dish management IP is still reachable on the
192.168.100.0/24subnet via the connected interface.
In both cases, the -i flag ensures traffic to 192.168.100.1 is routed
through the correct WAN interface on your multi-homed SD-WAN appliance.