ad placeholder image ad placeholder image

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

Network Concepts

Security

Explore More

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.

ad placeholder image ad placeholder image
Three funny piglies - an illustration ippigly.com