# sshd_config: baseline for a test stand

LLMS index: [llms.txt](/en/llms.txt)

---

SSH access to a test stand often gets opened in a hurry, and then the logs fill with brute-force attempts. A baseline sshd_config that blocks common attack vectors fits into five parameters and twenty minutes.

## Why Change Defaults

Distribution-provided sshd ships with permissive settings: root login via password, no user restrictions, three authentication attempts. On a test stand this is tolerable until the logs show:

```
Failed password for root from 1.2.3.4 port 42341 ssh2
Failed password for root from 1.2.3.4 port 42342 ssh2
Failed password for root from 1.2.3.4 port 42343 ssh2
```

A local network is not a trusted network. Default configuration means risk and noise in monitoring.

## Checking Current Values

Before editing, inspect what's already set:

```bash
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|maxauthtries|allowusers)'
```

Output shows the actual values sshd will use at startup, including parameters from Match blocks.

## Four Parameters for a Test Stand

| Parameter | Value | Rationale |
|---|---|---|
| `PermitRootLogin` | `no` | Root should not log in directly |
| `AllowUsers` | `devops admin` | Whitelist, everyone else rejected |
| `PasswordAuthentication` | `no` | Keys only, passwords disabled |
| `MaxAuthTries` | `3` | Block after three failures |

> [!WARNING]
> Changes apply after `systemctl reload sshd`. Make edits via `ssh -t user@host "sudo nano /etc/ssh/sshd_config"` so you do not lose your session on a mistake.

## PermitRootLogin

Direct root login is the first thing attackers brute-force. Disable it:

```bash
sudo sed -i 's/^PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
```

If you need root access, log in as a regular user and escalate via `sudo`. This logs your actions to auth.log.

## AllowUsers

A whitelist excludes everyone not explicitly added. If a user is not in the list, sshd returns `Permission denied` before asking for a password.

```bash
echo "AllowUsers devops admin monitoring" | sudo tee -a /etc/ssh/sshd_config
```

> [!NOTE]
> Specify users space-separated. For groups use `AllowGroups`. Both parameters support patterns: `AllowUsers devops@10.0.0.*` restricts login by subnet.

## PasswordAuthentication

Keys cannot be brute-forced. Switch the setting:

```bash
sudo sed -i 's/^PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
```

Before disabling, confirm your public key is in `~/.ssh/authorized_keys` on the stand. Otherwise you lock yourself out.

## MaxAuthTries

Protection against brute force. After three failed attempts the connection drops:

```
MaxAuthTries 3
```

Setting below one disables the limit. Use 3–5 depending on your network's reliability.

## Validating Configuration

Always validate syntax after editing:

```bash
sudo sshd -t
```

Empty output means sshd will start with the new parameters. Any error prints to the screen.

Then apply:

```bash
sudo systemctl reload sshd
```

## Common Mistakes

**Editing the wrong file.** On some distributions sshd_config lives in `/etc/ssh/sshd_config.d/`. Include files are read in alphabetical order. The default `/etc/ssh/sshd_config` may be overwritten on package updates — put custom parameters in a `.conf` file with a meaningful name instead.

**Spaces after the parameter.** Syntax requires a space between key and value:

```
# Wrong
PermitRootLogin= no

# Correct
PermitRootLogin no
```

**Comments instead of parameters.** The line `#PasswordAuthentication no` is a comment, sshd ignores it. Remove the `#` or add a new line.

**Match blocks override global settings.** If a `Match User root` block exists at the end of the file, it may restore `PermitRootLogin yes` for that user. Check `sshd -T` output.

## Additional

This covers a test stand. Production adds `ClientAliveInterval 300`, `ClientAliveCountMax 2` for keepalive and `X11Forwarding no` if graphics are not needed. But deploying a minimal baseline takes four parameters and a couple of commands.
