What Is SSH?
SSH (Secure Shell) is a cryptographic network protocol for securely accessing and managing remote servers over an unsecured network. Unlike FTP which only transfers files, SSH gives you a full command-line interface on the remote machine — you can edit files, restart services, view logs, manage databases, and do virtually anything the server can do.
SSH/SFTP encrypts everything — credentials and data. Gives you a full terminal. Runs on port 22.
FTP sends credentials in plain text (unless using FTPS). File transfers only. Runs on port 21.
For modern server management, SSH is always the preferred choice. See our FTP guide for when FTP is still necessary.
Connecting via SSH
The basic SSH connection command:
# Basic connection
ssh username@hostname
# Specify a custom port
ssh username@hostname -p 2222
# Connect to a server by IP
ssh root@192.168.1.100
# Connect with verbose output (for debugging)
ssh -v username@hostname
On Windows, you can use the built-in OpenSSH client (Windows 10+), PuTTY, or Windows Terminal. On macOS and Linux, SSH is built into the terminal.
SSH Key Authentication
Password authentication is convenient but vulnerable to brute-force attacks. SSH keys are significantly more secure — they use public-key cryptography to authenticate without sending a password over the network.
Generate an SSH Key Pair
# Generate a 4096-bit RSA key pair
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# Or use the newer Ed25519 algorithm (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"
# You'll be prompted for a save location and passphrase
# Default location: ~/.ssh/id_rsa or ~/.ssh/id_ed25519
Copy Your Public Key to the Server
# The easy way (Linux/macOS)
ssh-copy-id username@hostname
# Manual method (works everywhere)
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Test Key-Based Login
# Should connect without asking for password
ssh username@hostname
# If it still asks for a password, check permissions:
# ~/.ssh directory: 700
# ~/.ssh/authorized_keys: 600
Essential Linux Commands via SSH
Navigation & File Inspection
# Where am I?
pwd
# List files with details
ls -la
# List files sorted by modification time
ls -lt
# Change directory
cd /var/www/html
# Show disk usage of current directory
du -sh *
# Find files by name
find /var/www -name "*.php" -type f
File Operations
# Copy files
cp source.txt destination.txt
cp -r source_dir/ destination_dir/
# Move or rename
mv old_name.txt new_name.txt
# Delete files (use with caution!)
rm filename.txt
rm -rf directory_name/
# Create directories
mkdir -p /path/to/new/directory
# Edit files with nano (beginner-friendly)
nano /etc/nginx/nginx.conf
# Edit files with vim (powerful)
vim /etc/apache2/apache2.conf
Permissions & Ownership
# Change file permissions
chmod 644 file.txt # rw-r--r--
chmod 755 directory/ # rwxr-xr-x
chmod +x script.sh # Make executable
# Change ownership
chown www-data:www-data file.txt
chown -R www-data:www-data /var/www/html/
Service Management (systemd)
# Check service status
systemctl status nginx
systemctl status apache2
systemctl status mysql
# Start / Stop / Restart
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
# Reload config without downtime
systemctl reload nginx
# Enable service to start on boot
systemctl enable nginx
Log Viewing
# View last 50 lines of a log
tail -50 /var/log/apache2/error.log
# Watch a log in real-time
tail -f /var/log/nginx/access.log
# View systemd service logs
journalctl -u nginx --since "1 hour ago"
journalctl -u apache2 -f # follow in real-time
# Search logs for a pattern
grep "error" /var/log/syslog | tail -20
Process Management
# List all running processes
ps aux
# Find a specific process
ps aux | grep nginx
# Interactive process monitor
top
htop # (more user-friendly, may need to install)
# Kill a process by PID
kill 12345
kill -9 12345 # Force kill
SCP File Transfers
SCP (Secure Copy) lets you transfer files over SSH without needing a separate FTP connection:
# Upload a file to the server
scp local_file.txt user@host:/remote/path/
# Download a file from the server
scp user@host:/remote/path/file.txt ./local_destination/
# Upload an entire directory
scp -r local_directory/ user@host:/remote/path/
# Use a custom port
scp -P 2222 file.txt user@host:/path/
SSH Config File
Create ~/.ssh/config to save connection settings and connect with short aliases:
# ~/.ssh/config
Host myserver
HostName 192.168.1.100
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host production
HostName prod.example.com
User deploy
IdentityFile ~/.ssh/deploy_key
# Now you can simply type:
# ssh myserver
# ssh production
SSH Tunneling & Port Forwarding
SSH tunnels let you securely access remote services through an encrypted connection:
# Local port forwarding: access remote MySQL on localhost:3307
ssh -L 3307:localhost:3306 user@server
# Access a remote web panel on localhost:8080
ssh -L 8080:localhost:8080 user@server
# Dynamic SOCKS proxy (browse through the server)
ssh -D 9090 user@server
SSH Troubleshooting
- Permission denied (publickey) — your key isn't on the server or permissions are wrong on
~/.ssh(must be 700) andauthorized_keys(must be 600) - Connection refused — SSH service isn't running (
systemctl start sshd) or the port is blocked by a firewall - Connection timed out — wrong IP/hostname, network issue, or firewall blocking port 22
- Host key verification failed — the server's fingerprint changed (reinstall or IP change). Remove the old entry:
ssh-keygen -R hostname
Security Best Practices
Edit /etc/ssh/sshd_config and apply these settings:
# /etc/ssh/sshd_config
# Disable root login
PermitRootLogin no
# Disable password authentication (key-only)
PasswordAuthentication no
# Change default port (obscurity, not security alone)
Port 2222
# Allow only specific users
AllowUsers deploy admin
# Set idle timeout (disconnect after 10 min inactive)
ClientAliveInterval 300
ClientAliveCountMax 2
After editing, restart SSH: systemctl restart sshd
Additional security measures:
- Install fail2ban to automatically block IPs with too many failed login attempts
- Use UFW or iptables to restrict SSH access to specific IPs
- Set up two-factor authentication with Google Authenticator PAM module
- Keep your server's SSH software updated
# Install and enable fail2ban
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Basic UFW firewall setup
sudo ufw allow 2222/tcp # Allow SSH on custom port
sudo ufw enable
Always test your new SSH configuration in a separate terminal session before closing your current one. If something is misconfigured, you'll still have access through the existing connection to fix it.