SSH (Secure Shell Protocol) is a cryptographic network protocol for secure remote access to systems and services.
Table of Contents
- What is SSH?
- SSH Server Setup
- SSH Client Setup
- SSH Authentication Methods
- Setting Up SSH Keys
- Password Authentication
- SSH Configuration
- Advanced SSH Features
- Security Best Practices
- Troubleshooting
What is SSH?
SSH operates on a client-server model:
- SSH Server (sshd): Runs on the remote machine
- SSH Client (ssh): Runs on your local machine
Key benefits: encryption, authentication, integrity, port forwarding.
SSH Server Setup
Installing SSH Server
Ubuntu/Debian:
sudo apt update && sudo apt install openssh-server
sudo systemctl start ssh && sudo systemctl enable ssh
sudo systemctl status ssh
CentOS/RHEL:
sudo yum install openssh-server # RHEL 7
sudo dnf install openssh-server # RHEL 8+
sudo systemctl start sshd && sudo systemctl enable sshd
sudo systemctl status sshd
Fedora:
sudo dnf install openssh-server
sudo systemctl start sshd && sudo systemctl enable sshd
sudo systemctl status sshd
Arch Linux:
sudo pacman -S openssh
sudo systemctl start sshd && sudo systemctl enable sshd
sudo systemctl status sshd
Basic SSH Server Configuration
Backup original config:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
Edit configuration:
sudo nano /etc/ssh/sshd_config
Essential settings:
Port 22
Protocol 2
PermitRootLogin no
MaxAuthTries 3
MaxSessions 2
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
PermitEmptyPasswords no
X11Forwarding no
PrintMotd no
SyslogFacility AUTH
LogLevel INFO
Test and restart:
sudo sshd -t
sudo systemctl restart sshd
Firewall Configuration
UFW (Ubuntu/Debian):
sudo ufw allow ssh
sudo ufw enable
Firewalld (CentOS/RHEL/Fedora):
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
UFW on Arch:
sudo pacman -S ufw
sudo ufw allow ssh
sudo ufw enable
SSH Client Setup
Installing SSH Client
Ubuntu/Debian:
sudo apt install openssh-client
CentOS/RHEL/Fedora:
sudo yum install openssh-clients # RHEL 7
sudo dnf install openssh-clients # RHEL 8+/Fedora
Arch Linux:
sudo pacman -S openssh
Basic SSH Client Usage
# Basic connection
ssh username@server_ip
# Custom port
ssh -p 2222 username@server_ip
# Specific private key
ssh -i ~/.ssh/private_key username@server_ip
# Execute command
ssh user@server 'ls -la'
SSH Authentication Methods
Password Authentication
Simple username/password method. Less secure but universally supported.
Public Key Authentication
Uses asymmetric cryptography. More secure and can be automated.
Setting Up SSH Keys
Step 1: Generate SSH Key Pair
Check existing keys:
ls -la ~/.ssh/
Generate new key (Ed25519 recommended):
ssh-keygen -t ed25519 -C "your_email@example.com"
For legacy systems (RSA):
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Step 2: Set Proper Permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 # Private key
chmod 644 ~/.ssh/id_ed25519.pub # Public key
Step 3: Copy Public Key to Server
Method 1: ssh-copy-id (Easiest)
ssh-copy-id username@server_ip
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@server_ip
Method 2: Manual Copy (Detailed Steps)
On your local machine:
# Display your public key
cat ~/.ssh/id_ed25519.pub
Copy the entire output (starts with ssh-ed25519
and ends with your comment).
On the server:
# Create SSH directory
mkdir -p ~/.ssh
# Create or edit authorized_keys file
nano ~/.ssh/authorized_keys
Paste your public key as a single line in the authorized_keys file. Each key should be on its own line.
Example authorized_keys content:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILw...rest_of_key...xyz user@laptop
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC...rest_of_key...abc user@desktop
Set proper permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Method 3: One-liner Command
cat ~/.ssh/id_ed25519.pub | ssh username@server_ip "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Step 4: Test SSH Key Authentication
ssh username@server_ip
Should connect without password prompt.
Step 5: Disable Password Authentication (Optional)
sudo nano /etc/ssh/sshd_config
Change:
PasswordAuthentication no
ChallengeResponseAuthentication no
Restart SSH:
sudo systemctl restart sshd
Password Authentication
Server Configuration
# In /etc/ssh/sshd_config
PasswordAuthentication yes
PermitEmptyPasswords no
Client Usage
ssh username@server_ip
# Force password auth
ssh -o PreferredAuthentications=password username@server_ip
SSH Configuration
Client Config File (~/.ssh/config)
touch ~/.ssh/config
chmod 600 ~/.ssh/config
Example configuration:
# Global defaults
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# Production server
Host prod
HostName production.example.com
User admin
Port 2222
IdentityFile ~/.ssh/prod_key
# Development server
Host dev
HostName 192.168.1.100
User developer
LocalForward 8080 localhost:80
# Jump host
Host internal
HostName 10.0.1.100
ProxyJump jumphost
Host jumphost
HostName jump.example.com
User jump_user
Usage:
ssh prod # Connects using prod alias
ssh dev # Connects using dev alias
Advanced SSH Features
SSH Agent
# Start agent
eval "$(ssh-agent -s)"
# Add keys
ssh-add
ssh-add ~/.ssh/id_ed25519
# List keys
ssh-add -l
# Remove keys
ssh-add -D
Port Forwarding
Local Port Forwarding
# Forward local port 8080 to server's port 80
ssh -L 8080:localhost:80 user@server
# Background process
ssh -f -N -L 8080:localhost:80 user@server
Remote Port Forwarding
# Forward server's port 8080 to local port 3000
ssh -R 8080:localhost:3000 user@server
SOCKS Proxy
ssh -D 1080 user@server
File Transfer
SFTP
sftp user@server
sftp> get file.txt
sftp> put file.txt
sftp> get -r directory/
SCP
# Upload
scp file.txt user@server:/path/
# Download
scp user@server:/path/file.txt ./
# Recursive
scp -r directory/ user@server:/path/
Security Best Practices
Server Hardening
# /etc/ssh/sshd_config
Port 2222
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
MaxSessions 2
AllowUsers user1 user2
X11Forwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
Key Management
Generate strong keys:
ssh-keygen -t ed25519 -a 100 -C "user@host-$(date +%Y%m%d)"
Rotate keys regularly and use SSH agent for convenience.
Monitoring
Check logs:
# Ubuntu/Debian
sudo tail -f /var/log/auth.log
# CentOS/RHEL/Fedora/Arch
sudo tail -f /var/log/secure
sudo journalctl -u sshd -f
Install Fail2Ban
Ubuntu/Debian:
sudo apt install fail2ban
CentOS/RHEL/Fedora:
sudo dnf install fail2ban
Arch Linux:
sudo pacman -S fail2ban
Configure SSH protection:
sudo nano /etc/fail2ban/jail.local
[sshd]
enabled = true
maxretry = 3
bantime = 3600
Troubleshooting
Common Issues
Connection Refused
# Check service
sudo systemctl status sshd
# Check port
sudo grep "^Port" /etc/ssh/sshd_config
# Check firewall
sudo ufw status
Permission Denied (publickey)
# Debug connection
ssh -v user@server
# Check agent
ssh-add -l
# Fix permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Host Key Verification Failed
# Remove old key
ssh-keygen -R hostname
Debugging
# Verbose output
ssh -vvv user@server
# Test config
sudo sshd -t
# Network test
nc -zv server_ip 22
Performance
Add to /etc/ssh/sshd_config:
UseDNS no
Add to ~/.ssh/config:
GSSAPIAuthentication no
Top comments (0)