What is SSH?
SSH (Secure Shell) is a protocol for secure remote access:
- Encrypted connections
- Remote command execution
- File transfer
- Tunneling
Basic Connection
Connect to a Server
# Basic connection
ssh user@hostname
# With port
ssh -p 2222 user@hostname
# With identity file
ssh -i ~/.ssh/my_key user@hostname
First Connection
On first connect, you'll see:
The authenticity of host 'hostname' can't be established.
ED25519 key fingerprint is SHA256:xxx...
Are you sure you want to continue connecting (yes/no)?
Type yes to add to known hosts.
SSH Keys
Why Keys?
Keys are more secure than passwords:
- No password to intercept
- Harder to brute force
- Can be managed centrally
- Can be revoked
Generate Keys
# Generate Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Generate RSA key (wider compatibility)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Output:
~/.ssh/id_ed25519 # Private key (keep secret!)
~/.ssh/id_ed25519.pub # Public key (share this)
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"
Key Permissions
# Private key: owner only
chmod 600 ~/.ssh/id_ed25519
# Public key: can be readable
chmod 644 ~/.ssh/id_ed25519.pub
# .ssh directory
chmod 700 ~/.ssh
SSH Config
Config File
~/.ssh/config simplifies connections:
# Default settings for all hosts
Host *
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
# Specific host
Host myserver
HostName server.example.com
User admin
Port 2222
# Jump host
Host internal
HostName 192.168.1.100
User admin
ProxyJump bastion
# Bastion/jump server
Host bastion
HostName bastion.example.com
User admin
Using Config
# Instead of
ssh -p 2222 admin@server.example.com
# Just use
ssh myserver
Common Operations
Execute Remote Command
# Single command
ssh user@host "ls -la /var/log"
# Multiple commands
ssh user@host "cd /app && git pull && npm restart"
File Transfer with SCP
# Copy to remote
scp file.txt user@host:/path/to/destination/
# Copy from remote
scp user@host:/path/to/file.txt ./local/
# Copy directory
scp -r ./directory user@host:/path/
File Transfer with rsync
Better for large transfers:
# Sync directory
rsync -avz ./local/ user@host:/remote/
# With delete (mirror)
rsync -avz --delete ./local/ user@host:/remote/
# Exclude patterns
rsync -avz --exclude "*.log" ./local/ user@host:/remote/
Tunneling
Local Port Forward
Access remote service locally:
# Forward local 8080 to remote localhost:80
ssh -L 8080:localhost:80 user@host
# Forward to another host through SSH server
ssh -L 8080:database.internal:5432 user@bastion
Now localhost:8080 reaches the remote service.
Remote Port Forward
Expose local service remotely:
# Forward remote 8080 to local 3000
ssh -R 8080:localhost:3000 user@host
Dynamic (SOCKS Proxy)
# Create SOCKS proxy on local port 9999
ssh -D 9999 user@host
# Use with curl
curl --socks5 localhost:9999 http://internal-site.com
SSH Agent
What It Does
Holds your keys in memory, avoiding repeated passphrase entry.
Using the Agent
# Start agent
eval "$(ssh-agent -s)"
# Add key
ssh-add ~/.ssh/id_ed25519
# List keys
ssh-add -l
# Remove all keys
ssh-add -D
Agent Forwarding
Use your local keys on remote servers:
ssh -A user@host
Or in config:
Host myserver
ForwardAgent yes
Caution: Only forward to trusted hosts.
Security Best Practices
Server Configuration
In /etc/ssh/sshd_config:
# Disable password auth
PasswordAuthentication no
# Disable root login
PermitRootLogin no
# Use key auth only
PubkeyAuthentication yes
# Change default port (security through obscurity)
Port 2222
Client Practices
- Use strong passphrases on keys
- Don't share private keys
- Use different keys for different purposes
- Regularly rotate keys
- Remove unused keys from servers
Fail2Ban
Protect against brute force:
# Install
apt install fail2ban
# Default config protects SSH
Troubleshooting
Verbose Mode
# Debug connection issues
ssh -v user@host
# More verbose
ssh -vv user@host
# Maximum verbosity
ssh -vvv user@host
Common Issues
Permission denied:
- Check key permissions (
chmod 600) - Verify key is in authorized_keys
- Check server config
Connection refused:
- SSH service not running
- Firewall blocking
- Wrong port
Host key verification failed:
- Server changed
- Man-in-the-middle attack
- Remove old key:
ssh-keygen -R hostname
Check SSH Service
# Status
systemctl status sshd
# Restart
sudo systemctl restart sshd
# Check logs
sudo journalctl -u sshd
Useful Commands
Keep Connection Alive
In ~/.ssh/config:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Escape Sequences
While connected, press ~:
~. Disconnect
~? Help
~# List forwarded connections
~C Command line (add forwards)
Background SSH
# Start in background
ssh -fN -L 8080:localhost:80 user@host
# Find and kill
ps aux | grep ssh
kill <pid>
Conclusion
SSH essentials:
- Use keys, not passwords
- Configure
~/.ssh/config - Use tunnels for secure access
- Follow security best practices
SSH is foundational for remote system access.
Next: Systemd Basics - Managing Linux services