# Mozilla's OpenSSH Guidelines for sshd_config Hardening on Linux Servers

> Learn Mozilla's essential OpenSSH guidelines for sshd_config hardening. Secure your Linux servers with strong cryptography and audit logging to prevent attacks.

- Repository: [IMTheNachoMan/How-To-Secure-A-Linux-Server](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server)
- Tags: best-practices
- Published: 2026-05-14

---

**Mozilla's OpenSSH hardening guidelines specify concrete `sshd_config` directives that enforce strong cryptography, eliminate weak algorithms, and enable verbose audit logging to secure SSH servers against modern cryptographic attacks.**

The imthenachoman/How-To-Secure-A-Linux-Server repository implements these recommendations verbatim in its README (lines [523‑549](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/blob/master/README.md#L523)), providing a defense‑in‑depth configuration compatible with OpenSSH 6.7 and later. These settings prioritize **elliptic‑curve cryptography** and authenticated encryption modes while disabling obsolete Diffie‑Hellman groups and weak MAC algorithms.

## Core Cryptographic Directives

Mozilla's approach hardens four critical algorithm categories in `/etc/ssh/sshd_config`. OpenSSH processes the first occurrence of each directive, so ensure these entries appear before any conflicting defaults.

### Host Key Algorithms

The **HostKey** directive establishes the order of server host key algorithms from strongest to weakest. Mozilla recommends listing Ed25519 first, followed by RSA and ECDSA:

```text
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key

```

This ensures compatible clients negotiate **Ed25519**, the current strongest public‑key algorithm, before falling back to RSA or ECDSA.

### Key Exchange Algorithms

The **KexAlgorithms** line removes weak Diffie‑Hellman groups and prioritizes elliptic‑curve key exchange to mitigate Logjam‑style attacks:

```text
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256

```

This list excludes legacy `diffie-hellman-group1-sha1` and `diffie-hellman-group14-sha1` methods that use small modulus groups.

### Encryption Ciphers

The **Ciphers** directive enables only authenticated‑encryption modes, preventing padding oracle attacks and providing built‑in integrity checking:

```text
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

```

**ChaCha20‑Poly1305** and **AES‑GCM** modes provide both confidentiality and integrity via built‑in MACs, eliminating the need for separate MAC algorithms when these ciphers are selected.

### Message Authentication Codes

The **MACs** line specifies SHA‑2 based algorithms with "encrypt‑then‑MAC" (**ETM**) mode, which resists length‑extension attacks:

```text
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

```

ETM variants (`*-etm@openssh.com`) encrypt the message before applying the MAC, preventing attackers from modifying ciphertext without detection.

## Security and Logging Restrictions

Mozilla's guidelines extend beyond cryptography to limit privilege escalation and improve audit trails.

### Verbose Authentication Logging

Setting **LogLevel VERBOSE** records the fingerprint of every authenticated key on login, creating an audit trail that identifies which specific key was used for access:

```text
LogLevel VERBOSE

```

### Privilege Separation Sandboxing

**UsePrivilegeSeparation sandbox** forces the unprivileged part of `sshd` into a restricted environment. While deprecated in OpenSSH 7.5+, this remains valuable for older distributions:

```text
UsePrivilegeSeparation sandbox

```

### Environment Variable Restrictions

**PermitUserEnvironment no** prevents users from injecting arbitrary environment variables via `ssh -o SendEnv=...`, blocking potential vectors for affecting **sudo** or other privileged command execution:

```text
PermitUserEnvironment no

```

### Internal SFTP Subsystem

Replacing external `sftp-server` with **internal-sftp** reduces attack surface and enables detailed logging of file operations:

```text
Subsystem sftp internal-sftp -f AUTHPRIV -l INFO

```

### X11 Forwarding

**X11Forwarding no** disables X11 tunneling, eliminating a common vector for X‑based attacks and cookie interception:

```text
X11Forwarding no

```

### Minimum RSA Key Size (OpenSSH 9.1+)

For OpenSSH 9.1 and later, uncomment **RequiredRSASize** to reject RSA keys smaller than 3072 bits:

```text
RequiredRSASize 3072

```

This prevents authentication with weak RSA keys that could be cracked using modern computational resources.

## Implementing the Configuration

To apply Mozilla's hardening guidelines to your server, back up the existing configuration, merge the directives, and validate syntax before reloading.

First, create a timestamped backup of `/etc/ssh/sshd_config`:

```bash
sudo cp -a /etc/ssh/sshd_config \
  /etc/ssh/sshd_config.backup.$(date +%Y%m%d%H%M%S)

```

Optionally strip comment lines to identify duplicate directives:

```bash
sudo sed -i -r '/^#|^$/d' /etc/ssh/sshd_config

```

Append the complete Mozilla configuration block using a heredoc:

```bash
sudo tee -a /etc/ssh/sshd_config > /dev/null <<'EOF'

# Mozilla OpenSSH hardening (Modern OpenSSH 6.7+)

HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key

KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256

Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

LogLevel VERBOSE
UsePrivilegeSeparation sandbox

PermitUserEnvironment no
Subsystem sftp internal-sftp -f AUTHPRIV -l INFO
X11Forwarding no

# RequiredRSASize 3072  # Uncomment for OpenSSH >=9.1

EOF

```

Test the configuration syntax to prevent lockouts:

```bash
sudo sshd -t

```

If the test returns no output, reload the daemon to apply changes:

```bash
sudo systemctl reload sshd

```

## Verifying the Configuration

Confirm your server advertises only the hardened algorithms by querying supported methods locally:

```bash
ssh -Q kex
ssh -Q cipher
ssh -Q mac

```

Verify that the output matches the Mozilla‑specified lists exactly, ensuring no weak algorithms like `diffie-hellman-group1-sha1` or `hmac-md5` remain enabled.

## Summary

Mozilla's OpenSSH hardening guidelines for `sshd_config` provide a complete defense‑in‑depth strategy:

- **HostKey** ordering prioritizes Ed25519 over RSA and ECDSA
- **KexAlgorithms** eliminates weak Diffie‑Hellman groups in favor of elliptic‑curve key exchange
- **Ciphers** restricts connections to authenticated‑encryption modes (ChaCha20‑Poly1305, AES‑GCM, AES‑CTR)
- **MACs** enforces SHA‑2 based algorithms with encrypt‑then‑MAC mode
- **LogLevel VERBOSE** creates detailed audit trails of key fingerprints
- **PermitUserEnvironment no** blocks environment variable injection attacks
- **internal-sftp** reduces attack surface compared to external SFTP servers

## Frequently Asked Questions

### Which OpenSSH versions support Mozilla's hardening guidelines?

Mozilla's **Modern OpenSSH 6.7+** recommendations require OpenSSH 6.7 or later for full compatibility. The **RequiredRSASize** directive requires OpenSSH 9.1 or later. Most current Linux distributions (Ubuntu 20.04+, RHEL 8+, Debian 10+) ship versions that support all listed algorithms except `RequiredRSASize`.

### Will these settings break compatibility with older SSH clients?

Clients running OpenSSH 6.7 or later, current versions of PuTTY, WinSCP, and modern mobile clients support all recommended algorithms. However, legacy clients using only SHA‑1 or small Diffie‑Hellman groups will fail to connect. Test with `ssh -v user@host` from the client side to verify algorithm negotiation before deploying widely.

### How do I test `sshd_config` changes without restarting the SSH service?

Use the **`sshd -t`** command to parse the configuration file and report syntax errors without applying changes. For runtime validation, spawn a second `sshd` instance on a non‑standard port (`sudo /usr/sbin/sshd -p 2222 -f /etc/ssh/sshd_config`) and test connections there before reloading the production daemon.

### What is the difference between `internal-sftp` and external `sftp-server`?

**`internal-sftp`** is a built‑in OpenSSH subsystem that runs within the `sshd` process using the user's existing authentication context, eliminating the need to execute an external binary (`/usr/lib/openssh/sftp-server`). This reduces attack surface by avoiding additional process forking and allows fine‑grained logging via the `-f AUTHPRIV -l INFO` flags specified in Mozilla's configuration.