SSH: Secure Shell Protocol Complete Guide
SSH (Secure Shell) is a cryptographic network protocol for secure remote access, file transfer, and network services over unsecured networks. SSH has become the standard for secure remote administration, replacing insecure protocols like Telnet and rlogin. This comprehensive guide explains SSH, its features, configuration, and best practices.
What is SSH?
SSH is a protocol that provides secure encrypted communication between two computers over an insecure network. It uses strong cryptography to authenticate users and encrypt all traffic, including passwords, commands, and data.
SSH Basics
Protocol characteristics:
Layer: Application layer (Layer 7)
Transport: TCP
Port: 22 (default)
Encryption: Strong cryptography
Authentication: Multiple methods
Purpose: Remote access, file transfer, tunneling
SSH replaces:
Telnet: Unencrypted remote access
rlogin: Unencrypted remote login
rsh: Unencrypted remote shell
FTP: Unencrypted file transfer
Learn more about FTP and SSL/TLS.
SSH versions:
SSH-1: Original, deprecated (insecure)
SSH-2: Current standard, secure
Status: Only use SSH-2
How SSH Works
SSH Connection Process
Connection establishment:
1. Client connects to server (port 22)
2. Server sends public key
3. Client verifies server identity
4. Negotiate encryption algorithms
5. Establish encrypted connection
6. User authentication
7. Secure session established
Encryption layers: ``` Transport Layer: - Server authentication - Encryption - Integrity
User Authentication Layer: - Password - Public key - Keyboard-interactive
Connection Layer: - Multiplexing - Channel management ```
SSH Authentication Methods
Password authentication: ``` Process: 1. User enters password 2. Password sent encrypted 3. Server verifies password 4. Access granted or denied
Security: Weakest method Risk: Brute force attacks Recommendation: Disable for production ```
Public key authentication: ``` Process: 1. User has key pair (public/private) 2. Public key on server 3. Server sends challenge 4. Client signs with private key 5. Server verifies with public key 6. Access granted
Security: Strong Advantages: No password transmission Recommendation: Preferred method ```
Keyboard-interactive: ``` Process: 1. Server sends prompts 2. User responds 3. Can include multiple factors 4. Flexible authentication
Use cases: - Two-factor authentication - One-time passwords - Custom challenges ```
Host-based authentication: ``` Process: 1. Client host authenticated 2. Based on host keys 3. User trusted from that host
Use: Automated systems Security: Less common ```
SSH Key Management
Generating SSH Keys
RSA keys (traditional): ```bash
Generate RSA key (2048-bit minimum, 4096-bit recommended)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Output:
Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Your identification has been saved in /home/user/.ssh/id_rsa Your public key has been saved in /home/user/.ssh/id_rsa.pub ```
Ed25519 keys (modern, recommended): ```bash
Generate Ed25519 key (faster, more secure)
ssh-keygen -t ed25519 -C "your_email@example.com"
Advantages:
- Smaller key size
- Faster
- More secure
- Modern standard ```
ECDSA keys: ```bash
Generate ECDSA key
ssh-keygen -t ecdsa -b 521 -C "your_email@example.com"
Note: Ed25519 preferred over ECDSA
```
Key files:
Private key: ~/.ssh/id_ed25519 (keep secret!)
Public key: ~/.ssh/id_ed25519.pub (share this)
Permissions: 600 for private, 644 for public
Deploying Public Keys
Copy to server: ```bash
Easiest method
ssh-copy-id user@server.com
Manual method
cat ~/.ssh/id_ed25519.pub | ssh user@server.com "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Or copy-paste
cat ~/.ssh/id_ed25519.pub
Copy output, then on server:
echo "paste-public-key-here" >> ~/.ssh/authorized_keys ```
Authorized keys file:
Location: ~/.ssh/authorized_keys
Permissions: 600
Format: One public key per line
Multiple keys: ```bash
authorized_keys can contain multiple keys
ssh-rsa AAAAB3... user1@host1 ssh-ed25519 AAAAC3... user2@host2 ssh-rsa AAAAB3... user3@host3 ```
Key Passphrases
Purpose:
Protect private key
Additional security layer
Required if key stolen
Using ssh-agent: ```bash
Start ssh-agent
eval "$(ssh-agent -s)"
Add key (enter passphrase once)
ssh-add ~/.ssh/id_ed25519
List loaded keys
ssh-add -l
Remove all keys
ssh-add -D ```
Keychain (persistent): ```bash
Install keychain
sudo apt install keychain
Add to ~/.bashrc
eval $(keychain --eval id_ed25519)
Keys loaded on login
```
SSH Client Usage
Basic Connection
Connect to server: ```bash
Basic connection
ssh user@server.com
Specify port
ssh -p 2222 user@server.com
Specify key
ssh -i ~/.ssh/custom_key user@server.com
Verbose output (debugging)
ssh -v user@server.com ssh -vv user@server.com # More verbose ssh -vvv user@server.com # Maximum verbosity ```
First connection: ``` The authenticity of host 'server.com (203.0.113.1)' can't be established. ED25519 key fingerprint is SHA256:abc123... Are you sure you want to continue connecting (yes/no)?
Type: yes Result: Host added to ~/.ssh/known_hosts ```
SSH Config File
Location: ~/.ssh/config
Basic configuration: ``` Host myserver HostName server.example.com User alice Port 22 IdentityFile ~/.ssh/id_ed25519
Host github HostName github.com User git IdentityFile ~/.ssh/github_key
Host * ServerAliveInterval 60 ServerAliveCountMax 3 ```
Usage: ```bash
Instead of: ssh alice@server.example.com
ssh myserver
Instead of: ssh git@github.com
ssh github ```
Advanced options: ``` Host production HostName prod.example.com User admin Port 2222 IdentityFile ~/.ssh/prod_key ForwardAgent yes Compression yes LogLevel INFO
Host *.internal ProxyJump bastion.example.com User internal_user ```
Remote Command Execution
Run single command: ```bash
Execute command and exit
ssh user@server.com "ls -la"
Multiple commands
ssh user@server.com "cd /var/log && tail -n 20 syslog"
With sudo
ssh user@server.com "sudo systemctl restart nginx" ```
Script execution: ```bash
Run local script on remote server
ssh user@server.com 'bash -s' < local_script.sh
With arguments
ssh user@server.com 'bash -s' < script.sh arg1 arg2 ```
Here document:
bash
ssh user@server.com << 'EOF'
cd /var/www
git pull
npm install
pm2 restart app
EOF
SSH File Transfer
SCP (Secure Copy)
Upload file: ```bash
Single file
scp file.txt user@server.com:/path/to/destination/
Multiple files
scp file1.txt file2.txt user@server.com:/path/
Directory (recursive)
scp -r directory/ user@server.com:/path/ ```
Download file: ```bash
Single file
scp user@server.com:/path/to/file.txt .
Multiple files
scp user@server.com:/path/to/*.txt .
Directory
scp -r user@server.com:/path/to/directory/ . ```
Options: ```bash
Preserve timestamps and permissions
scp -p file.txt user@server.com:/path/
Limit bandwidth (KB/s)
scp -l 1000 file.txt user@server.com:/path/
Specify port
scp -P 2222 file.txt user@server.com:/path/
Compression
scp -C largefile.tar user@server.com:/path/ ```
SFTP (SSH File Transfer Protocol)
Interactive session: ```bash
Connect
sftp user@server.com
Commands
sftp> ls # List remote files sftp> lls # List local files sftp> pwd # Remote directory sftp> lpwd # Local directory sftp> cd /path # Change remote directory sftp> lcd /path # Change local directory sftp> get file.txt # Download file sftp> put file.txt # Upload file sftp> get -r directory/ # Download directory sftp> put -r directory/ # Upload directory sftp> mkdir newdir # Create remote directory sftp> rm file.txt # Delete remote file sftp> exit # Quit ```
Batch mode: ```bash
Execute commands from file
sftp -b commands.txt user@server.com
commands.txt:
cd /var/www put index.html put style.css quit ```
rsync over SSH
Sync directories: ```bash
Basic sync
rsync -avz /local/dir/ user@server.com:/remote/dir/
Options:
-a: Archive mode (preserves permissions, timestamps) -v: Verbose -z: Compression -P: Progress and partial transfers --delete: Delete files not in source
Exclude files
rsync -avz --exclude '*.log' /local/ user@server.com:/remote/
Dry run (test)
rsync -avz --dry-run /local/ user@server.com:/remote/ ```
Advantages over scp:
Only transfers changes
Resume capability
Compression
Exclude patterns
Preserves permissions
Faster for updates
SSH Tunneling and Port Forwarding
Local Port Forwarding
Forward local port to remote: ```bash
Syntax
ssh -L local_port:destination:destination_port user@ssh_server
Example: Access remote database
ssh -L 3306:localhost:3306 user@database-server.com
Now connect to localhost:3306 → remote MySQL
Access service on different host
ssh -L 8080:internal-server:80 user@bastion.com
localhost:8080 → internal-server:80 via bastion
```
Use cases:
Access remote database
Bypass firewall
Secure unencrypted protocols
Access internal services
Remote Port Forwarding
Forward remote port to local: ```bash
Syntax
ssh -R remote_port:destination:destination_port user@ssh_server
Example: Share local web server
ssh -R 8080:localhost:80 user@public-server.com
public-server.com:8080 → your localhost:80
Expose local service
ssh -R 3000:localhost:3000 user@server.com ```
Use cases:
Expose local development server
Share local service temporarily
Bypass NAT/firewall
Remote access to local machine
Dynamic Port Forwarding (SOCKS Proxy)
Create SOCKS proxy: ```bash
Start SOCKS proxy on local port
ssh -D 1080 user@server.com
Configure browser/application to use:
SOCKS5 proxy: localhost:1080
All traffic routed through SSH tunnel
```
Use cases:
Secure browsing on public WiFi
Bypass geographic restrictions
Encrypt all traffic
Access region-locked content
Browser configuration:
Firefox:
Settings → Network Settings → Manual proxy
SOCKS Host: localhost
Port: 1080
SOCKS v5: Yes
SSH Jump Host (ProxyJump)
Access through bastion: ```bash
Old method
ssh -J bastion.com user@internal-server
Or
ssh -o ProxyJump=bastion.com user@internal-server
Multiple jumps
ssh -J bastion1.com,bastion2.com user@internal-server ```
Config file:
Host internal
HostName internal-server.local
User admin
ProxyJump bastion.example.com
SSH Server Configuration
Installation
Debian/Ubuntu:
bash
sudo apt update
sudo apt install openssh-server
RHEL/CentOS:
bash
sudo yum install openssh-server
Start service:
bash
sudo systemctl start sshd
sudo systemctl enable sshd
Configuration File
Location: /etc/ssh/sshd_config
Basic hardening: ```
Port (change from default)
Port 2222
Protocol
Protocol 2
Authentication
PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes PermitEmptyPasswords no
Security
X11Forwarding no MaxAuthTries 3 MaxSessions 10 LoginGraceTime 60
Logging
SyslogFacility AUTH LogLevel VERBOSE
Allow specific users
AllowUsers alice bob
Or allow specific groups
AllowGroups sshusers ```
Apply changes: ```bash
Test configuration
sudo sshd -t
Restart service
sudo systemctl restart sshd ```
Security Best Practices
1. Disable password authentication:
PasswordAuthentication no
ChallengeResponseAuthentication no
2. Disable root login:
PermitRootLogin no
3. Change default port: ``` Port 2222
Security through obscurity (minor benefit)
Reduces automated attacks
```
4. Limit users: ``` AllowUsers alice bob
Or
AllowGroups sshusers ```
5. Use fail2ban: ```bash
Install
sudo apt install fail2ban
Configure /etc/fail2ban/jail.local
[sshd] enabled = true port = 22 filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 3600 ```
6. Two-factor authentication: ```bash
Install Google Authenticator
sudo apt install libpam-google-authenticator
Configure PAM
/etc/pam.d/sshd
auth required pam_google_authenticator.so
/etc/ssh/sshd_config
ChallengeResponseAuthentication yes AuthenticationMethods publickey,keyboard-interactive ```
7. Keep updated:
bash
sudo apt update
sudo apt upgrade openssh-server
Advanced SSH Features
SSH Agent Forwarding
Purpose:
Use local SSH keys on remote servers
Access further servers without copying keys
Convenient for jump hosts
Enable: ```bash
Command line
ssh -A user@server.com
Config file
Host server ForwardAgent yes ```
Security warning:
Risk: Admin on intermediate server can use your keys
Use: Only on trusted servers
Alternative: ProxyJump (more secure)
SSH Multiplexing
Purpose:
Reuse existing connection
Faster subsequent connections
Reduce overhead
Configuration:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h:%p
ControlPersist 10m
Create socket directory:
bash
mkdir -p ~/.ssh/sockets
Benefits:
First connection: Normal
Subsequent: Instant (reuses connection)
Persist: Stays open for 10 minutes
SSH Escape Sequences
During session:
~. : Disconnect
~^Z : Background SSH
~# : List forwarded connections
~& : Background SSH at logout
~? : Help
Usage:
Press Enter, then ~.
Immediately disconnects
Useful for hung connections
Troubleshooting SSH
Connection Issues
Connection refused:
Check: SSH service running
Check: Firewall rules
Check: Correct port
Test: telnet server.com 22
Connection timeout:
Check: Network connectivity
Check: Firewall blocking
Check: Server reachable
Test: ping server.com
Permission denied:
Check: Username correct
Check: Key permissions (600 for private)
Check: authorized_keys permissions (600)
Check: Home directory permissions (755)
Verbose: ssh -vvv user@server.com
Authentication Issues
Public key not working:
Check: Public key in authorized_keys
Check: File permissions
Check: SELinux (if enabled)
Check: sshd_config allows PubkeyAuthentication
Debug: ssh -vvv user@server.com
Permissions: ```bash
Fix permissions
chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub ```
Host key verification failed: ``` Warning: REMOTE HOST IDENTIFICATION HAS CHANGED!
Causes: - Server reinstalled - Man-in-the-middle attack - IP address reused
Fix (if legitimate): ssh-keygen -R server.com
Or edit ~/.ssh/known_hosts
```
Performance Issues
Slow connection: ``` Cause: DNS lookup Fix: UseDNS no in sshd_config
Cause: GSSAPI authentication Fix: GSSAPIAuthentication no
Cause: Network latency Test: ssh -v to see delays ```
Slow file transfer:
Enable compression: scp -C
Use rsync: More efficient
Check network: Bandwidth limits
SSH Best Practices
Client-Side
1. Use SSH keys:
Generate strong keys (Ed25519 or RSA 4096)
Use passphrases
Use ssh-agent
2. Configure SSH config:
Organize connections
Set defaults
Use aliases
3. Verify host keys:
Check fingerprints on first connection
Don't blindly accept
Compare with known good value
4. Use ProxyJump:
Safer than agent forwarding
Access internal servers
Cleaner than manual tunneling
Server-Side
1. Harden configuration:
Disable password authentication
Disable root login
Change default port (optional)
Limit users
2. Monitor logs:
Watch for failed attempts
Detect brute force
Investigate anomalies
3. Use fail2ban:
Automatic IP blocking
Reduce brute force attempts
Configurable thresholds
4. Keep updated:
Regular security updates
Monitor CVEs
Test updates in staging
5. Regular audits:
Review authorized_keys
Check user accounts
Verify permissions
Review logs
Conclusion
SSH is the standard for secure remote access and file transfer, providing strong encryption, flexible authentication, and powerful features like tunneling and port forwarding. Proper SSH configuration with key-based authentication, disabled password login, and security hardening is essential for secure server management.
Related Articles
Secure Protocols
- SSL/TLS - TLS encryption
- FTP - SFTP uses SSH
- HTTP vs HTTPS - Web security
- VPN Basics - VPN tunneling
Network Concepts
- Port Forwarding - SSH tunneling
- TCP/IP Model - Protocol stack
- Firewall Basics - SSH access control
- Default Gateway - Remote access
Security
- IP Blacklisting - SSH brute force protection
- IP Spoofing - SSH security
- Network Scanning - SSH port scanning
Explore More
- Protocols - Internet protocols hub
- Security & Privacy - Security resources
Key takeaways: - SSH provides encrypted remote access - Port 22 (default), customizable - Key-based authentication preferred - Disable password authentication - Use Ed25519 or RSA 4096 keys - SSH config simplifies connections - SCP/SFTP for secure file transfer - Port forwarding for tunneling - Harden server configuration - Monitor and update regularly
Bottom line: SSH is indispensable for secure server administration. Always use key-based authentication, disable password login on production servers, keep SSH updated, and follow security best practices. Proper SSH configuration protects against unauthorized access while providing convenient and secure remote management capabilities.