_____                   _             ___     _________  __
 |_   _|__ _ __ _ __ ___ (_)_ __   __ _| \ \   / / ____\ \/ /
   | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | |\ \ / /|  _|  \  /
   | |  __/ |  | | | | | | | | | | (_| | | \ V / | |___ /  \
   |_|\___|_|  |_| |_| |_|_|_| |_|\__,_|_|  \_/  |_____/_/\_\
advanced14 min

Secure Remote Connection with SSH

What is SSH?

SSH (Secure Shell) is a network protocol that creates a secure, encrypted communication channel between two computers. It was developed in 1995 by Finnish researcher Tatu Ylönen as an alternative to insecure Telnet and rlogin protocols. Today, SSH is the de facto standard method for connecting to remote servers, transferring files, and creating network tunnels.

The most basic use case for SSH is securely connecting to a remote server and executing commands. However, SSH's capabilities extend far beyond this: it offers many advanced features such as file transfer (SCP/SFTP), port forwarding, X11 forwarding (running graphical applications remotely), and creating VPN-like tunnels. From web developers managing servers to DevOps engineers automating processes, SSH is everywhere.

How SSH Works

SSH is based on the client-server model. The following steps occur when establishing a connection:

  • 1. TCP Connection: The client initiates a TCP connection to the server's port 22 (default).
  • 2. Protocol Negotiation: Both sides share their supported SSH versions and encryption algorithms.
  • 3. Key Exchange: A shared session key is created using Diffie-Hellman or a similar algorithm. From this point on, all communication is encrypted.
  • 4. Server Authentication: The server proves its identity by sending its host key. On the first connection, this key is stored on the client side.
  • 5. Client Authentication: The client verifies its identity using a password or key pair.
  • 6. Secure Session: If authentication is successful, an encrypted session is opened and commands can be executed.

Basic SSH Connection

The ssh Command

# Basic connection (username@server address)
$ ssh user@server.example.com

# Connection with IP address
$ ssh root@192.168.1.100

# Connection on a different port (-p)
$ ssh -p 2222 user@server.example.com

# Verbose connection output (debugging)
$ ssh -v user@server.example.com

# Terminate the connection
$ exit
# or Ctrl+D

Host Key Verification on First Connection

When you connect to a server for the first time, SSH shows the server's fingerprint and asks for confirmation. This is an important security step to verify the server's identity.

$ ssh user@new-server.com
The authenticity of host 'new-server.com (203.0.113.50)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'new-server.com' (ED25519) to the list of known hosts.

After confirmation, the server's key is saved in the ~/.ssh/known_hosts file. Subsequent connections perform this verification automatically.

Generating SSH Key Pairs (ssh-keygen)

Key-based authentication is much more secure and practical than using passwords. A key pair consists of two files: a private key and a public key that are mathematically related to each other.

# Generate an RSA key pair (4096 bits)
$ ssh-keygen -t rsa -b 4096 -C "email@example.com"

# Generate an Ed25519 key pair (recommended)
$ ssh-keygen -t ed25519 -C "email@example.com"

# Output:
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (/home/user/.ssh/id_ed25519):
# Enter passphrase (empty for no passphrase):
# Enter same passphrase again:
# Your identification has been saved in /home/user/.ssh/id_ed25519
# Your public key has been saved in /home/user/.ssh/id_ed25519.pub

# Generate a key with a custom filename
$ ssh-keygen -t ed25519 -f ~/.ssh/project_key -C "project server"

Files created:

  • ~/.ssh/id_ed25519 — Private key (NEVER share this with anyone!)
  • ~/.ssh/id_ed25519.pub — Public key (this is the file you copy to servers)

Key-Based Authentication

After copying your public key to the remote server, you can connect without entering a password.

# Copy the public key to the server (easiest method)
$ ssh-copy-id user@server.example.com

# Manual copy (if ssh-copy-id is not available)
$ cat ~/.ssh/id_ed25519.pub | ssh user@server.example.com "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

# Verify — you can now connect without a password
$ ssh user@server.example.com

File Permissions

SSH is very strict about key file permissions. Incorrect permissions will cause connection errors.

# Set correct permissions
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/id_ed25519
$ chmod 644 ~/.ssh/id_ed25519.pub
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 644 ~/.ssh/known_hosts

SSH Config File

The ~/.ssh/config file allows you to define shortcuts and custom settings for servers you frequently connect to. This way, you can use short aliases instead of typing long commands.

# ~/.ssh/config file example

# Global settings
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    AddKeysToAgent yes

# Production server
Host production
    HostName server.example.com
    User deploy
    Port 22
    IdentityFile ~/.ssh/production_key

# Test server
Host test
    HostName test.example.com
    User developer
    Port 2222
    IdentityFile ~/.ssh/test_key

# GitHub
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/github_key

# Connection through bastion/jump host
Host internal-server
    HostName 10.0.1.50
    User admin
    ProxyJump bastion.example.com

Using the Config File

# You can now connect with short names
$ ssh production
# Equivalent: ssh -i ~/.ssh/production_key -p 22 deploy@server.example.com

$ ssh test
# Equivalent: ssh -i ~/.ssh/test_key -p 2222 developer@test.example.com

File Transfer with SCP

scp (Secure Copy Protocol) is used to copy files over SSH. Its syntax is similar to the cp command, but you can also send files to or download files from remote servers.

# Copy a local file to a remote server
$ scp file.txt user@server:/home/user/

# Copy from a remote server to the local machine
$ scp user@server:/var/log/app.log ./

# Copy a directory recursively (-r)
$ scp -r project/ user@server:/home/user/projects/

# Copy with a different port (-P uppercase!)
$ scp -P 2222 file.txt user@server:/tmp/

# Copy between two remote servers
$ scp user1@server1:/file.txt user2@server2:/destination/

# Copy with progress indicator
$ scp -v large-file.tar.gz user@server:/backup/

File Transfer with SFTP

sftp (SSH File Transfer Protocol) provides an interactive file transfer session. It works with commands similar to FTP, but all communication is encrypted over SSH.

# Start an SFTP session
$ sftp user@server.example.com

# SFTP commands (within the session):
sftp> ls                    # List remote directory contents
sftp> lls                   # List local directory contents
sftp> cd /var/www           # Change remote directory
sftp> lcd ~/Desktop         # Change local directory
sftp> get file.txt          # Download from remote
sftp> put local-file.txt    # Upload to remote
sftp> mget *.log            # Download multiple files
sftp> mput *.html           # Upload multiple files
sftp> mkdir new-dir         # Create remote directory
sftp> rm old-file.txt       # Delete remote file
sftp> exit                  # Close session

Port Forwarding

SSH port forwarding allows you to create secure tunnels between local and remote ports. This feature is very useful for accessing services behind firewalls or encrypting traffic.

Local Port Forwarding

# Access remote MySQL through a local port
$ ssh -L 3307:localhost:3306 user@server.example.com
# You can now connect to remote MySQL via localhost:3307

# Access a web application on the remote network
$ ssh -L 8080:10.0.1.50:80 user@bastion.example.com
# localhost:8080 -> bastion -> 10.0.1.50:80

# Create a tunnel in the background (-f -N)
$ ssh -f -N -L 5432:localhost:5432 user@db-server.example.com

Remote Port Forwarding

# Make local development server accessible remotely
$ ssh -R 8080:localhost:3000 user@server.example.com
# server:8080 -> local machine:3000

Dynamic Port Forwarding (SOCKS Proxy)

# Create a SOCKS proxy
$ ssh -D 1080 user@server.example.com
# Set browser proxy to SOCKS5: localhost:1080

Security Best Practices

  • Use key-based authentication instead of passwords: It is much more secure against brute-force attacks.
  • Protect your private key with a passphrase: Even if your key file is stolen, it cannot be used without the passphrase.
  • Disable direct root SSH login: Set PermitRootLogin no in the /etc/ssh/sshd_config file.
  • Change the default port: Use a different port instead of port 22 to reduce automated scanning attacks.
  • Use Fail2ban: Automatically block IP addresses after a certain number of failed login attempts.
  • Rotate your SSH keys regularly: Deactivate old keys and generate new ones.
  • Prefer strong encryption algorithms: Use Ed25519 or RSA 4096-bit keys.
  • Add two-factor authentication (2FA): Add an extra security layer with tools like Google Authenticator.

Server-Side Security Settings

# Recommended settings in /etc/ssh/sshd_config:

# Disable root login
PermitRootLogin no

# Disable password authentication
PasswordAuthentication no

# Do not allow empty passwords
PermitEmptyPasswords no

# Change the port
Port 2222

# Allow specific users
AllowUsers deploy developer

# Session timeout
ClientAliveInterval 300
ClientAliveCountMax 2

# Restart SSH service after changes
$ sudo systemctl restart sshd

SSH Agent Key Management

# Start SSH agent
$ eval "$(ssh-agent -s)"

# Add key to agent
$ ssh-add ~/.ssh/id_ed25519

# List keys in agent
$ ssh-add -l

# Remove all keys from agent
$ ssh-add -D

Summary

SSH is the cornerstone of secure communication with remote systems. Establishing secure connections with the ssh command, generating key pairs with ssh-keygen, configuring key-based authentication with ssh-copy-id, managing connections with the SSH config file, secure file transfers with scp and sftp, and creating tunnels with port forwarding — all of these skills are essential in every system administrator's and developer's toolkit. Follow security best practices to keep your SSH infrastructure solid and boost your productivity.