Remote Access to a Raspberry Pi 4: SSH Keys, VNC and File Transfer
Most Raspberry Pi 4 projects end up running without a keyboard or monitor: a NAS in a cupboard, a sensor logger on a shelf, a web server under the desk. You manage these boards remotely. Typing a password each time you connect is slow and, if the board is reachable from outside your home network, insecure.
This tutorial sets up three things: SSH key authentication so you log in without a password, a hardened SSH server that refuses password logins, and VNC remote desktop for when you do need the graphical desktop. It finishes with copying files to and from the Pi using scp.
How SSH Key Authentication Works
An SSH key pair has two halves. The private key stays on your laptop and never leaves it. The public key is copied into the file ~/.ssh/authorized_keys on the Pi. When you connect, the server sends a challenge that only the holder of the matching private key can sign. No password crosses the network, and an attacker who guesses or steals your Pi password still cannot log in once password authentication is disabled.
Use the ed25519 key type. It is short, fast and supported by every current OpenSSH version, including the client built into Windows 10 and 11.
Creating and Installing the Key
Step 1: Generate the key on your PC
ssh-keygen -t ed25519 -C "laptop-to-pi4" # Press Enter to accept the default path # Enter a passphrase to protect the private key (recommended)
This creates id_ed25519 (private) and id_ed25519.pub (public) in the .ssh folder of your home directory.
Step 2: Copy the public key to the Pi
On Linux and macOS, ssh-copy-id yourname@pi4lab.local does everything. Windows does not ship ssh-copy-id, so use this PowerShell one-liner instead. It appends your public key and sets the correct permissions:
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh yourname@pi4lab.local "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Now run ssh yourname@pi4lab.local. You should be asked for the key passphrase (or nothing at all), not the Pi account password.
Step 3: Add a host shortcut
Create or edit the file config inside your .ssh folder on the PC so that a short name holds all the details:
# ~/.ssh/config (on Windows: C:\Users\<you>\.ssh\config)
Host pi4
HostName pi4lab.local # or the fixed IP, e.g. 192.168.1.50
User yourname # the account created in Raspberry Pi Imager
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60 # keep idle sessions from dropping
From now on, ssh pi4 is enough, and the same alias works with scp and with VS Code Remote-SSH.
Hardening the SSH Server
Only do this after key login works, or you will lock yourself out. Bookworm's /etc/ssh/sshd_config includes every file in /etc/ssh/sshd_config.d/, so put your changes in a separate file that system upgrades will not overwrite:
#!/bin/bash
# harden_ssh.sh - run on the Pi AFTER confirming key login works
set -e
# Write a drop-in config file. Settings here override the defaults.
sudo tee /etc/ssh/sshd_config.d/10-hardening.conf > /dev/null << 'EOF'
# Allow only public-key logins
PasswordAuthentication no
KbdInteractiveAuthentication no
# Never allow root to log in directly
PermitRootLogin no
# Limit authentication attempts per connection
MaxAuthTries 3
EOF
# Check the syntax before restarting; sshd -t prints nothing if all is well
sudo sshd -t
# Apply the new settings (existing sessions stay open)
sudo systemctl restart ssh
# Show the effective values to confirm
sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin|maxauthtries'
Remote Desktop with VNC
On a Pi 4, Bookworm runs a Wayland desktop. The old RealVNC Server that worked with X11 is replaced by wayvnc, which is installed with the desktop image. Enable it with sudo raspi-config, then Interface Options, then VNC, and answer Yes. It is also available under Preferences, Raspberry Pi Configuration, Interfaces on the desktop.
On your PC, install a VNC viewer such as TigerVNC Viewer or RealVNC Viewer and connect to pi4lab.local (port 5900). Log in with your Pi username and password.
| Problem | Cause | Fix |
|---|---|---|
| VNC shows a tiny or blank screen | No monitor attached, so no display size | Set a headless resolution in raspi-config, Display Options |
| Connection refused | VNC not enabled or desktop not running | Enable VNC and boot to desktop with auto-login |
| Lite image has no VNC option | No desktop installed | Use SSH only, or install the desktop packages |
Copying Files with scp
With the pi4 alias defined, copying in either direction is one command, run from your PC:
# PC to Pi: copy a script into the home folder scp blink.py pi4:~/projects/ # Pi to PC: fetch a log file into the current folder scp pi4:~/logs/sensor.csv . # Copy a whole folder recursively scp -r ./website pi4:~/
For a drag-and-drop experience, WinSCP or FileZilla in SFTP mode use the same SSH key and need no extra software on the Pi.
Common Mistakes
- Copying the private key (
id_ed25519) to the Pi instead of the.pubfile. Only the public key belongs on the server. - Wrong permissions: if
~/.sshis writable by others, sshd silently ignoresauthorized_keys. Use 700 for the folder and 600 for the file. - "REMOTE HOST IDENTIFICATION HAS CHANGED" after reflashing the card: the Pi has new host keys. Remove the old entry with
ssh-keygen -R pi4lab.local. - Forwarding port 22 on your router to the Pi. If you need access from outside, use a VPN such as WireGuard or Tailscale instead.
Summary
Generate an ed25519 key on your PC, append the public half to ~/.ssh/authorized_keys on the Pi, add a host alias, and then disable password logins with a drop-in file in /etc/ssh/sshd_config.d/. Use wayvnc through raspi-config when you need the desktop, and scp or an SFTP client for files. The board is now ready to be managed from anywhere on your network.