Secure Outbound SSH: Connecting Your Raspberry Pi to External Systems
Scenario: Automating Backups Offsite
Suppose your Raspberry Pi collects IoT sensor data at home, but you want nightly offsite backups to a cloud VPS. Outbound SSH is the standard tool for this — but poorly configured, it risks data exposure, failed scripts, or account lockouts.
Outbound vs. Inbound SSH
Direction | Use Case | Key Risk |
---|---|---|
SSH to Raspberry Pi from outside | Remote admin | Port-scanning & attacks |
SSH from Raspberry Pi outward | Data backup, sync, admin | Leaked credentials |
This article focuses on the outbound path: the Pi as SSH client to a remote machine. See bottom for inbound notes.
1. Baseline: Verify OpenSSH Client
Raspberry Pi OS (Debian 11+) ships with the OpenSSH client by default. Confirm:
ssh -V
# Example output:
# OpenSSH_8.9p1 Debian-3, OpenSSL 1.1.1n 15 Mar 2022
Missing? Install or upgrade:
sudo apt-get update
sudo apt-get install openssh-client
Note: No need for openssh-server
unless accepting inbound SSH.
2. Hardened Authentication: Key-Based SSH
Password authentication is deprecated for any system exposed to the internet, even as an outbound client.
Generate Ed25519 Key Pair
ssh-keygen -t ed25519 -C "pi@$(hostname) $(date +%Y-%m-%d)"
# Store passphrase in a secure vault, or leave it empty for automation.
Result: ~/.ssh/id_ed25519
and ~/.ssh/id_ed25519.pub
Known issue: Some legacy systems still require RSA; prefer Ed25519 when possible.
3. Install Public Key on Remote Host
Automated method (requires remote password the first time):
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@remotehost.example.com
If that fails (some hosts block ssh-copy-id
):
cat ~/.ssh/id_ed25519.pub | ssh username@remotehost.example.com "umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys"
Files involved:
~/.ssh/authorized_keys
on remote~/.ssh/id_ed25519
on the Pi
Gotcha: Many VPS providers restrict SSH to non-root users by default.
4. Outbound SSH: Sanity Check
Test key-only login:
ssh -i ~/.ssh/id_ed25519 username@remotehost.example.com
If you see:
Permission denied (publickey).
Possible causes:
- SELinux or file permissions on
~/.ssh
- Key algorithm unsupported by remote SSHD (
/etc/ssh/sshd_config
)
5. Practical Example: Automated Offsite Rsync
Script to push /var/lib/iot_data
to a remote backup target every night:
rsync -avz --delete -e "ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no" \
/var/lib/iot_data/ username@backup1.example.com:/srv/backups/pihost/
Cron job:
0 2 * * * /usr/bin/rsync ... # (full command as above)
Notes:
StrictHostKeyChecking=no
can suppress host verification in automation, but use with caution.- Use a dedicated backup user on the remote with locked-down shell or
ForceCommand
.
6. Security Realities and Headaches
-
Upgrade regularly:
sudo apt-get update && sudo apt-get upgrade
CVEs appear rapidly in OpenSSH (as recent as 2024-05). -
Watch key sprawl:
Remove stale keys from allauthorized_keys
.
Auditing with:ssh-add -l # Local grep ssh ~/.ssh/authorized_keys # Remote
-
Restrict remote shell:
Usecommand="..."
inauthorized_keys
to force only safe commands. -
Limit external exposure:
If possible, have the backup host only accept SSH from trusted IP ranges.
7. Inbound Access to Your Pi (Shortest Guide)
- Forward TCP port 22 (or a random high port) on your router to the Pi’s IP.
- Configure dynamic DNS if your public IP changes.
- Disable password auth in
/etc/ssh/sshd_config
. - Add
fail2ban
or similar brute-force protection. - For regular external admin, use VPN (e.g., WireGuard) instead of exposing SSH.
Note: Many consumer ISPs block inbound port 22. Tunneling or a VPS relay may be required.
Non-Obvious Tip
SSH configuration fragments (Include ~/.ssh/config.d/*.conf
) allow per-host settings for complex multi-environment setups. Example:
# ~/.ssh/config.d/backup.conf
Host backup1
HostName backup1.example.com
User backupjob
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Summary
Outbound SSH from a Raspberry Pi is routine for secure data sync, CI tasks, or remote operations. Keys are critical — never script with plaintext passwords. Lock down remote destinations and audit key usage periodically. When automation fails, actual error logs (not just return code 255
) are more informative than you’d expect.
For advanced scenarios, SSH tunnels or jump hosts are equally valid but outside this article’s scope. For production, couple SSH with logging and monitoring — lost data from a misconfigured script is common.
Known alternative:
Commercial tools (Tailscale, NGROK, etc.) can replace manual SSH + VPN if you need a simpler setup or mesh networking, at the cost of handing traffic to a third party.