SSH & Remote Access

Securely connect to another computer's terminal from anywhere in the world.

What Is SSH?

SSH (Secure Shell) lets you open a terminal on another computer and control it remotely — as if you were sitting right in front of it, typing commands. The "secure" part means everything you send back and forth is encrypted, so nobody can eavesdrop on the connection.

That's really all it is: a way to type commands on a computer that's somewhere else, over an encrypted connection.

When Would You Use SSH?

Connecting to a Server

The basic command looks like this:

ssh user@hostname

Let's break that down:

So a real command might look like:

# Connecting to a VPS by IP address
ssh root@203.0.113.10

# Connecting to a Raspberry Pi on your local network
ssh pi@192.168.1.42

# Connecting to a server by domain name
ssh deploy@myapp.example.com

It will ask for a password. Type it in (you won't see any characters appear — that's normal, it's just hidden) and press Enter.

Good to know: If the remote server uses a non-standard port (the default is 22), add -p followed by the port number: ssh -p 2222 user@hostname

Your First Connection: The Fingerprint Warning

The very first time you connect to a new server, you'll see something like this:

The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:AbCdEf1234567890...
Are you sure you want to continue connecting (yes/no/[fingerprint])?

This looks scary, but it's perfectly normal. Here's what's happening:

SSH is saying "I've never talked to this computer before, so I can't verify it is who it says it is. Here's its fingerprint — do you want to trust it?"

Think of it like meeting someone new. The first time, you have to take their word for who they are. After that, SSH remembers their fingerprint and will warn you if it changes (which could mean someone is trying to impersonate that server).

Type yes and press Enter. SSH will save the fingerprint and you won't see this message for this server again.

SSH Keys: Your Digital ID Card

Typing a password every time you connect gets old fast. SSH keys are a better way to log in — more secure and more convenient.

Here's the idea: instead of proving your identity with a password, you prove it with a pair of special files called keys:

When you connect, the server checks whether your private key matches the public key it has on file. If it matches, you're in — no password needed.

Step 1: Generate Your Keys

Run this command on your computer (not on the server):

ssh-keygen -t ed25519 -C "your.email@example.com"

Let's break that down:

It will ask you a few things:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519): 

Press Enter to accept the default location. Your keys will be saved in the ~/.ssh/ folder.

Enter passphrase (empty for no passphrase): 

You can set a passphrase here. It's like a password for the key itself — an extra layer of security in case someone steals your key file. It's optional but recommended. If you set one, you'll type it once per session (your system's keyring usually remembers it after that).

When it's done, you'll have two files:

Step 2: Add Your Key to a Server

The easiest way is with ssh-copy-id:

ssh-copy-id user@hostname

It will ask for your password one last time. After this, it copies your public key to the server and you can log in without a password from now on.

What it actually does behind the scenes: it appends your public key to the file ~/.ssh/authorized_keys on the remote server. Every public key listed in that file is allowed to log in.

If ssh-copy-id isn't available (for example, on macOS), you can do it manually:
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
This does the exact same thing — just the long way around.

Now test it:

ssh user@hostname

If everything worked, you should get in without being asked for a password.

Step 3 (Optional): Add Your Key to GitHub

SSH keys aren't just for servers — GitHub uses them too, so you can push and pull code without typing your password.

  1. Copy your public key to the clipboard:
    # If you have xclip installed:
    xclip -selection clipboard < ~/.ssh/id_ed25519.pub
    
    # Or on Wayland:
    wl-copy < ~/.ssh/id_ed25519.pub
    
    # Or just print it and copy manually:
    cat ~/.ssh/id_ed25519.pub
  2. Go to GitHub: Open github.com/settings/keys (Settings → SSH and GPG keys).
  3. Click "New SSH key".
  4. Give it a title (something like "My Laptop" so you know which computer it's from).
  5. Paste your public key into the "Key" field.
  6. Click "Add SSH key".
  7. Test it:
    ssh -T git@github.com

    You should see: Hi username! You've successfully authenticated...

From now on, when cloning repos, use the SSH URL (starts with git@github.com:) instead of the HTTPS one.

SSH config file: create shortcuts for your servers

If you connect to the same servers often, typing the full command every time gets tedious. You can create shortcuts in ~/.ssh/config:

# Create or edit the config file
nano ~/.ssh/config

Add entries like this:

# My VPS
Host myserver
    HostName 203.0.113.10
    User deploy
    Port 22

# Raspberry Pi at home
Host pi
    HostName 192.168.1.42
    User pi

# Work server with a non-standard port
Host work
    HostName work.example.com
    User jdoe
    Port 2222
    IdentityFile ~/.ssh/work_key

Now instead of typing ssh deploy@203.0.113.10, you just type:

ssh myserver

That's it. SSH reads the config file and fills in the details for you.

Some useful options you can put in each Host block:

Make sure the config file has the right permissions:

chmod 600 ~/.ssh/config

Copying Files Over SSH

SSH isn't just for remote terminals — you can use it to copy files between computers too.

SCP (Secure Copy)

The simplest way to copy a file. It works like the regular cp command, but between computers:

# Copy a file FROM your computer TO a server
scp myfile.txt user@hostname:/home/user/

# Copy a file FROM a server TO your computer
scp user@hostname:/var/log/app.log ./

# Copy an entire folder (use -r for recursive)
scp -r myfolder/ user@hostname:/home/user/

rsync (Smarter Copying)

rsync is like SCP's smarter cousin. It only transfers files that have changed, which makes it much faster for repeated backups or syncs:

# Sync a folder to a server (only sends changes)
rsync -avz myfolder/ user@hostname:/home/user/myfolder/

# Sync from a server to your computer
rsync -avz user@hostname:/home/user/data/ ./data/

The flags: -a preserves file permissions and dates, -v shows progress, -z compresses data during transfer.

Which one should you use? For a quick one-off file copy, scp is fine. For anything you'll do more than once — like backups or keeping folders in sync — use rsync.

Common Errors and How to Fix Them

Connection refused

ssh: connect to host 203.0.113.10 port 22: Connection refused

This means nothing is listening for SSH connections on that server. Possible causes:

Permission denied (publickey)

Permission denied (publickey).

The server wants key-based login only, and it doesn't recognize your key. This usually means:

Host key verification failed

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
...
Host key verification failed.

Remember the fingerprint from your first connection? SSH saved it, and now the server's fingerprint is different. This could mean:

If you know the server was reinstalled or you trust the change, remove the old fingerprint:

ssh-keygen -R hostname

Then connect again and accept the new fingerprint.

Don't blindly clear this warning. If you didn't reinstall the server and nothing about it changed, investigate before connecting. This warning exists for a good reason.
Security tips: hardening your SSH server

If you're running an SSH server (for example, on a VPS), here are some important steps to make it more secure. These changes are made in /etc/ssh/sshd_config on the server:

Disable password login

Once you've set up SSH keys, there's no reason to allow password logins anymore. Passwords can be brute-forced — keys can't.

# Edit the SSH server config
sudo nano /etc/ssh/sshd_config

# Find these lines and set them to:
PasswordAuthentication no
ChallengeResponseAuthentication no

# Restart SSH to apply changes
sudo systemctl restart sshd
Make sure your SSH key login works before doing this! If you disable passwords and your key isn't set up properly, you'll be locked out of your own server.

Change the default port

Port 22 is the standard SSH port, which means automated bots constantly try to break into it. Changing it won't stop a determined attacker, but it eliminates most of the noise from automated scanners.

# In /etc/ssh/sshd_config, change:
Port 2222    # Pick any unused port between 1024-65535

# Restart SSH
sudo systemctl restart sshd

# Don't forget to update your firewall!
sudo ufw allow 2222/tcp    # If using UFW

After this, connect with: ssh -p 2222 user@hostname

Disable root login

Logging in directly as root is risky. Instead, log in as a normal user and use sudo when you need admin access.

# In /etc/ssh/sshd_config:
PermitRootLogin no

# Restart SSH
sudo systemctl restart sshd

Install fail2ban

fail2ban watches your login attempts and automatically bans IP addresses that fail too many times. It's a great defense against brute-force attacks.

# Install fail2ban
sudo apt install fail2ban       # Ubuntu/Debian/Mint
sudo dnf install fail2ban       # Fedora
sudo pacman -S fail2ban         # Arch/Manjaro

# Start and enable it
sudo systemctl enable --now fail2ban

The default settings work well for most people — it bans an IP for 10 minutes after 5 failed login attempts.

Quick security checklist