Минимальный набор для домашнего или VPS-сервера: вход по ключу, без пароля и без прямого root по SSH. На RHEL 9 правки удобно класть в drop-in, не трогая весь /etc/ssh/sshd_config.
Важно: не закрывайте текущую сессию, пока не проверите вход во втором окне. Иначе легко остаться без доступа.
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_server
ssh-copy-id -i ~/.ssh/id_ed25519_server.pub user@server
Проверьте вход по ключу:
ssh -i ~/.ssh/id_ed25519_server user@server
mkdir -p /etc/ssh/sshd_config.d
cat > /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
X11Forwarding no
AllowTcpForwarding no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
EOF
Если нужен туннель (например, для локального проброса) — оставьте AllowTcpForwarding yes.
Проверка конфига и перезапуск:
sshd -t
systemctl reload sshd
echo 'AllowUsers youruser' >> /etc/ssh/sshd_config.d/99-hardening.conf
sshd -t && systemctl reload sshd
Смена порта снижает шум сканеров, но не заменяет ключи и Fail2ban:
echo 'Port 2222' >> /etc/ssh/sshd_config.d/99-hardening.conf
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload
sshd -t && systemctl reload sshd
Не забывайте указывать порт в клиенте: ssh -p 2222 ....
firewalld: разрешён только нужный порт SSH.PasswordAuthentication no — сверьте sshd -T | grep -i password.semanage port (пакет policycoreutils-python-utils).Итог: sshd принимает только ключи обычного пользователя — меньше поверхности для брутфорса.