Warning

Don’t just copy and paste a config from somewhere and just load it. It will break everything :)

Preperations

Regenerate Host keys

rm -f /etc/ssh/ssh_host_*
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""

Remove short modulis for DH

Does not make a difference for the config below, as DH is not used, still recommended otherwise.

awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.tmp 
mv /etc/ssh/moduli.tmp /etc/ssh/moduli

The Config

# Basics
Port 22
Protocol 2
ListenAddress 0.0.0.0
#ListenAddress ::

# No Login with root
PermitRootLogin no

# Only key-based login
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

# Limit SSH Login to certain user group
AllowGroups ssh-login
IgnoreRhosts yes

# Max Login tries
MaxAuthTries 3

# Disable Message of the day
PrintMotd no
DebianBanner no

# Keys & Ciphers
# Limit to secure ciphers & use of ed25519 curve
HostKey /etc/ssh/ssh_host_ed25519_key
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
KexAlgorithms curve25519-sha256@libssh.org

# Disable compression to prevent potential sec issues with encryption
Compression no

# Forwarding
# Will have to be adjusted when using the host as a jumphost / explicitly for forwarding
AllowAgentForwarding no
AllowTcpForwarding no
AllowStreamLocalForwarding no
DisableForwarding yes
PermitTunnel no
GatewayPorts no
X11Forwarding no

# Logging --> Also logs the user's fingerprint
LogLevel VERBOSE

# use internal sftp
Subsystem sftp internal-sftp

# no reverse DNS lookups
UseDNS no

TCPKeepAlive no

# Locales
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

Notes

Change the SSH Port!

Yes, but NMAP! Yes, you can detect anomalies, and a bunch of false positives. It’s recommended, well …

References