SSH on Fedora: service configuration, key-based login and hardening
sshd configuration on Fedora is laid out differently from most distributions: the main file is nearly empty and the real configuration lives in sshd_config.d/*.conf. On top of that, crypto-policies owns the cipher suite, so copying online tutorials often changes nothing.
Measured on F45.
Version and where the configuration lives
Section titled “Version and where the configuration lives”rpm -q openssh-serversudo grep -vE "^#|^$" /etc/ssh/sshd_configopenssh-server-10.5p1-1.fc45.x86_64
Include /etc/ssh/sshd_config.d/*.confAuthorizedKeysFile .ssh/authorized_keysSubsystem sftp /usr/libexec/openssh/sftp-serverThe main file has three effective lines. Everything else is in the drop-in directory:
sudo ls /etc/ssh/sshd_config.d/40-redhat-crypto-policies.conf50-cloud-init.conf50-redhat.confWhich means: put your changes in a new 99-*.conf — do not touch the main file, and do not touch the 40- one.
crypto-policies overrides your cipher settings
Section titled “crypto-policies overrides your cipher settings”Look at 40-redhat-crypto-policies.conf:
sudo cat /etc/ssh/sshd_config.d/40-redhat-crypto-policies.conf# This system is following system-wide crypto policy. The changes to# crypto properties (Ciphers, MACs, ...) will not have any effect in# this or following included files. ...In other words: writing Ciphers, MACs or KexAlgorithms into sshd_config.d/ mostly does nothing, because the system-wide crypto policy decides first. For a stricter suite, change the policy:
update-crypto-policies --showDEFAULTsudo update-crypto-policies --set FUTURE # stricter suite set, takes effect on rebootsudo update-crypto-policies --set DEFAULT # revertSee the configuration that actually applies
Section titled “See the configuration that actually applies”Do not read files; read the effective values:
sudo sshd -TPort 22AddressFamily anyListenAddress [::]:22sshd -T expands includes and defaults into the final configuration. This is always step one in troubleshooting, not reading file by file.
The client side has the same tool:
ssh -G <host> | grep -E "^(user|port|identityfile|proxyjump)"Key-based login
Section titled “Key-based login”Generate an ed25519 pair (shorter and faster than RSA; what OpenSSH 10 recommends):
ssh-keygen -t ed25519 -C "alice@laptop"+----[SHA256]-----+ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHiplpcIlutsQhEAyomGV8+ntl2VIaba3xiHIsrxRY2A alice@laptopFile permissions:
ls -l ~/.ssh/-rw-------. 1 labuser labuser 97 Oct 25 17:37 authorized_keysThe rules are rigid: private key 600, authorized_keys and config 600, the .ssh directory 700. If permissions are too open, sshd ignores the file and logs a line — which shows up as “the key is uploaded but it still asks for a password”.
Copy the key to the server:
ssh-copy-id alice@serverIt appends the public key to ~/.ssh/authorized_keys and fixes the permissions.
Key files and permissions at a glance
Section titled “Key files and permissions at a glance”| Path | Mode | Note |
|---|---|---|
~/.ssh | 700 | too open and sshd ignores it |
~/.ssh/id_ed25519 | 600 | the private key, never shared |
~/.ssh/id_ed25519.pub | 644 | public key, safe to distribute |
~/.ssh/authorized_keys | 600 | server-side public keys |
/etc/ssh/sshd_config | 600 | main config (three lines on Fedora) |
/etc/ssh/sshd_config.d/*.conf | 600 | the drop-ins that actually apply |
/etc/ssh/ssh_host_*_key | 600 | host private keys — back them up or clients will see a fingerprint change |
Minimal hardening checklist
Section titled “Minimal hardening checklist”Write a new file; do not edit the main configuration:
sudo tee /etc/ssh/sshd_config.d/99-hardening.conf >/dev/null <<'EOF'PermitRootLogin noPasswordAuthentication noKbdInteractiveAuthentication noMaxAuthTries 3ClientAliveInterval 300ClientAliveCountMax 2EOFsudo sshd -t # syntax check, alwayssudo systemctl reload sshdsshd -t only validates; on a typo it points at the line number. Reloading without running -t is how people lock themselves out.
On Cloud images this is already the default:
sudo cat /etc/ssh/sshd_config.d/50-cloud-init.confPasswordAuthentication noPorts, firewall and SELinux
Section titled “Ports, firewall and SELinux”Changing the port takes three steps, not one:
sudo tee /etc/ssh/sshd_config.d/99-port.conf >/dev/null <<'EOF'Port 2222EOFsudo sshd -t && sudo systemctl reload sshdDo not forget the firewall and SELinux:
sudo firewall-cmd --permanent --add-port=2222/tcp && sudo firewall-cmd --reloadsudo semanage port -a -t ssh_port_t -p tcp 2222Change only sshd and the result is “configured correctly, still cannot connect”. See firewalld and SELinux.
Troubleshooting order
Section titled “Troubleshooting order”ss -tlnp | grep :22 # 1) is it listeningsudo sshd -T | head -5 # 2) what configuration appliessudo sshd -t # 3) is the syntax validjournalctl -u sshd -n 30 --no-pager # 4) why authentication failedsudo ausearch -m AVC -ts recent # 5) is SELinux blocking itIn step 4, Failed publickey for alice and Invalid user are completely different problems: the first is a wrong key or over-permissive permissions, the second is a user that does not exist.
Related pages
Section titled “Related pages”- Users and permissions — accounts and sudo
- firewalld — opening ports
- SELinux — the
ssh_port_ttype - Error lookup —
Badly formatted port number,Invalid RSA key length - Cheat sheet — networking and service commands
- Official: OpenSSH