OpenSSH
OpenSSH (Open Secure Shell) is a suite of secure networking utilities based on the Secure Shell (SSH) protocol. It provides encrypted communication sessions over a computer network and replaces insecure tools like telnet, rlogin, and rcp. This guide covers both client and server usage with a focus on security best practices.
OpenSSH Security Guide: Comprehensive Manual and Best Practices
Remember to test your configuration thoroughly with
sshd -t
before applying changes to avoid locking yourself out of your server.
Table of Contents
- Core Components
- Key SSH Commands
- Configuration Files
- Authentication Methods
- Securing OpenSSH
- Advanced Configuration
- Troubleshooting
- Additional Resources
Core Components
OpenSSH consists of several key components:
- sshd: The SSH server daemon that allows incoming SSH connections
- ssh: The SSH client for connecting to remote machines
- ssh-keygen: Tool for generating and managing SSH keys
- ssh-agent: Agent for storing private keys for authentication
- ssh-add: Tool for adding keys to the ssh-agent
- scp: Secure copy program for transferring files
- sftp: Secure FTP for file transfers with more functionality than scp
Key SSH Commands
Basic SSH Connection
1
2
3
4
5
6
# Connect to a remote server
ssh username@hostname
# Example:
ssh [email protected]
ssh [email protected]
Specifying a Port
1
2
3
4
5
# Connect to a non-standard SSH port
ssh -p 2222 username@hostname
# Example:
ssh -p 2222 [email protected]
Using Key-Based Authentication
1
2
3
4
5
# Connect using a specific private key
ssh -i ~/.ssh/id_ed25519 username@hostname
# Example:
ssh -i ~/.ssh/server_key [email protected]
X11 Forwarding (GUI Applications)
1
2
3
4
5
6
7
# Forward X11 to run graphical applications remotely
ssh -X username@hostname
# Example:
ssh -X [email protected]
# Then run a GUI application
firefox &
Port Forwarding (Local)
1
2
3
4
5
6
# Forward local port to remote server
ssh -L local_port:destination_host:destination_port username@hostname
# Example: Forward local port 8080 to remote web server on port 80
ssh -L 8080:localhost:80 [email protected]
# Now access the remote web server by browsing to http://localhost:8080
Port Forwarding (Remote)
1
2
3
4
5
6
# Forward remote port to local machine
ssh -R remote_port:destination_host:destination_port username@hostname
# Example: Allow remote access to a local web server
ssh -R 8080:localhost:3000 [email protected]
# Remote users can now access your local server on port 3000 by connecting to localhost:8080 on the remote machine
Running a Command on a Remote Host
1
2
3
4
5
6
# Execute a command without logging in interactively
ssh username@hostname "command args"
# Example:
ssh [email protected] "uptime"
ssh [email protected] "ls -la /var/log"
Secure File Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Copy a local file to remote server
scp file.txt username@hostname:/path/to/destination
# Example:
scp document.pdf [email protected]:/home/john/documents/
# Copy a remote file to local machine
scp username@hostname:/path/to/file.txt local_destination
# Example:
scp [email protected]:/home/john/logs/system.log ./downloaded_logs/
# Copy entire directories with the -r flag
scp -r local_directory username@hostname:/path/to/destination
scp -r username@hostname:/path/to/directory local_destination
Configuration Files
Client-Side Configuration Files
- ~/.ssh/config: User-specific SSH client configuration
- /etc/ssh/ssh_config: System-wide client configuration
Example ~/.ssh/config file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Default settings for all hosts
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
HashKnownHosts yes
IdentitiesOnly yes
# Specific settings for a host
Host myserver
HostName 192.168.1.100
User john
Port 2222
IdentityFile ~/.ssh/myserver_key
# Example for connecting via a jump host
Host internal-server
HostName 10.0.0.5
User admin
ProxyJump jumphost.example.com
Server-Side Configuration Files
- /etc/ssh/sshd_config: SSH daemon configuration file
- /etc/ssh/sshd_config.d/: Directory for modular configuration files
Example /etc/ssh/sshd_config file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Basic SSH server configuration
Port 22
ListenAddress 0.0.0.0
Protocol 2
# Authentication settings
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
# Logging
SyslogFacility AUTH
LogLevel INFO
# Security settings
MaxAuthTries 3
LoginGraceTime 60
PermitEmptyPasswords no
Authentication Methods
Password Authentication
The basic authentication method where users provide their system password.
1
2
# Default SSH connection will prompt for password
ssh username@hostname
Public Key Authentication
A more secure method using cryptographic keys:
- Generate a key pair:
1 2 3 4 5 6 7 8
# Generate a modern Ed25519 key ssh-keygen -t ed25519 -C "[email protected]" # Generate an RSA key with 4096 bits (for compatibility with older systems) ssh-keygen -t rsa -b 4096 -C "[email protected]" # Generate a key with a specific filename ssh-keygen -t ed25519 -f ~/.ssh/myserver_key -C "access to myserver"
- Copy public key to the server:
1 2 3 4 5 6 7 8
# Automated way using ssh-copy-id ssh-copy-id -i ~/.ssh/id_ed25519.pub username@hostname # Example: ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected] # Manual method if ssh-copy-id is not available cat ~/.ssh/id_ed25519.pub | ssh username@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
- Verify key-based authentication:
1 2 3 4 5 6 7 8
# Try connecting with the key ssh -i ~/.ssh/id_ed25519 username@hostname # If your key has the default name, you don't need to specify it ssh username@hostname # Testing with verbose output to see authentication methods used ssh -v username@hostname
Using SSH Agent
1
2
3
4
5
6
7
8
9
10
11
12
# Start the SSH agent and add your keys
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519
# Add a key with a specific timeout (3600 seconds = 1 hour)
ssh-add -t 3600 ~/.ssh/id_ed25519
# List currently loaded keys
ssh-add -l
# Delete all keys from the agent
ssh-add -D
Securing OpenSSH
Server-Side Security Best Practices
Use Modern Protocol and Ciphers
Edit /etc/ssh/sshd_config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Only use SSHv2 protocol Protocol 2 # Use secure ciphers Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr # Secure host key algorithms HostKeyAlgorithms ssh-ed25519,ssh-rsa # Secure key exchange algorithms KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256 # Secure MACs (Message Authentication Codes) MACs [email protected],[email protected],[email protected]
Apply changes:
1
sudo systemctl restart sshd
Disable Root Login
Edit /etc/ssh/sshd_config:
1
PermitRootLogin no
Apply changes:
1
sudo systemctl restart sshd
Disable Password Authentication (after setting up key-based auth)
Edit /etc/ssh/sshd_config:
1 2
PasswordAuthentication no ChallengeResponseAuthentication no
Apply changes:
1
sudo systemctl restart sshd
Limit User Access
Edit /etc/ssh/sshd_config:
1 2 3 4 5 6 7 8 9 10 11
# Allow only specific users AllowUsers john mary admin # Or allow only specific groups AllowGroups sshusers admins # Block specific users DenyUsers guest test # Block specific groups DenyGroups guests
Create an SSH group and add users to it:
1 2
sudo groupadd sshusers sudo usermod -a -G sshusers john
Change Default Port (helps avoid automated attacks)
Edit /etc/ssh/sshd_config:
1
Port 2222
Update firewall rules (example using UFW):
1 2
sudo ufw allow 2222/tcp sudo ufw reload
Apply changes:
1
sudo systemctl restart sshd
Disable Empty Passwords
Edit /etc/ssh/sshd_config:
1
PermitEmptyPasswords no
Implement Connection Timeouts
Edit /etc/ssh/sshd_config:
1 2 3 4 5 6 7 8
# Server will send a keep-alive message every 300 seconds ClientAliveInterval 300 # Server will disconnect after 2 failed keep-alive responses (10 minutes total) ClientAliveCountMax 2 # User has 60 seconds to authenticate before connection is closed LoginGraceTime 60
Limit Authentication Attempts
Edit /etc/ssh/sshd_config:
1 2 3 4 5
# Allow maximum 3 authentication attempts per connection MaxAuthTries 3 # Allow 3 unauthenticated connections, 50% probability of refusing above that, max 10 MaxStartups 3:50:10
Disable Unused Features
Edit /etc/ssh/sshd_config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Disable X11 forwarding if not needed X11Forwarding no # Disable TCP forwarding if not needed AllowTcpForwarding no # Disable tunneling if not needed PermitTunnel no # Disable agent forwarding if not needed AllowAgentForwarding no # Disable gateway ports GatewayPorts no
Restrict SSH to Specific Interfaces (if necessary)
Edit /etc/ssh/sshd_config:
1 2 3 4 5 6
# Only listen on specific IP address ListenAddress 192.168.1.100 # Multiple listen addresses can be specified (IPv4 and IPv6) ListenAddress 10.0.0.1 ListenAddress 2001:db8::1
Set Proper File Permissions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# User's SSH directory chmod 700 ~/.ssh # Public keys chmod 644 ~/.ssh/id_ed25519.pub # Private keys chmod 600 ~/.ssh/id_ed25519 # Authorized keys chmod 600 ~/.ssh/authorized_keys # Known hosts chmod 644 ~/.ssh/known_hosts # Server host keys sudo chmod 640 /etc/ssh/ssh_host_*_key sudo chmod 644 /etc/ssh/ssh_host_*_key.pub
Use SSH Key Certificates (for larger deployments)
1 2 3 4 5 6 7 8 9 10 11
# On CA machine: Create a CA key ssh-keygen -t ed25519 -f ssh_ca_key # Sign user key with the CA, valid for 52 weeks, for user "john" ssh-keygen -s ssh_ca_key -I "john_laptop" -n john -V +52w id_ed25519.pub # On server: Add the CA public key to trusted CAs echo "ssh-ed25519 AAAA..." > /etc/ssh/ca.pub # In /etc/ssh/sshd_config: TrustedUserCAKeys /etc/ssh/ca.pub
Enable Key Revocation
Create and populate the revocation list:
1 2 3 4 5 6 7 8
# Create the revoked keys file sudo touch /etc/ssh/revoked_keys # Add a revoked key (copy the full public key line) echo "ssh-ed25519 AAAA..." | sudo tee -a /etc/ssh/revoked_keys # In /etc/ssh/sshd_config: RevokedKeys /etc/ssh/revoked_keys
Use Two-Factor Authentication (2FA)
Install and configure Google Authenticator:
1 2 3 4 5 6 7
# Install the package sudo apt install libpam-google-authenticator # Run the initialization tool as the user who needs 2FA google-authenticator # Follow the prompts, scan QR code with your authenticator app
Configure PAM:
1 2 3
# Edit /etc/pam.d/sshd # Add this line at the top: auth required pam_google_authenticator.so
Configure SSH:
1 2 3
# In /etc/ssh/sshd_config: ChallengeResponseAuthentication yes AuthenticationMethods publickey,keyboard-interactive
Apply changes:
1
sudo systemctl restart sshd
Client-Side Security Best Practices
Create a Custom SSH Configuration
Create or edit ~/.ssh/config:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
# Default settings for all connections Host * # Use IPv4 only AddressFamily inet # Hash hostnames and addresses in known_hosts HashKnownHosts yes # Only use the specified identity file IdentitiesOnly yes # Keep connection alive ServerAliveInterval 60 # Compression may improve speed on slow connections Compression yes # Specific host configuration Host myserver HostName example.com User myusername Port 2222 IdentityFile ~/.ssh/id_ed25519 # Example for using a jump host Host internal HostName 10.0.0.5 User admin ProxyJump jumphost.example.com # Shortcut for common parameters Host dev HostName dev-server.example.com User developer ForwardAgent yes # Match pattern example Host *.example.com User admin IdentityFile ~/.ssh/example_key
Use SSH Key with Passphrase
1 2 3 4 5 6 7
# Generate a key with increased KDF rounds for stronger protection ssh-keygen -t ed25519 -a 100 -C "comment" # When prompted, enter a strong passphrase # Change passphrase for an existing key ssh-keygen -p -f ~/.ssh/id_ed25519
Use SSH-Agent with Timeouts
1 2 3 4 5 6 7 8 9 10 11
# Start agent if not running eval $(ssh-agent) # Add key with 1-hour timeout ssh-add -t 3600 ~/.ssh/id_ed25519 # For macOS Keychain integration (remembers passphrase) ssh-add -K ~/.ssh/id_ed25519 # For temporary access to a specific key ssh -o "IdentityAgent none" -i ~/.ssh/specific_key username@hostname
Keep Your SSH Client Updated
1 2 3 4 5 6 7 8 9 10 11
# Debian/Ubuntu sudo apt update && sudo apt upgrade openssh-client # RHEL/CentOS sudo yum update openssh-clients # Fedora sudo dnf update openssh-clients # macOS brew update && brew upgrade openssh
Configure Known Hosts Verification
Edit ~/.ssh/config:
1 2 3 4 5 6 7 8
# Strict checking rejects connections if host key changed StrictHostKeyChecking yes # Use DNS to verify host keys if available VerifyHostKeyDNS yes # Visual host key fingerprint VisualHostKey yes
Advanced Configuration
SSH Certificates for Authentication
- Create a CA key:
1 2 3 4
# Create a certificate authority key ssh-keygen -t ed25519 -f ~/ca # Use a strong passphrase when prompted
- Sign a user key:
1 2 3 4 5 6 7 8 9 10
# Sign a user's public key ssh-keygen -s ~/ca -I "john_laptop" -n john -V +52w id_ed25519.pub # This creates id_ed25519-cert.pub # Options explained: # -s ~/ca : Sign using this CA key # -I "john_laptop" : Identity/comment for this certificate # -n john : Username(s) this certificate is valid for # -V +52w : Valid for 52 weeks from now
- Add the public CA key to server:
1 2 3 4 5 6 7 8 9 10 11
# Copy CA public key to server scp ~/ca.pub admin@server:/tmp/ # On server sudo cp /tmp/ca.pub /etc/ssh/ca.pub # In /etc/ssh/sshd_config TrustedUserCAKeys /etc/ssh/ca.pub # Apply changes sudo systemctl restart sshd
Jump Hosts (Bastion Hosts)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Direct in command line
ssh -J jumpuser@jumphost targetuser@targethost
# Multiple jumps
ssh -J user1@host1,user2@host2 user3@destination
# Example: Access private network behind a jump host
ssh -J [email protected] [email protected]
# In ~/.ssh/config
Host targethost
HostName 10.0.0.2
User targetuser
ProxyJump jumpuser@jumphost
# Example with multiple jumps in config file
Host private-server
HostName 192.168.1.50
User admin
ProxyJump jumphost1,jumphost2
Host jumphost1
HostName public1.example.com
User jumpuser1
Host jumphost2
HostName 10.10.0.1
User jumpuser2
SSH Multiplexing (Connection Sharing)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# In ~/.ssh/config
Host *
# Enable multiplexing
ControlMaster auto
# Path for control socket
ControlPath ~/.ssh/control:%h:%p:%r
# Keep socket open for 10 minutes after last connection closes
ControlPersist 10m
# Example usage:
# First connection creates the master connection
ssh server.example.com
# Subsequent connections reuse the existing connection (faster)
ssh server.example.com
scp file.txt server.example.com:/tmp/
# Force a new connection if needed
ssh -o ControlPath=none server.example.com
# Check for existing connections
ssh -O check server.example.com
# Close a persistent connection
ssh -O exit server.example.com
Restricting with SSH Keys
Specify commands or restrictions in authorized_keys:
1
2
3
4
5
6
7
8
9
10
11
# Edit ~/.ssh/authorized_keys and prepend the key with restrictions
command="uptime",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA...
# Full example for a backup user limited to rsync
command="rsync --server --sender -vlogDtpre.iLsfxC . /backup",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAA...
# Example to only allow specific source IP addresses
from="192.168.1.0/24,10.0.0.5" ssh-ed25519 AAAA...
# Combine restrictions (monitoring user that can only run specific commands)
from="10.0.0.0/24",command="uptime",no-pty,no-X11-forwarding ssh-ed25519 AAAA...
Using Fail2ban to Protect SSH
Install and configure Fail2ban to block repeated login attempts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Install Fail2ban
sudo apt install fail2ban
# Create a custom configuration
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
action = iptables-multiport[name=ssh, port="ssh"]
# For custom SSH port add:
port = 2222
# Apply changes
sudo systemctl restart fail2ban
# Check status
sudo fail2ban-client status sshd
# Unban an IP if needed
sudo fail2ban-client set sshd unbanip 192.168.1.5
Troubleshooting
Verbose Logging
Increase verbosity with -v flag (up to -vvv):
1
2
3
4
5
6
7
8
# Basic verbose logging
ssh -v username@hostname
# Very verbose logging
ssh -vvv username@hostname
# Example for debugging authentication issues
ssh -vvv -i ~/.ssh/id_ed25519 [email protected]
Common Error Messages
Permission denied (publickey)
Check key permissions:
1 2 3 4 5 6 7 8 9 10
# Fix permissions on ~/.ssh directory chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 600 ~/.ssh/authorized_keys # Verify the key is being offered ssh -vvv username@hostname # Check authorized_keys file for correct entry cat ~/.ssh/authorized_keys
Connection refused
Check server status:
1 2 3 4 5 6 7 8
# On the server, check if sshd is running sudo systemctl status sshd # Check firewall rules sudo iptables -L | grep ssh # Check netstat to see if the port is listening sudo netstat -tulpn | grep ssh
Host key verification failed
Fix host key verification:
1 2 3 4 5 6 7 8 9 10
# Remove the offending key from known_hosts ssh-keygen -R hostname # Or edit ~/.ssh/known_hosts manually # For when using HashKnownHosts, find the hash of the hostname ssh-keygen -H -F hostname # Accept new host key ssh -o StrictHostKeyChecking=accept-new username@hostname
Debugging Server Issues
- Check sshd service status:
1 2 3 4 5
# Check service status sudo systemctl status sshd # View recent logs sudo journalctl -u sshd --since "1 hour ago"
- Test configuration before restarting:
1 2 3 4 5 6 7 8
# Test configuration for errors sudo sshd -t # For more verbose output sudo sshd -T # Show all actual configuration settings sudo sshd -T | grep -i "passwordauthentication"
- Check logs for issues:
1 2 3 4 5 6 7 8
# Ubuntu/Debian systems sudo tail -f /var/log/auth.log | grep sshd # RHEL/CentOS systems sudo tail -f /var/log/secure | grep sshd # Using journalctl sudo journalctl -f -u sshd
Additional Resources
- OpenSSH Official Documentation
- Mozilla SSH Guidelines
- SSH.com Security Best Practices
- Man pages:
man ssh
,man sshd
,man ssh_config
,man sshd_config
Slim OpenSSH Server Configuration Guide
Settings to Comment Out or Disable
Disable Unnecessary Features
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Disable X11 forwarding
X11Forwarding no
# Disable TCP port forwarding if not needed
AllowTcpForwarding no
# Disable SSH agent forwarding
AllowAgentForwarding no
# Prevent listening on forwarded ports
GatewayPorts no
# Disable tunneling features
PermitTunnel no
# Disable permitopen for port forwarding
PermitOpen none
# Disable compression (saves CPU resources)
Compression no
# Disable banner messages
#Banner /etc/issue.net
# Don't print the message of the day
PrintMotd no
# Disable SFTP subsystem if file transfers not needed
#Subsystem sftp /usr/lib/openssh/sftp-server
# Disable reverse DNS lookups (improves connection time)
UseDNS no
# Disable custom environment variable setting
PermitUserEnvironment no
# Disable .rhosts files
IgnoreRhosts yes
# Disable user's ~/.ssh/known_hosts for RhostsRSAAuthentication
HostbasedAuthentication no
Streamline Cryptographic Options
Limit to modern, secure algorithms to reduce overhead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Only use ED25519 host keys (comment out other key types)
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
# Limit to modern ciphers
Ciphers [email protected],[email protected]
# Limit key exchange algorithms
KexAlgorithms [email protected],curve25519-sha256
# Limit MAC algorithms
MACs [email protected],[email protected]
# Limit authentication methods to public key only
AuthenticationMethods publickey
# Disable less secure authentication methods
PasswordAuthentication no
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
Security Hardening Settings to Keep
These settings don’t add much overhead but provide important security benefits:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Enforce protocol 2 only
Protocol 2
# Log more details for security monitoring
LogLevel VERBOSE
# Disable empty passwords
PermitEmptyPasswords no
# Disable root login
PermitRootLogin no
# Limit authentication attempts
MaxAuthTries 3
# Timeout settings
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
# Allow only specific users (customize as needed)
AllowUsers user1 user2
Complete Example Configuration
A complete minimal sshd_config
file might look like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Minimal secure OpenSSH server configuration
# Protocol and basic settings
Protocol 2
Port 22
AddressFamily inet
ListenAddress 0.0.0.0
# Authentication
HostKey /etc/ssh/ssh_host_ed25519_key
AuthenticationMethods publickey
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
PermitRootLogin no
MaxAuthTries 3
AllowUsers user1 user2
# Cryptographic settings
Ciphers [email protected],[email protected]
KexAlgorithms [email protected],curve25519-sha256
MACs [email protected],[email protected]
# Timeout settings
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
# Features to disable
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
GatewayPorts no
PermitTunnel no
PermitOpen none
Compression no
UseDNS no
PrintMotd no
PermitUserEnvironment no
IgnoreRhosts yes
HostbasedAuthentication no
# Logging
LogLevel VERBOSE
Memory and Performance Optimizations
Beyond configuration, you can optimize the OpenSSH daemon itself:
- Use minimal system libraries when compiling OpenSSH
- Run OpenSSH with reduced privileges
- Consider disabling unused authentication methods at compile time
- On resource-constrained systems, consider using lightweight alternatives like Dropbear SSH