Linux Server Administration Complete Guide Part 5: SSH and Remote Server Management
Master SSH for Secure Remote Access
Linux Server Administration Complete Guide Series
Part 4: Network & Firewall | Part 5: SSH & Remote Management (Current) | Part 6: Shell Script Basics
Introduction: SSH, The Core of Remote Server Management
SSH (Secure Shell) is a protocol for securely connecting to and managing remote servers over a network. It protects data through encrypted communication and is one of the most important tools in modern server operations. This part covers everything from SSH basics to advanced usage.
1. SSH Basics
1.1 Basic SSH Connection
# Basic connection
ssh username@hostname
# Connect on specific port
ssh -p 2222 username@hostname
# Connect by IP address
ssh user@192.168.1.100
# Verbose debug mode
ssh -v username@hostname
ssh -vvv username@hostname # More detailed info
1.2 SSH Server Installation and Status
# Ubuntu/Debian
sudo apt update
sudo apt install openssh-server
# RHEL/CentOS
sudo dnf install openssh-server
# Check SSH server status
sudo systemctl status sshd
# Start/Stop/Restart service
sudo systemctl start sshd
sudo systemctl stop sshd
sudo systemctl restart sshd
# Enable auto-start on boot
sudo systemctl enable sshd
1.3 Disconnecting SSH
# Normal exit
exit
logout
Ctrl + D
# Force disconnect when session is frozen
~. # Type Enter then ~.
2. SSH Key-Based Authentication
2.1 Generating Key Pair
# Generate RSA key (default)
ssh-keygen -t rsa -b 4096
# Generate Ed25519 key (recommended, more secure and faster)
ssh-keygen -t ed25519
# Generate with specific filename
ssh-keygen -t ed25519 -f ~/.ssh/myserver_key
# Add comment
ssh-keygen -t ed25519 -C "admin@company.com"
# Check generated files
ls -la ~/.ssh/
# id_ed25519 - Private key (never share)
# id_ed25519.pub - Public key (register on server)
2.2 Registering Public Key on Server
# Using ssh-copy-id (easiest method)
ssh-copy-id username@hostname
ssh-copy-id -i ~/.ssh/myserver_key.pub username@hostname
# Manual registration
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# Or directly on server
# Add public key content to ~/.ssh/authorized_keys
# Permission settings (important!)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
2.3 Key-Based Connection
# Connect with default key
ssh username@hostname
# Specify specific key
ssh -i ~/.ssh/myserver_key username@hostname
# Avoid passphrase prompt (ssh-agent)
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519
ssh-add -l # List registered keys
3. SSH Configuration Files
3.1 Client Configuration (~/.ssh/config)
# ~/.ssh/config example
# Web server
Host webserver
HostName 192.168.1.10
User admin
Port 22
IdentityFile ~/.ssh/webserver_key
# Development server (using alias)
Host dev
HostName dev.company.com
User developer
Port 2222
# DB server (via jump host)
Host dbserver
HostName 10.0.0.50
User dbadmin
ProxyJump webserver
# Common settings for all hosts
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
# Now simply connect with:
# ssh webserver
# ssh dev
3.2 Server Configuration (/etc/ssh/sshd_config)
# Key security settings
# Change port
Port 2222
# Disable root login
PermitRootLogin no
# Disable password authentication (key auth only)
PasswordAuthentication no
# Forbid empty passwords
PermitEmptyPasswords no
# Allow specific users only
AllowUsers admin deploy
# Allow specific groups only
AllowGroups sshusers
# Limit login attempts
MaxAuthTries 3
# Maximum sessions
MaxSessions 5
# Disable X11 forwarding
X11Forwarding no
# Apply settings
sudo sshd -t # Syntax check
sudo systemctl restart sshd
4. File Transfer: SCP and SFTP
4.1 SCP (Secure Copy)
# Local → Remote (file)
scp file.txt user@host:/path/to/destination/
# Local → Remote (directory)
scp -r mydir/ user@host:/path/to/destination/
# Remote → Local
scp user@host:/path/to/file.txt ./local/
# Use different port
scp -P 2222 file.txt user@host:/path/
# Use specific key
scp -i ~/.ssh/mykey file.txt user@host:/path/
# Compressed transfer (useful for large files)
scp -C largefile.zip user@host:/path/
# Bandwidth limit (KB/s)
scp -l 1000 file.txt user@host:/path/
# Server to server transfer
scp user1@host1:/file.txt user2@host2:/path/
4.2 SFTP (SSH File Transfer Protocol)
# SFTP connection
sftp user@host
sftp -P 2222 user@host
# SFTP commands
sftp> pwd # Remote current directory
sftp> lpwd # Local current directory
sftp> ls # Remote file list
sftp> lls # Local file list
sftp> cd /path # Change remote directory
sftp> lcd /path # Change local directory
sftp> get file.txt # Download
sftp> get -r dir/ # Download directory
sftp> put file.txt # Upload
sftp> put -r dir/ # Upload directory
sftp> rm file.txt # Delete
sftp> mkdir newdir # Create directory
sftp> exit # Exit
4.3 rsync over SSH
# Basic sync
rsync -avz source/ user@host:/destination/
# Sync with deleted files
rsync -avz --delete source/ user@host:/destination/
# Use different port
rsync -avz -e "ssh -p 2222" source/ user@host:/dest/
# Show progress
rsync -avz --progress source/ user@host:/dest/
# Test run (dry-run)
rsync -avzn source/ user@host:/dest/
5. SSH Tunneling (Port Forwarding)
5.1 Local Port Forwarding
Connect a local machine port to another server through the remote server.
# Syntax: ssh -L [local_port]:[target_host]:[target_port] [ssh_server]
# Example: Connect to remote DB via local 3306
ssh -L 3306:localhost:3306 user@sshserver
# Example: Access server behind remote server
ssh -L 8080:internal-web.lan:80 user@sshserver
# Run in background
ssh -fNL 3306:localhost:3306 user@sshserver
# Now connect to DB via localhost:3306
mysql -h localhost -P 3306 -u dbuser -p
5.2 Remote Port Forwarding
Connect a remote server port to the local machine.
# Syntax: ssh -R [remote_port]:[local_host]:[local_port] [ssh_server]
# Example: Forward remote 8080 to local 80
ssh -R 8080:localhost:80 user@sshserver
# External access to remote server's 8080 forwards to local 80
# Run in background
ssh -fNR 8080:localhost:80 user@sshserver
5.3 Dynamic Port Forwarding (SOCKS Proxy)
# Create SOCKS proxy
ssh -D 1080 user@sshserver
# Run in background
ssh -fND 1080 user@sshserver
# Configure SOCKS5 proxy in browser or application
# Proxy: localhost:1080
5.4 Jump Host (Proxy Jump)
# Using -J option (OpenSSH 7.3+)
ssh -J jumphost user@targetserver
# Multiple jump hosts
ssh -J jump1,jump2 user@target
# Legacy method (-o ProxyCommand)
ssh -o ProxyCommand="ssh -W %h:%p jumphost" user@target
# Configure in ~/.ssh/config
Host internal
HostName 10.0.0.50
User admin
ProxyJump jumphost
6. SSH Security Hardening
6.1 sshd_config Security Settings
# /etc/ssh/sshd_config
# Disable password authentication (key only)
PasswordAuthentication no
ChallengeResponseAuthentication no
# Forbid root login
PermitRootLogin no
# Forbid empty passwords
PermitEmptyPasswords no
# Disable keyboard interactive auth
KbdInteractiveAuthentication no
# Allow protocol version 2 only (default)
Protocol 2
# Limit login attempts
MaxAuthTries 3
LoginGraceTime 30
# Allow from specific IP only (sshd_config or firewall)
# AllowUsers admin@192.168.1.0/24
# Restrict TCP forwarding
AllowTcpForwarding no
AllowAgentForwarding no
# Allow only strong encryption algorithms
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# Syntax check before applying
sudo sshd -t
sudo systemctl restart sshd
6.2 Installing Fail2Ban
# Ubuntu/Debian
sudo apt install fail2ban
# RHEL/CentOS
sudo dnf install fail2ban
# Create config file
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log # Debian/Ubuntu
# logpath = /var/log/secure # RHEL/CentOS
maxretry = 3
bantime = 3600
findtime = 600
# Start service
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Check status
sudo fail2ban-client status sshd
6.3 Two-Factor Authentication (2FA)
# Install Google Authenticator
sudo apt install libpam-google-authenticator
# Initialize setup
google-authenticator
# PAM config (/etc/pam.d/sshd)
auth required pam_google_authenticator.so
# sshd_config settings
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
# Restart service
sudo systemctl restart sshd
7. SSH Agent and Key Management
7.1 Using SSH Agent
# Start agent
eval $(ssh-agent)
# Add keys
ssh-add # Default key
ssh-add ~/.ssh/mykey # Specific key
ssh-add -t 3600 ~/.ssh/key # Auto-remove after 1 hour
# List registered keys
ssh-add -l
# Remove keys
ssh-add -d ~/.ssh/mykey # Specific key
ssh-add -D # All keys
# Kill agent
ssh-agent -k
7.2 SSH Agent Forwarding
# Agent forwarding with -A option
ssh -A user@server1
# Now connect to other servers using local key from server1
ssh user@server2
# Configure in ~/.ssh/config
Host server1
ForwardAgent yes
# Caution: Only use on trusted servers
7.3 Key Management Best Practices
# Separate keys by purpose
ssh-keygen -t ed25519 -f ~/.ssh/work_key -C "work"
ssh-keygen -t ed25519 -f ~/.ssh/personal_key -C "personal"
# Set strong passphrase
ssh-keygen -t ed25519 -f ~/.ssh/mykey
# (Enter passphrase interactively)
# Check key permissions
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
chmod 700 ~/.ssh
# Rotate old keys
# 1. Generate new key
# 2. Register new key on servers
# 3. Test
# 4. Remove old key
8. Remote Server Management Tips
8.1 Session Keepalive
# Client config (~/.ssh/config)
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# Server config (/etc/ssh/sshd_config)
ClientAliveInterval 60
ClientAliveCountMax 3
8.2 Using with tmux/screen
# Create tmux session
tmux new -s mysession
# Detach session (Ctrl+B, D)
# Work continues even if SSH disconnects
# Reattach after reconnecting
tmux attach -t mysession
# List sessions
tmux ls
8.3 Managing Multiple Servers
# Run same command on multiple servers
for server in server1 server2 server3; do
ssh $server "uptime"
done
# Using parallel-ssh
pssh -h hosts.txt -l user "uptime"
# Using Ansible (recommended)
ansible all -m ping
ansible all -a "uptime"
8.4 SSH Connection Reuse
# ~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
# Create socket directory
mkdir -p ~/.ssh/sockets
# Additional connections after first are fast
9. Troubleshooting
9.1 Common Errors
# Permission denied (publickey)
# → Check key permissions
chmod 600 ~/.ssh/id_*
chmod 700 ~/.ssh
# Host key verification failed
# → Remove host from known_hosts
ssh-keygen -R hostname
# Connection refused
# → Check SSH server running
sudo systemctl status sshd
# Connection timed out
# → Check firewall
sudo ufw status
sudo firewall-cmd --list-all
9.2 Debug Mode
# Client debug
ssh -v user@host # Basic
ssh -vv user@host # Detailed
ssh -vvv user@host # Very detailed
# Server debug (foreground)
sudo /usr/sbin/sshd -d -p 2222
10. Practice: SSH Security Checklist
# 1. Set up key-based authentication
ssh-keygen -t ed25519
ssh-copy-id user@server
# 2. Disable password authentication
# /etc/ssh/sshd_config
PasswordAuthentication no
# 3. Disable root login
PermitRootLogin no
# 4. Change port (optional)
Port 2222
# 5. Configure firewall
sudo ufw allow 2222/tcp
sudo ufw enable
# 6. Install Fail2Ban
sudo apt install fail2ban
# 7. Apply settings
sudo sshd -t && sudo systemctl restart sshd
# 8. Test
ssh -p 2222 user@server
Conclusion
SSH is the core tool for remote server management. Using key-based authentication, applying proper security settings, and utilizing tunneling features enable secure and efficient server management. In the next part, we'll begin our journey into server management automation with shell script basics.