How to Connect to a Fedora Machine via SSH

Enable the SSH daemon on your Fedora machine, open the firewall port, and connect from any client using the standard ssh command.

You typed ssh and got Connection refused

You just finished configuring a new Fedora Workstation as a home server, or maybe you dual-booted and want to jump between desktops without logging out. You type ssh user@192.168.1.50 and get Connection refused. Or worse, Connection timed out. The machine is on, the network is up, but the door is locked.

Fedora ships with the SSH server package but leaves it disabled by default for security. The firewall also blocks port 22 unless you explicitly allow it. You need to open the port, start the daemon, and decide how you want to authenticate.

What's actually happening

SSH creates an encrypted tunnel between your local machine and the remote Fedora system. The remote side runs a daemon called sshd that listens for incoming connections. When you connect, the client and server negotiate encryption, verify identities, and establish a session.

Think of SSH as a digital front door. The firewall is the gate. The sshd service is the doorman. The keys are the ID badge. If the gate is closed, nobody gets in. If the doorman is sleeping, the gate doesn't matter. If you don't have a badge, the doorman sends you away.

Fedora's default stance is to keep the gate closed and the doorman off until you ask for them. This prevents accidental exposure of services on public networks. You enable the service when you need remote access. You open the firewall when you are ready to accept connections. You configure keys when you want secure, automated login.

Install and enable the SSH server

Here's how to ensure the SSH server is installed and running. Fedora includes openssh-server in the base repository. Minimal spins might not install it by default.

sudo dnf install -y openssh-server
# openssh-server provides the sshd daemon and client tools.
# Fedora includes this package but may not install it on minimal spins.

sudo systemctl enable --now sshd
# enable creates the symlink for boot persistence.
# --now starts the service immediately without a second command.

Verify the daemon is active and listening.

systemctl status sshd
# status shows active state, PID, and recent log lines.
# Look for "Active: active (running)" to confirm the service is up.

Run systemctl status sshd before you blame the network. If the unit is inactive, no amount of firewall tweaking will help.

Open the firewall

Fedora uses firewalld by default. The firewall blocks incoming connections to port 22 unless you add a rule. You must add the rule permanently and reload the firewall to apply it.

sudo firewall-cmd --permanent --add-service=ssh
# --permanent writes the rule to the config file so it survives reboots.
# --add-service=ssh opens port 22/tcp using the predefined service definition.

sudo firewall-cmd --reload
# --reload applies the change to the running firewall immediately.
# Always reload after permanent changes. Runtime and persistent configs diverge otherwise.

Check that the service is allowed.

sudo firewall-cmd --list-services
# Lists all services allowed in the active zone.
# ssh should appear in the output.

Always run firewall-cmd --reload after every rule change. Otherwise the runtime config and the persistent config diverge, and you get confused when reboots break your access.

Find the machine's IP address

You need the IP address or hostname of the Fedora machine to connect. Use ip or hostname to find it.

ip -br addr
# -br gives a brief, one-line output per interface.
# Easier to scan than the full dump from ip addr show.

hostname -I
# Prints all IP addresses assigned to the host on one line.
# Useful for quick copy-paste.

Look for the interface connected to your network. eth0 or enp3s0 for wired, wlan0 for wireless. Ignore 127.0.0.1 and lo.

Connect from a client

From any Linux, macOS, or Windows machine with an SSH client, connect using the username and IP address.

ssh username@192.168.1.100
# First connection prompts for host key verification.
# Type yes to trust the machine and add its key to ~/.ssh/known_hosts.

Replace username with your Fedora account name. Replace the IP with the server's address. You can also use a hostname if DNS is configured.

If you see Permission denied (publickey,password), your key is not accepted or password auth is disabled. Check the next section. If you see Connection timed out, the firewall is blocking the port or the IP is wrong.

Use key-based authentication

Password authentication works but key pairs are more secure. Keys resist brute-force attacks and allow automation. Generate a key pair on your client machine.

ssh-keygen -t ed25519 -C "fedora-client"
# ed25519 is the modern standard. Fast, secure, and widely supported.
# -C adds a comment for identification. It does not affect security.
# Press Enter to accept the default file location and leave the passphrase empty for convenience.

Copy the public key to the server. ssh-copy-id handles permissions and file placement automatically.

ssh-copy-id username@192.168.1.100
# Copies the public key to ~/.ssh/authorized_keys on the server.
# Handles permissions automatically. Safer than manual cat/echo piping.
# Prompts for the password once to complete the transfer.

After this, SSH will authenticate with your key automatically. You can optionally disable password login on the server to enforce key-only access.

Harden the SSH configuration

Edit the SSH daemon configuration to disable password authentication. This step is optional but recommended for servers exposed to the internet or shared networks.

sudo nano /etc/ssh/sshd_config
# Edit /etc/ssh/sshd_config, never /usr/lib/ssh/sshd_config.
# Changes in /usr/lib/ get overwritten by package updates.
# /etc/ is the user-modified layer. /usr/lib/ ships with the package.

Find the line #PasswordAuthentication yes. Remove the # and change yes to no. You can also disable root login.

PasswordAuthentication no
PermitRootLogin no

Test the configuration for syntax errors before restarting. A typo can lock you out.

sudo sshd -t
# Tests the configuration file for syntax errors without restarting the service.
# Prevents locking yourself out due to a typo.
# Returns no output if the config is valid.

Restart the service to apply changes. Keep a second terminal session open in case the restart fails and you need to revert.

sudo systemctl restart sshd
# restart stops and starts the service.
# Use reload instead of restart to keep existing sessions alive.
# restart is safer here to ensure the new config is fully loaded.

Trust the package manager. Manual file edits drift, snapshots stay. If you break the config, sudo dnf reinstall openssh-server restores the default file.

Store connection details in config

If you connect to the same host multiple times, use ~/.ssh/config to avoid typing flags every time. This file lives on your client machine.

nano ~/.ssh/config
# Creates or edits the SSH client configuration file.
# This file is local to the user. It does not affect the server.

Add a host block with your connection details.

Host myserver
    HostName 192.168.1.100
    User username
    IdentityFile ~/.ssh/my_key
    ServerAliveInterval 60
# Host defines an alias you can use with ssh myserver.
# HostName is the actual IP or domain.
# User sets the default login name.
# IdentityFile points to a specific private key.
# ServerAliveInterval sends a keepalive packet every 60 seconds to prevent idle disconnects.

Set strict permissions on the config file. SSH refuses to use it if other users can read it.

chmod 600 ~/.ssh/config
# 600 restricts access to the owner only.
# SSH requires strict permissions on config and key files.

Connect using the alias.

ssh myserver
# Uses the settings from the config block.
# No need to type user, IP, or key file.

Run ssh -v myserver if the connection fails. The verbose output shows exactly which config lines are being applied and where the handshake breaks.

Verify it worked

Confirm the server is running and accepting connections. Check the service status and recent logs.

systemctl status sshd
# status shows active state and recent log lines.
# Active: active (running) means the daemon is up.

journalctl -xeu sshd
# -x adds explanatory text to log entries.
# -e jumps to the end of the journal.
# -u filters for the sshd unit.
# Most sysadmins type journalctl -xeu <unit> muscle-memory style.

Look for Accepted publickey for username in the logs. This confirms key authentication is working. If you see Failed password, password attempts are still happening. Check your sshd_config and client behavior.

Reboot before you debug. Half the time the symptom is gone after a clean boot cycle.

Common pitfalls and errors

Connection refused means the port is closed or the service is down. Check systemctl status sshd and sudo firewall-cmd --list-services.

Connection timed out means the packet is dropped. The firewall is blocking the port, or the IP address is wrong. Verify the IP with ip -br addr.

Permission denied (publickey) means the server rejected your key. Check that ssh-copy-id succeeded. Verify ~/.ssh/authorized_keys exists on the server and has 600 permissions. Check ~/.ssh directory has 700 permissions.

Host key verification failed means the server's key changed. This happens after a reinstall or if the IP was reassigned. Remove the old key from ~/.ssh/known_hosts on the client.

ssh-keygen -R 192.168.1.100
# Removes the old key for the specified host from known_hosts.
# Prevents the verification error on the next connection.

sshd: error: Bind to port 22 failed: Address already in use means another process is using port 22. Check with sudo ss -tlnp | grep :22.

When to use this vs alternatives

Use SSH keys when you want secure, automated access without typing passwords. Use password authentication only for temporary access on trusted networks where key setup is impractical. Use ssh-copy-id when you have password access and want to deploy keys quickly. Use manual authorized_keys editing when you are managing a headless server where you cannot run interactive commands. Use ~/.ssh/config when you connect to the same host multiple times with different users or ports. Use systemctl reload sshd when you change configuration and want to keep existing sessions alive. Use systemctl restart sshd when you need to fully restart the daemon or reload fails to apply changes.

Where to go next