Jump to content

SSH: Difference between revisions

From Archive
Added Technical navigation
Major expansion: add Linux/Debian coverage, port forwarding, security hardening, troubleshooting, advanced techniques
 
Line 1: Line 1:
== Setting up SSH in OS X ==
= SSH =


Quick setup guide for enabling SSH access to a Mac from another machine.
[[File:OpenSSH logo.png|thumb|right|180px|OpenSSH - secure shell protocol]]


=== On Target Mac (Server) ===
'''SSH''' (Secure Shell) is the fundamental protocol for secure remote access. Essential for server administration, development workflows, and secure file transfer.


==== Enable SSH ====
== Quick Reference ==
* '''macOS Ventura/Sonoma:''' System Settings → General → Sharing → Toggle "Remote Login" ON
 
* '''Older macOS:''' System Preferences → Sharing → Check "Remote Login"
{| class="wikitable"
* Note the IP address displayed (e.g., <code>192.168.1.XXX</code>)
! Task !! Command
|-
| Connect || <code>ssh user@host</code>
|-
| Copy file to remote || <code>scp file.txt user@host:/path/</code>
|-
| Copy file from remote || <code>scp user@host:/path/file.txt .</code>
|-
| Sync directories || <code>rsync -avz dir/ user@host:/path/</code>
|-
| Local port forward || <code>ssh -L 8080:localhost:80 user@host</code>
|-
| Remote port forward || <code>ssh -R 9090:localhost:3000 user@host</code>
|-
| SOCKS proxy || <code>ssh -D 1080 user@host</code>
|}
 
== SSH Key Setup ==
 
=== Generate Keys ===


==== Get IP Address ====
<pre>
<pre>
ifconfig | grep "inet " | grep -v 127.0.0.1
# Modern Ed25519 (recommended)
ssh-keygen -t ed25519 -C "[email protected]"
 
# RSA 4096-bit (legacy compatibility)
ssh-keygen -t rsa -b 4096 -C "your@email.com"
</pre>
</pre>


==== Prevent Sleep (Optional) ====
=== Copy Key to Server ===
 
<pre>
# Automatic method
ssh-copy-id user@hostname
 
# Manual method
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
</pre>
 
== SSH Config ==
 
The config file (<code>~/.ssh/config</code>) eliminates repetitive typing:
 
<pre>
# Personal VPS
Host vps
    HostName 123.45.67.89
    User debian
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 30
    ServerAliveCountMax 3
 
# Jump through bastion
Host internal-server
    HostName 10.0.0.50
    User admin
    ProxyJump bastion
 
# Bastion/jump host
Host bastion
    HostName bastion.example.com
    User jumpuser
    IdentityFile ~/.ssh/bastion_key
 
# Wildcard for work servers
Host *.work.example.com
    User workuser
    IdentityFile ~/.ssh/work_key
    ForwardAgent yes
</pre>
 
'''Useful options:'''
* <code>ServerAliveInterval 30</code> - Keep connection alive
* <code>ServerAliveCountMax 3</code> - Retry 3 times before disconnect
* <code>ProxyJump host</code> - Jump through another host
* <code>ForwardAgent yes</code> - Forward SSH agent (use carefully)
* <code>LocalForward 8080 localhost:80</code> - Persistent port forward
* <code>Compression yes</code> - Enable compression
 
== Port Forwarding ==
 
=== Local Forward ===
Access remote service locally:
<pre>
# Access remote PostgreSQL on localhost:5433
ssh -L 5433:localhost:5432 user@dbserver
 
# Access internal web app
ssh -L 8080:internal-app:80 user@bastion
</pre>
 
=== Remote Forward ===
Expose local service to remote:
<pre>
# Let remote server access your local dev server
ssh -R 9000:localhost:3000 user@remote
 
# Expose to all interfaces (requires GatewayPorts yes on server)
ssh -R 0.0.0.0:9000:localhost:3000 user@remote
</pre>
 
=== Dynamic Forward (SOCKS Proxy) ===
<pre>
# Create SOCKS5 proxy
ssh -D 1080 user@host
 
# Use with curl
curl --socks5 localhost:1080 https://example.com
</pre>
 
== macOS Setup ==
 
=== Enable SSH Server ===
* '''macOS Ventura+:''' System Settings → General → Sharing → "Remote Login" ON
* '''Older macOS:''' System Preferences → Sharing → "Remote Login"
 
=== Prevent Sleep (for always-on Mac) ===
<pre>
<pre>
# Disable sleep on AC power
sudo pmset -c sleep 0
sudo pmset -c sleep 0
sudo pmset -c disablesleep 1
sudo pmset -c disablesleep 1
sudo pmset -c womp 1  # Wake on network
</pre>


# Keep WiFi alive during sleep
=== Keychain Integration ===
sudo pmset -c womp 1
Add to <code>~/.ssh/config</code>:
<pre>
Host *
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519
</pre>
 
== Linux/Debian Server Setup ==
 
=== Install and Enable ===
<pre>
sudo apt update && sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh
</pre>
 
=== Harden SSH ===
Edit <code>/etc/ssh/sshd_config</code>:
<pre>
# Disable password auth (keys only)
PasswordAuthentication no
ChallengeResponseAuthentication no
 
# Disable root login
PermitRootLogin no
 
# Limit users
AllowUsers debian
 
# Change port (optional security through obscurity)
# Port 2222
 
# Timeout settings
ClientAliveInterval 300
ClientAliveCountMax 2
</pre>
</pre>


=== On Client Mac (Controller) ===
Apply changes: <code>sudo systemctl reload ssh</code>
 
== Mosh (Mobile Shell) ==
 
For unstable connections (WiFi, mobile, high latency):


==== Test Connection ====
<pre>
<pre>
ssh username@192.168.1.XXX
# Install (both client and server)
brew install mosh    # macOS
sudo apt install mosh # Debian
 
# Connect
mosh user@hostname
 
# With custom port
mosh --ssh="ssh -p 2222" user@hostname
</pre>
</pre>


==== Setup SSH Keys ====
'''Why Mosh:'''
* Survives IP changes and sleep/wake
* Local echo for instant feedback
* UDP-based, handles packet loss
 
== Troubleshooting ==
 
=== Connection Refused ===
<pre>
<pre>
# Generate key if needed
# Check if SSH is running
ls ~/.ssh/id_rsa.pub || ssh-keygen -t rsa -b 4096
sudo systemctl status ssh     # Linux
sudo systemsetup -getremotelogin  # macOS


# Copy key to target Mac
# Check if port is open
ssh-copy-id [email protected]
nc -zv hostname 22
 
# Firewall issues
sudo ufw status                # UFW
sudo iptables -L -n          # iptables
</pre>
</pre>


==== Create SSH Config ====
=== Permission Denied ===
Add to <code>~/.ssh/config</code>:
<pre>
<pre>
Host imac
# Fix key permissions (must be restrictive)
    HostName 192.168.1.XXX
chmod 700 ~/.ssh
    User username
chmod 600 ~/.ssh/id_*
    ServerAliveInterval 30
chmod 644 ~/.ssh/id_*.pub
    ServerAliveCountMax 3
chmod 600 ~/.ssh/authorized_keys
 
# Debug connection
ssh -vvv user@hostname
</pre>
</pre>


Now connect with: <code>ssh imac</code>
=== Host Key Changed ===
<pre>
# Remove old host key
ssh-keygen -R hostname


=== For Unstable Connections ===
# Or edit ~/.ssh/known_hosts manually
</pre>


==== Install Mosh ====
=== Slow Connection ===
On both machines:
<pre>
<pre>
brew install mosh
# Often DNS-related, disable reverse lookup on server
# Add to /etc/ssh/sshd_config:
UseDNS no
</pre>
</pre>


Connect with: <code>mosh [email protected]</code>
== Advanced Techniques ==
 
=== SSH Agent ===
<pre>
# Start agent
eval $(ssh-agent -s)


=== Troubleshooting ===
# Add key
ssh-add ~/.ssh/id_ed25519


==== SSH Connection Refused ====
# List loaded keys
ssh-add -l
</pre>
 
=== Multiplexing ===
Speed up multiple connections to same host:
<pre>
<pre>
# Check if SSH is running
# Add to ~/.ssh/config
sudo systemsetup -getremotelogin
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600
</pre>
 
=== Run Remote Commands ===
<pre>
# Single command
ssh user@host 'ls -la /var/log'


# Force enable
# Multiple commands
sudo systemsetup -setremotelogin on
ssh user@host 'cd /app && git pull && pm2 restart all'


# Check firewall
# With sudo
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate
ssh -t user@host 'sudo systemctl restart nginx'
</pre>
</pre>


==== WiFi Keepalive Script ====
=== Copy with Progress ===
<pre>
<pre>
cat > ~/keepalive.sh << 'EOF'
# rsync with progress
#!/bin/bash
rsync -avz --progress largefile.tar.gz user@host:/path/
while true; do
    ping -c 1 192.168.1.1  # Router IP
    sleep 30
done
EOF


chmod +x ~/keepalive.sh
# scp with compression
nohup ~/keepalive.sh &
scp -C largefile.tar.gz user@host:/path/
</pre>
</pre>
== Related ==
* [[VPS]] - Server administration
* [[Dotfiles]] - Shell configuration
* [[PGP]] - Key management


[[Category:SSH]]
[[Category:SSH]]
[[Category:macOS]]
[[Category:Networking]]
[[Category:Networking]]
[[Category:Security]]
[[Category:System Administration]]


{{Navbox Technical}}
{{Navbox Technical}}

Latest revision as of 05:31, 15 January 2026

SSH

File:OpenSSH logo.png
OpenSSH - secure shell protocol

SSH (Secure Shell) is the fundamental protocol for secure remote access. Essential for server administration, development workflows, and secure file transfer.

Quick Reference

Task Command
Connect ssh user@host
Copy file to remote scp file.txt user@host:/path/
Copy file from remote scp user@host:/path/file.txt .
Sync directories rsync -avz dir/ user@host:/path/
Local port forward ssh -L 8080:localhost:80 user@host
Remote port forward ssh -R 9090:localhost:3000 user@host
SOCKS proxy ssh -D 1080 user@host

SSH Key Setup

Generate Keys

# Modern Ed25519 (recommended)
ssh-keygen -t ed25519 -C "[email protected]"

# RSA 4096-bit (legacy compatibility)
ssh-keygen -t rsa -b 4096 -C "[email protected]"

Copy Key to Server

# Automatic method
ssh-copy-id user@hostname

# Manual method
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

SSH Config

The config file (~/.ssh/config) eliminates repetitive typing:

# Personal VPS
Host vps
    HostName 123.45.67.89
    User debian
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 30
    ServerAliveCountMax 3

# Jump through bastion
Host internal-server
    HostName 10.0.0.50
    User admin
    ProxyJump bastion

# Bastion/jump host
Host bastion
    HostName bastion.example.com
    User jumpuser
    IdentityFile ~/.ssh/bastion_key

# Wildcard for work servers
Host *.work.example.com
    User workuser
    IdentityFile ~/.ssh/work_key
    ForwardAgent yes

Useful options:

  • ServerAliveInterval 30 - Keep connection alive
  • ServerAliveCountMax 3 - Retry 3 times before disconnect
  • ProxyJump host - Jump through another host
  • ForwardAgent yes - Forward SSH agent (use carefully)
  • LocalForward 8080 localhost:80 - Persistent port forward
  • Compression yes - Enable compression

Port Forwarding

Local Forward

Access remote service locally:

# Access remote PostgreSQL on localhost:5433
ssh -L 5433:localhost:5432 user@dbserver

# Access internal web app
ssh -L 8080:internal-app:80 user@bastion

Remote Forward

Expose local service to remote:

# Let remote server access your local dev server
ssh -R 9000:localhost:3000 user@remote

# Expose to all interfaces (requires GatewayPorts yes on server)
ssh -R 0.0.0.0:9000:localhost:3000 user@remote

Dynamic Forward (SOCKS Proxy)

# Create SOCKS5 proxy
ssh -D 1080 user@host

# Use with curl
curl --socks5 localhost:1080 https://example.com

macOS Setup

Enable SSH Server

  • macOS Ventura+: System Settings → General → Sharing → "Remote Login" ON
  • Older macOS: System Preferences → Sharing → "Remote Login"

Prevent Sleep (for always-on Mac)

sudo pmset -c sleep 0
sudo pmset -c disablesleep 1
sudo pmset -c womp 1  # Wake on network

Keychain Integration

Add to ~/.ssh/config:

Host *
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519

Linux/Debian Server Setup

Install and Enable

sudo apt update && sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh

Harden SSH

Edit /etc/ssh/sshd_config:

# Disable password auth (keys only)
PasswordAuthentication no
ChallengeResponseAuthentication no

# Disable root login
PermitRootLogin no

# Limit users
AllowUsers debian

# Change port (optional security through obscurity)
# Port 2222

# Timeout settings
ClientAliveInterval 300
ClientAliveCountMax 2

Apply changes: sudo systemctl reload ssh

Mosh (Mobile Shell)

For unstable connections (WiFi, mobile, high latency):

# Install (both client and server)
brew install mosh     # macOS
sudo apt install mosh # Debian

# Connect
mosh user@hostname

# With custom port
mosh --ssh="ssh -p 2222" user@hostname

Why Mosh:

  • Survives IP changes and sleep/wake
  • Local echo for instant feedback
  • UDP-based, handles packet loss

Troubleshooting

Connection Refused

# Check if SSH is running
sudo systemctl status ssh      # Linux
sudo systemsetup -getremotelogin  # macOS

# Check if port is open
nc -zv hostname 22

# Firewall issues
sudo ufw status                # UFW
sudo iptables -L -n           # iptables

Permission Denied

# Fix key permissions (must be restrictive)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/id_*.pub
chmod 600 ~/.ssh/authorized_keys

# Debug connection
ssh -vvv user@hostname

Host Key Changed

# Remove old host key
ssh-keygen -R hostname

# Or edit ~/.ssh/known_hosts manually

Slow Connection

# Often DNS-related, disable reverse lookup on server
# Add to /etc/ssh/sshd_config:
UseDNS no

Advanced Techniques

SSH Agent

# Start agent
eval $(ssh-agent -s)

# Add key
ssh-add ~/.ssh/id_ed25519

# List loaded keys
ssh-add -l

Multiplexing

Speed up multiple connections to same host:

# Add to ~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 600

Run Remote Commands

# Single command
ssh user@host 'ls -la /var/log'

# Multiple commands
ssh user@host 'cd /app && git pull && pm2 restart all'

# With sudo
ssh -t user@host 'sudo systemctl restart nginx'

Copy with Progress

# rsync with progress
rsync -avz --progress largefile.tar.gz user@host:/path/

# scp with compression
scp -C largefile.tar.gz user@host:/path/
  • VPS - Server administration
  • Dotfiles - Shell configuration
  • PGP - Key management


Technical
Core Technical · CLI · Dotfiles · Nvim · SSH · VPS
Tools Sketchybar · ArchiveBox · ThinkPad Linux
Systems Automation · Personal APIs · Quantified Self
Reference Runbooks · New Computer Runbook · Syntax guide