SSH Tunnels
SSH tunnels provide secure shell access to your devices through Peridio's infrastructure. This guide covers SSH-specific configuration and best practices.
Prerequisites
- SSH server running on your device (e.g., OpenSSH)
- Device configured to accept SSH connections
- SSH client on your local machine
Creating an SSH Tunnel
Basic SSH Tunnel
peridio tunnels create \
--device-prn $PERIDIO_DEVICE_PRN \
--device-tunnel-port 22
Connect with SSH
Once the tunnel is open:
ssh username@server_ip -p server_port
Advanced SSH Configuration
Using SSH Config File
Add tunnel configuration to ~/.ssh/config
:
Host my-device-tunnel
HostName 3.82.23.99
Port 47532
User root
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Then connect with:
ssh my-device-tunnel
SSH Key Authentication
Copy your public key to the device before creating the tunnel:
ssh-copy-id -i ~/.ssh/id_rsa.pub user@device
Then connect through the tunnel without password:
ssh -i ~/.ssh/id_rsa user@server_ip -p server_port
Port Forwarding Through SSH
Forward local ports through the SSH tunnel:
# Forward local port 8080 to device port 80
ssh -L 8080:localhost:80 user@server_ip -p server_port
# Forward multiple ports
ssh -L 8080:localhost:80 \
-L 3306:localhost:3306 \
user@server_ip -p server_port
SOCKS Proxy
Create a SOCKS proxy through the tunnel:
ssh -D 1080 user@server_ip -p server_port
Configure applications to use localhost:1080
as SOCKS proxy.
SCP and SFTP
Copy Files with SCP
Upload files to device:
scp -P server_port file.txt user@server_ip:/path/to/destination
Download files from device:
scp -P server_port user@server_ip:/path/to/file.txt ./
SFTP Connection
sftp -P server_port user@server_ip
SSH Tunnel Automation
Shell Script Example
#!/bin/bash
DEVICE_PRN="prn:1:device:..."
MAX_WAIT=30
WAIT_INTERVAL=2
# Create tunnel
TUNNEL_RESPONSE=$(peridio tunnels create \
--device-prn $DEVICE_PRN \
--device-tunnel-port 22 \
--output json)
TUNNEL_PRN=$(echo $TUNNEL_RESPONSE | jq -r '.prn')
# Poll for tunnel to open
elapsed=0
while [ $elapsed -lt $MAX_WAIT ]; do
sleep $WAIT_INTERVAL
STATUS=$(peridio tunnels get --prn $TUNNEL_PRN --output json)
STATE=$(echo $STATUS | jq -r '.state')
if [ "$STATE" = "open" ]; then
IP=$(echo $STATUS | jq -r '.server_tunnel_ip_address')
PORT=$(echo $STATUS | jq -r '.server_tunnel_port')
echo "Connecting to $IP:$PORT"
ssh root@$IP -p $PORT
exit 0
fi
elapsed=$((elapsed + WAIT_INTERVAL))
WAIT_INTERVAL=$((WAIT_INTERVAL * 2))
done
echo "Tunnel failed to open within $MAX_WAIT seconds"
exit 1
Security Considerations
SSH Hardening
On your devices, configure /etc/ssh/sshd_config
:
# Disable root login
PermitRootLogin no
# Use key authentication only
PasswordAuthentication no
PubkeyAuthentication yes
# Limit users
AllowUsers myuser
# Change default port (update tunnel creation accordingly)
Port 2222
Host Key Verification
For production use, maintain known hosts:
# Add device host key to known hosts
ssh-keyscan -p server_port server_ip >> ~/.ssh/known_hosts
Session Recording
Record SSH sessions for audit:
ssh user@server_ip -p server_port | tee session-$(date +%Y%m%d-%H%M%S).log
Troubleshooting SSH Tunnels
Connection Timeout
# Increase connection timeout
ssh -o ConnectTimeout=30 user@server_ip -p server_port
# Keep connection alive
ssh -o ServerAliveInterval=60 user@server_ip -p server_port
Permission Denied
- Verify SSH service is running:
systemctl status sshd
- Check SSH logs:
journalctl -u sshd
- Verify user exists and has shell access
- Check
/etc/ssh/sshd_config
for restrictions
Host Key Changed
If you get "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED":
# Remove old host key
ssh-keygen -R "[server_ip]:server_port"
# Connect and accept new key
ssh user@server_ip -p server_port
Best Practices
- Use Key Authentication: Always prefer SSH keys over passwords
- Limit Tunnel Duration: Request only the time needed
- Restrict User Access: Use dedicated accounts with limited privileges
- Monitor Sessions: Log and audit SSH access
- Regular Key Rotation: Rotate SSH keys periodically
- Disable Unused Services: Only run SSH when needed
Integration with CI/CD
Example GitHub Actions workflow:
- name: Create SSH Tunnel
run: |
TUNNEL_PRN=$(peridio tunnels create \
--device-prn ${{ secrets.DEVICE_PRN }} \
--device-tunnel-port 22 \
--output json | jq -r '.prn')
echo "TUNNEL_PRN=$TUNNEL_PRN" >> $GITHUB_ENV
- name: Wait for Tunnel
run: |
# Wait for tunnel to open
./scripts/wait-for-tunnel.sh $TUNNEL_PRN
- name: Deploy via SSH
run: |
ssh -o StrictHostKeyChecking=no \
user@$TUNNEL_IP -p $TUNNEL_PORT \
"cd /app && git pull && systemctl restart app"
Next Steps
- HTTP Tunnels - Web interface access
- Security Best Practices - Secure your SSH tunnels
- Troubleshooting - Common issues and solutions