# SSH to a Pi on 4G, LTE, or Starlink

A Raspberry Pi on a mobile connection has no reachable address. Carriers put
every SIM behind carrier-grade NAT, Starlink does the same on its standard
plans, and neither offers port forwarding. So the Pi connects out: an agent
on it holds a tunnel to a relay, and you SSH to the relay. When the link
drops — and on mobile it will — the agent reconnects on its own. This is the
setup for a Pi on a farm, in a vehicle, on a solar site, or on a phone
hotspot.

## Why the usual fixes fail on mobile

The IP a mobile modem reports is internal to the carrier, usually in
`100.64.0.0/10`. Nothing on the internet can connect to it. A
public IPv4 on a SIM is a business product — an APN with a static address —
that costs more per month than the data, and most consumer plans do not
offer it. Starlink's standard plans use CGNAT as well; a public IP is a
paid option on business tiers. Dynamic DNS publishes an address nobody can
reach. The same applies to any tethered laptop or hotspot.

## Install the agent while the Pi is still on your desk

Do this before the Pi goes to the site. Run the install command from
**Add device** and confirm the device shows up in the
dashboard. The agent runs as a systemd service and starts on every boot,
so a power cut at the site is not a trip.

```sh
curl -fsSL https://relayssh.com/install/YOUR-INSTALL-KEY/ | sudo sh
```

## Add a tunnel to port 22 and test it on the mobile link

Add a tunnel to port 22 on the device's page. The relay assigns a port
between 20000 and 29999. Then swap the Pi onto the mobile connection you
will use in the field — the same dongle, the same SIM — and SSH in from a
different network:

```sh
ssh -p 20001 pi@relayssh.com
```

If this works on your desk, it works on site. The carrier's NAT does not
care where the modem is.

## Pull the plug and watch it come back

Unplug the modem for two minutes and plug it back in. The tunnel's SSH
connection sends a keepalive every 30 seconds and gives up after three
missed replies, so a dead link is detected within about 90 seconds. The
agent then reconnects, waiting 5 seconds before the first attempt and
doubling the wait after each failure up to a 5-minute ceiling. Once the
tunnel has been up for a minute, the wait resets to 5 seconds. The device
shows offline in the dashboard while it is gone and online when it is
back — you do not have to do anything.

> **Tip:** A dropped link kills any SSH session that was open. For anything that must survive a reconnect, run it inside tmux or screen on the Pi.

## Data use on a metered plan

The agent sends a heartbeat to the control plane every 5 seconds over a
kept-open HTTPS connection, and the tunnel sends an SSH keepalive every 30
seconds. Both are a few hundred bytes. They still add up on a plan measured
in gigabytes: budget in the hundreds of megabytes a month for a Pi that does
nothing else, and measure it with `vnstat` for a day before
trusting any number, including that one. Your SSH sessions count too, and an
`apt upgrade` over the tunnel costs what it would over any link.

## Starlink specifics

Starlink is CGNAT with more bandwidth. Everything above applies unchanged.
The link also drops briefly a few times an hour on many installs, which the
reconnect handles. If you bought a public IP on a business plan, a forwarded
port on your own router is possible, but a tunnel still saves you exposing
sshd on that IP.

## Boundaries

The Pi needs outbound TCP to `relayssh.com` on ports 443 and
2002; carrier networks allow both. The connection is a tunnel to one port,
not a VPN. To reach a sensor controller or camera next to the Pi on the same
cellular router, see
[reaching devices next to your Pi](https://relayssh.com/docs/reach-lan-devices/).
For the full install walk-through, start at
[getting started](https://relayssh.com/docs/getting-started/).
