To turn on SSH on a Raspberry Pi, the most reliable headless method is creating an empty file named ssh (no extension) in the root of the FAT32 boot partition before first boot. If the Pi is already running and connected to a display, open a terminal and type sudo raspi-config, navigate to Interface Options > SSH, and select Yes. This opens port 22 for secure remote command-line access, allowing you to manage hardware projects without a dedicated monitor.

Bench Note on OS Versions: This guide targets the Raspberry Pi 5 (8GB) running Raspberry Pi OS (Bookworm, 64-bit). Bookworm introduced strict security changes, including the removal of the default pi user. If you are migrating older Bullseye tutorials to a modern Pi 5, expect user-permission errors unless you explicitly configure your custom user during the Imager flashing process.

The Direct Answer: 3 Ways to Enable Remote Access

Depending on your current hardware setup, choose the method that fits your bench environment:

  1. The Headless Boot Method (No Monitor): Flash your SD card using Raspberry Pi Imager. Click the gear icon (Advanced Options), check Enable SSH, and choose "Use password authentication". Alternatively, if using a pre-flashed card, mount the SD card on your PC, open the bootfs partition, and create a blank text file named exactly ssh (delete the .txt extension). The Pi OS detects this file on boot, enables the SSH daemon, and deletes the file.
  2. The Desktop GUI Method: Boot into the Pi OS desktop. Go to Menu > Preferences > Raspberry Pi Configuration. Click the Interfaces tab and toggle the SSH radio button to Enabled.
  3. The Terminal Method: If you have a keyboard and monitor attached, run sudo raspi-config, select 3 Interface Options, then I2 SSH, and confirm Yes.

Hardware Spec Sheet & GPIO Pin Mapping

Turning on SSH is usually step one for a headless hardware control project. Below is the spec sheet and pin mapping for a common bench test: controlling a 5V optocoupler-isolated relay module via SSH. This allows you to safely switch 120V/240V AC loads or 12V DC pumps remotely.

Parts List

  • Compute: Raspberry Pi 5 (8GB RAM) - ~$80
  • Power: Official Raspberry Pi 27W USB-C Power Supply - ~$12 (Required for Pi 5 to prevent USB/current throttling)
  • Actuator: 5V Single-Channel Relay Module (Optocoupler isolated, Active Low) - ~$4
  • Wiring: 22 AWG solid core female-to-female jumper wires

Pin Mapping Table

The Pi 5's 5V rail can safely supply up to 3A to peripherals when using the 27W PSU. A standard 5V relay module draws roughly 70mA when the coil is energized, making it perfectly safe to power directly from the GPIO header.

Function BCM GPIO Physical Pin Relay Module Terminal
Control Signal GPIO 17 Pin 11 IN (Signal)
Power (5V) N/A (5V Rail) Pin 2 VCC
Ground N/A (GND) Pin 6 GND

The Code: Remote GPIO Relay Control

Once SSH is enabled and you are logged into your Pi, you need a robust script to control the hardware. The following Python script uses the gpiozero library (pre-installed on Bookworm) to create an interactive command-line relay controller. It includes explicit pin definitions, active-low logic handling for standard relay modules, and comprehensive error handling.

#!/usr/bin/env python3
"""
Remote GPIO Relay Control Script
Target Board: Raspberry Pi 5 (Bookworm 64-bit)
Library: gpiozero
"""
import sys
import time

try:
    from gpiozero import OutputDevice
except ImportError:
    print("Error: gpiozero not found. Install via: sudo apt install python3-gpiozero")
    sys.exit(1)

# PIN DEFINITIONS (BCM Numbering)
RELAY_PIN = 17  # Physical Pin 11

# Initialize Relay (Active Low for most 5V relay modules)
# active_high=False means the pin goes LOW to trigger the relay coil
relay = OutputDevice(RELAY_PIN, active_high=False, initial_value=False)

def main():
    print(f"SSH GPIO Control Active on BCM Pin {RELAY_PIN}.")
    print("Commands: 'on', 'off', 'toggle', 'quit'")

    try:
        while True:
            cmd = input("relay> ").strip().lower()
            if cmd == 'on':
                relay.on()
                print("Relay ENGAGED (NO connected to COM).")
            elif cmd == 'off':
                relay.off()
                print("Relay DISENGAGED (NC connected to COM).")
            elif cmd == 'toggle':
                relay.toggle()
                state = "ENGAGED" if relay.value else "DISENGAGED"
                print(f"Relay toggled. Current state: {state}")
            elif cmd in ('quit', 'exit', 'q'):
                break
            else:
                print("Invalid command. Use on/off/toggle/quit.")
    except KeyboardInterrupt:
        print("\nCtrl+C detected. Safely shutting down GPIO...")
    except Exception as e:
        print(f"Unexpected runtime error: {e}")
    finally:
        relay.close()
        print("GPIO resources released. Goodbye.")

if __name__ == "__main__":
    main()

Save this as relay_control.py, make it executable with chmod +x relay_control.py, and run it via your SSH session.

Debugging: Exact Error Strings and Ranked Fixes

When remote access fails, the terminal gives you specific clues. Here are the two most common error strings and the first three things to check for each.

Error 1: ssh: connect to host 192.168.1.50 port 22: Connection refused

This means your computer reached the Pi's IP address, but the Pi actively rejected the connection on port 22.

  1. The SSH daemon isn't running: You likely forgot to create the headless ssh file, or you accidentally created ssh.txt because Windows hides file extensions. Re-flash the SD card using the Raspberry Pi Imager's Advanced Options menu to guarantee the service starts.
  2. The Pi hasn't finished booting: A Pi 5 booting from a slow SD card can take 45-60 seconds to initialize the network stack and start sshd. Wait two minutes after applying power before attempting to connect.
  3. IP Address Mismatch: Your router's DHCP server may have assigned a different IP. Check your router's client list or use a network scanner like nmap -sn 192.168.1.0/24 to find the correct IP.

Error 2: username@192.168.1.50: Permission denied (publickey,password)

This means the SSH daemon is running, but your credentials or authentication method were rejected.

  1. The 'pi' user no longer exists: In Raspberry Pi OS Bookworm, the default pi user was removed for security. You must SSH using the custom username you created in the Raspberry Pi Imager (e.g., ssh maker@192.168.1.50).
  2. Keyboard Layout Mismatch: If your password contains symbols (like @ or #) and the Pi is set to a UK keyboard layout while you are typing on a US keyboard, you are sending the wrong characters. Stick to alphanumeric passwords for initial setup.
  3. Corrupted authorized_keys: If you are using key-based authentication, ensure your public key was correctly appended to ~/.ssh/authorized_keys on the Pi, and that the .ssh directory has 700 permissions.

Extending and Simplifying the Build

Interactive SSH sessions are great for bench testing, but they aren't ideal for production IoT deployments. Here is how to adapt the build based on your end goal.

Simplify with Raspberry Pi Connect: If your Pi is behind a strict NAT or corporate firewall and you cannot configure port forwarding, look into Raspberry Pi Connect. This official service creates a secure WireGuard tunnel, allowing you to access your Pi's shell and browser remotely via a web dashboard without exposing port 22 to the public internet.

Extend with MQTT: To automate the relay based on sensor data rather than manual SSH commands, replace the interactive Python loop with an MQTT client using the paho-mqtt library. Install the Mosquitto broker on the Pi, and have your Python script subscribe to a topic like home/lab/relay1/set. This allows integration with Home Assistant or Node-RED without keeping an active SSH terminal open.

Fixing WiFi Dropouts: If your SSH session freezes when the Pi is on WiFi, the OS is likely putting the wireless adapter to sleep to save power. Fix this by running sudo iwconfig wlan0 power off. To make it permanent, add the command to your /etc/rc.local file.

Frequently Asked Questions

How do I turn on SSH on Raspberry Pi without a monitor or keyboard?

The standard headless method is to mount the freshly flashed microSD card on your PC. Open the drive labeled boot or bootfs (this is the only partition Windows/macOS can read). Create a new, completely empty file and name it ssh. Ensure your operating system hasn't secretly named it ssh.txt. When the Pi boots, it reads the bootfs partition, enables the SSH daemon, and deletes the file. For a more robust setup, use the "OS Customisation" gear icon in the official Raspberry Pi Imager software before flashing, which allows you to inject the SSH config, WiFi credentials, and username simultaneously.

Why is my Raspberry Pi SSH connection dropping over WiFi?

Intermittent SSH drops on Raspberry Pi 4 and 5 models over WiFi are almost always caused by aggressive power management on the Broadcom wireless chip. The OS puts the radio to sleep during micro-pauses in terminal typing. You can verify this is the issue by pinging the Pi continuously; you will see latency spikes or dropped packets. Run sudo iwconfig wlan0 power off to disable power saving. If the drops persist, check your power supply—a Pi 5 running on an underpowered USB-C phone charger will brownout the WiFi chip before the CPU throttles.

Is it safe to leave SSH enabled on a Raspberry Pi exposed to the internet?

No, exposing default port 22 to the open internet will result in automated brute-force botnets attempting to log in within minutes. If you must access your Pi remotely, you should implement three layers of defense: First, disable password authentication entirely and use SSH Ed25519 key pairs. Second, install fail2ban (sudo apt install fail2ban) to automatically ban IP addresses that fail login attempts. Third, change the default SSH port in /etc/ssh/sshd_config to a non-standard high port (e.g., 22222) to avoid the bulk of automated script-kiddie scanners. For the safest approach, avoid port forwarding altogether and use a WireGuard VPN or Raspberry Pi Connect.