Fedora

How to Enable SSH Server on Fedora 45 Workstation

Fedora Workstation ships the OpenSSH server installed but switched off. The moment you switch it on, the default firewall zone already lets port 22 in, and password logins are allowed. On a laptop that joins hotel and café Wi-Fi, that is a password prompt open to everyone on the network.

Original content from computingforgeeks.com - post 173053

This guide covers how to enable SSH on Fedora Workstation and lock it down in the same sitting. You will start sshd from GNOME Settings or systemctl, check what firewalld lets in, verify the host key on the first connection, switch to key authentication, and turn off password and root logins with a drop-in file. Each step was run against a second Fedora machine acting as the client, and the errors in the last section are the ones we hit along the way.

Run on Fedora 45 Workstation in October 2026, SELinux enforcing, firewalld on the default zone.

What each Fedora edition does with SSH by default

Workstation is the odd one out. Server and Cloud start sshd at boot, because they expect to be managed remotely. Workstation leaves it disabled through its systemd preset:

Editionsshd at bootFirewall and SSH
Workstationdisabled (preset)FedoraWorkstation zone allows SSH
ServerenabledFedoraServer zone allows ssh, cockpit, dhcpv6-client
Cloudenabledno firewalld installed

On Cloud images, cloud-init also writes PasswordAuthentication no into /etc/ssh/sshd_config.d/50-cloud-init.conf. Workstation has no such file. Its effective settings show what you get the moment you start the service:

sudo sshd -T | grep -iE "^(passwordauthentication|permitrootlogin|pubkeyauthentication|kbdinteractiveauthentication|port|maxauthtries) "

Passwords are on, and root may log in with a key:

Port 22
MaxAuthTries 6
PermitRootLogin prohibit-password
PubkeyAuthentication yes
PasswordAuthentication yes
KbdInteractiveAuthentication no

The KexAlgorithms line in the full output opens with mlkem768x25519-sha256, a post-quantum hybrid. You don’t have to configure it. Clients from the same OpenSSH generation negotiate it automatically, as Step 4 shows.

Step 1: Check whether SSH is running

On a fresh Workstation install, both checks come back negative:

systemctl is-enabled sshd; systemctl is-active sshd

The service is disabled and stopped:

disabled
inactive

A client that tries to connect gets refused, because nothing is listening on port 22:

ssh: connect to host ws-lab01.local port 22: Connection refused

That error is useful. “Connection refused” means the packet reached the machine and nothing answered. A firewall drop looks different: the client waits and then times out.

Step 2: Enable the SSH server

There are two ways in. Both enable the service at boot and start it now.

From GNOME Settings

Open Settings, scroll the sidebar to System, and pick Secure Shell:

GNOME Settings System panel on Fedora with the Secure Shell entry

Flip the Secure Shell switch. GNOME asks for your password through polkit, because enabling a system service needs admin rights:

polkit authentication prompt to enable remote login on Fedora Workstation

The switch stays on and the dialog shows a suggested login command:

GNOME Settings Secure Shell switch enabled on Fedora Workstation with the SSH login command

Do not rely on that ssh ws-lab01 line from another machine. Step 4 explains why the bare hostname did not resolve for us and what to use instead.

From the terminal

One command does the same thing:

sudo systemctl enable --now sshd

Confirm it is running and enabled:

systemctl status sshd --no-pager | head -12

The unit is active, enabled, and still marked preset: disabled, which tells you someone switched it on deliberately:

● sshd.service - OpenSSH server daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Mon 2026-10-05 21:48:47 EAT; 17ms ago
 Invocation: 43bd142b1e1645518df590a06265a7e9
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 7265 (sshd)
      Tasks: 1 (limit: 9415)
     Memory: 1.2M (peak: 1.3M)
        CPU: 14ms

The Settings switch did exactly this. After toggling it, systemctl is-enabled sshd returned enabled and the unit list showed the same preset mismatch.

Step 3: Check what the firewall lets in

Do not skip this step. Look at the zone your network interface is in:

firewall-cmd --get-active-zones
firewall-cmd --get-default-zone
sudo firewall-cmd --zone=FedoraWorkstation --list-all

The Workstation zone is active on the interface, allows SSH, and allows every TCP and UDP port from 1025 up:

FedoraWorkstation (default)
  interfaces: ens18
FedoraWorkstation
FedoraWorkstation (default, active)
  target: default
  ingress-priority: 0
  egress-priority: 0
  icmp-block-inversion: no
  interfaces: ens18
  sources: 
  services: dhcpv6-client samba-client ssh
  ports: 1025-65535/udp 1025-65535/tcp
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

So you never need to open port 22 on Workstation. You also can’t rely on firewalld to protect anything else you start on a high port. That is a deliberate Workstation default, and it is the reason the remaining steps matter.

The zone is assigned per NetworkManager connection, which gives you a clean way to protect a laptop on untrusted networks. Compare what three built-in zones allow:

for z in public home drop; do printf "%-7s %s\n" $z "$(firewall-cmd --zone=$z --list-services)"; done

public and home still allow SSH. drop allows nothing:

public  dhcpv6-client mdns ssh
home    dhcpv6-client mdns samba-client ssh
drop    

Put the connection you use on public Wi-Fi in the drop zone. List your connections with nmcli connection show and use the exact name. At the laptop’s own keyboard, one command does it:

sudo nmcli connection modify "Cafe Wi-Fi" connection.zone drop

If you change the zone of the connection you are logged in over, schedule an automatic undo first, so a mistake cannot lock you out. That is how we tested it on the lab machine’s wired connection:

sudo systemd-run --on-active=120 --unit=zone-revert nmcli connection modify "Wired connection 1" connection.zone ""
sudo nmcli connection modify "Wired connection 1" connection.zone drop
firewall-cmd --get-active-zones

The change applied immediately, and the established SSH session survived it:

Running timer as unit: zone-revert.timer
Will run service as unit: zone-revert.service
drop
  interfaces: ens18
FedoraWorkstation (default)

From the client, the machine vanished completely. The drop zone also blocks mDNS, so even the name stopped resolving:

ssh -o ConnectTimeout=5 [email protected] true

The client could no longer find the host at all:

ssh: Could not resolve hostname ws-lab01.local: Name or service not known

Two minutes later the timer cleared the setting and the interface went back to the default zone. When you want the change to stay, cancel the undo before it fires with sudo systemctl stop zone-revert.timer. On a real laptop, leave the café connection in drop and keep home networks on the default.

Step 4: Connect and verify the host key

Fedora Workstation runs avahi-daemon and has mdns4_minimal from nss-mdns in its hosts: lookup order, so another Workstation can reach yours by its .local name. The name is the Device Name under Settings, Sharing:

GNOME Settings Sharing panel showing the device name used for the .local SSH hostname on Fedora

Our client was a Fedora Cloud machine, which has neither by default. Install and start them on a client like that:

sudo dnf install nss-mdns
sudo systemctl enable --now avahi-daemon

Then check that the Workstation’s name resolves:

rpm -q nss-mdns avahi; systemctl is-active avahi-daemon; getent hosts ws-lab01.local >/dev/null && echo "ws-lab01.local resolves"

Both packages are present, the daemon runs, and the lookup succeeds:

nss-mdns-0.15.1-29.fc45.x86_64
avahi-0.9~rc2-9.fc45.x86_64
active
ws-lab01.local resolves

The bare name that GNOME Settings suggests did not resolve at all:

resolvectl query ws-lab01

Fedora’s systemd-resolved runs LLMNR in resolve-only mode (resolvectl llmnr prints resolve on both machines), so the Workstation never answers those queries:

ws-lab01: resolve call failed: Name 'ws-lab01' not found

Use the .local name or the IP address. Connect for the first time:

ssh [email protected]

OpenSSH has never seen this host, so it shows the key fingerprint and asks you to confirm it. The output starts with a line saying the authenticity of the host (name and address) can’t be established, followed by:

ED25519 key fingerprint is: SHA256:d742Emul7qUx7cg5PUZVQIBUr0bydQLh01prTjv/ZAM
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Answering yes stores the key in ~/.ssh/known_hosts, and OpenSSH says so in one more line. Do not type yes blindly. That fingerprint is the only thing standing between you and a machine pretending to be yours. Check it on the Workstation itself, at the console:

for k in /etc/ssh/ssh_host_*_key.pub; do ssh-keygen -lf $k; done

The ED25519 line matches what the client printed:

256 SHA256:YQvguj96YRthdQy6sBHGqnZ9D9XZWR9dU8WCIirZBy0 no comment (ECDSA)
256 SHA256:d742Emul7qUx7cg5PUZVQIBUr0bydQLh01prTjv/ZAM no comment (ED25519)
3072 SHA256:aMBnX6qAfK+3i3qf0Sk4iGmxnK616UzZmbpDtA38yg4 no comment (RSA)

Once the fingerprints match, answer yes. The client saves the key in ~/.ssh/known_hosts and never asks again unless the key changes. The verbose client log shows which key exchange was negotiated:

ssh -v -o BatchMode=yes [email protected] true 2>&1 | grep -E "Remote protocol version|kex: algorithm|kex: host key algorithm"

It was the post-quantum hybrid from the defaults:

debug1: Remote protocol version 2.0, remote software version OpenSSH_10.5
debug1: kex: algorithm: mlkem768x25519-sha256
debug1: kex: host key algorithm: ssh-ed25519

Step 5: Switch to key authentication

Generate a key on the client, not on the server. Protect it with a passphrase. A key file without one is a password written to disk:

ssh-keygen -t ed25519 -C "mercy@bastion-01"

The key pair lands in ~/.ssh:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/mercy/.ssh/id_ed25519): 
Enter passphrase for "/home/mercy/.ssh/id_ed25519" (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/mercy/.ssh/id_ed25519
Your public key has been saved in /home/mercy/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:DQFIXp54lfHDqGf0nk5NHfK7lhroODwwIiCnX55VdQ8 mercy@bastion-01

Copy the public key to the Workstation. This is the last time you type the account password over SSH:

ssh-copy-id [email protected]

The tool logs in with your password and appends the key to ~/.ssh/authorized_keys on the server:

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/mercy/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: 

Number of key(s) added: 1

Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

The next login asks for the key’s passphrase instead of the account password:

Enter passphrase for key '/home/mercy/.ssh/id_ed25519': 

Step 6: Disable password and root logins

Keep your current SSH session open until this step is finished and tested from a second terminal. If you lock yourself out anyway, the fix is at the Workstation’s own keyboard: delete the file you are about to create and reload sshd.

The Include line near the top of /etc/ssh/sshd_config pulls in every file in /etc/ssh/sshd_config.d/, in name order, before the settings below it. For most settings the first value read wins, so a low number makes sure your file comes first. List settings such as AllowUsers are the exception: every AllowUsers line in any file adds to the list. Create the drop-in:

sudo vim /etc/ssh/sshd_config.d/20-local.conf

Add these three lines, and change mercy to the accounts that should be allowed in:

PasswordAuthentication no
PermitRootLogin no
AllowUsers mercy

Test the syntax before reloading. A broken config plus a reload is how people lose access:

sudo sshd -t && echo "config OK"
sudo systemctl reload sshd

The syntax check passed:

config OK

Then confirm the effective values:

sudo sshd -T | grep -iE "^(passwordauthentication|permitrootlogin|allowusers) "

All three settings took effect:

PermitRootLogin no
PasswordAuthentication no
AllowUsers mercy

From the client, force a password-only login to prove passwords are gone:

ssh -o PubkeyAuthentication=no [email protected]

The server no longer offers password authentication at all:

[email protected]: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Key logins as mercy still worked. For root, rely on the PermitRootLogin no line in the sshd -T output above: a root login attempt without a key is refused under the old default too, so a client test proves nothing there.

The file number matters more than it looks. On our Fedora Cloud client, cloud-init writes 50-cloud-init.conf with PasswordAuthentication no. We added the opposite setting in a file numbered 99, checked the effective value, then renamed the file to 10 and checked again:

echo "PasswordAuthentication yes" | sudo tee /etc/ssh/sshd_config.d/99-passwords.conf >/dev/null
sudo sshd -T | grep -i ^passwordauthentication
sudo mv /etc/ssh/sshd_config.d/99-passwords.conf /etc/ssh/sshd_config.d/10-passwords.conf
sudo sshd -T | grep -i ^passwordauthentication
sudo rm /etc/ssh/sshd_config.d/10-passwords.conf

The last line removes the test file, because leaving it in place turns password logins back on. The 99 file was ignored, and the 10 file won:

PasswordAuthentication no
PasswordAuthentication yes

Any package or tool that drops a lower-numbered file can silently override yours. Check sshd -T after every change, not the file you edited. For brute-force protection, a non-standard port and the rest of the server hardening, follow the Fedora hardening guide. Changing the port has an SELinux step that catches people out, covered in our guide to changing the SSH port with SELinux. Hardware-backed keys are a further upgrade: see SSH with YubiKey FIDO2 keys.

SSH errors we hit on Fedora and how to fix them

Each of these came up during testing. They are listed by the exact message the client prints.

ssh: connect to host ws-lab01.local port 22: Connection refused

The machine answered, but sshd is not running. This is the Workstation default. Enable the service from Step 2 and check systemctl is-active sshd on the server.

ssh: Could not resolve hostname ws-lab01.local: Name or service not known

Two causes. The client cannot resolve mDNS names (install nss-mdns and enable avahi-daemon, as on our Cloud client), or the server’s interface is in the drop zone, which drops the incoming mDNS queries, so the host never replies. Run firewall-cmd --get-active-zones on the server. If neither applies, connect by IP address.

Permission denied (publickey,gssapi-keyex,gssapi-with-mic)

The list in brackets is what the server will accept. With passwords disabled, only a key works, so the server refuses any client that has no matching key loaded. Check three things: the user is in AllowUsers, the public key is in that user’s ~/.ssh/authorized_keys on the server, and you are offering the right key (add -i ~/.ssh/id_ed25519 to be explicit). ssh -v shows which keys the client tries.

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

We reproduced this by deleting the Workstation’s host keys and restarting sshd, which generated new ones. That is exactly what a reinstall does:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:SDmDVpvtwXYE/kUnhBGoMSxpzG6+ug3jiAx6259H9LQ.
Please contact your system administrator.
Add correct host key in /home/mercy/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/mercy/.ssh/known_hosts:3
Host key for ws-lab01.local has changed and you have requested strict checking.
Host key verification failed.

Do not delete the old entry until you know why the key changed. If you reinstalled the machine or regenerated its keys, compare the new fingerprint at the console (Step 4), then remove the stale entry on the client:

ssh-keygen -R ws-lab01.local

Every key stored for that name is removed, and a backup is kept:

# Host ws-lab01.local found: line 1
# Host ws-lab01.local found: line 2
# Host ws-lab01.local found: line 3
/home/mercy/.ssh/known_hosts updated.
Original contents retained as /home/mercy/.ssh/known_hosts.old

If nothing on the server changed, treat the warning as an attack until proven otherwise and do not connect. On a laptop that roams between networks, this is the warning that tells you someone is intercepting the connection, and it only works if you checked the fingerprint the first time.

Keep reading

Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Fedora Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Harden Fedora 45 / 44 for Desktop and Server: Complete Guide Fedora Harden Fedora 45 / 44 for Desktop and Server: Complete Guide Things to Do After Installing Fedora 44 Workstation Fedora Things to Do After Installing Fedora 44 Workstation Install COSMIC Desktop on Fedora: Spin, Atomic or dnf group Desktop Install COSMIC Desktop on Fedora: Spin, Atomic or dnf group Install Vagrant and VirtualBox on Fedora 45 / 44 Virtualization Install Vagrant and VirtualBox on Fedora 45 / 44 Install Fedora 44 Linux Step-by-Step with Screenshots Fedora Install Fedora 44 Linux Step-by-Step with Screenshots

Leave a Comment

Press ESC to close