# 🛡️SSH Brute Force Defense: A Step-by-Step Guide to Hardening Your Linux Server

Secure Shell (SSH) is the backbone of remote server management. However, its default exposed state makes it a prime target for automated **brute-force attacks**, where bots attempt to guess your login credentials.

Protecting your server isn't difficult—it just requires a few crucial steps. This guide will walk you through the essential techniques to lock down your server and significantly reduce the risk of compromise.

## 1\. Prerequisites

Before we begin, you'll need:

* A Linux server (e.g., Ubuntu, Debian, CentOS, RHEL).
    
* **Root or sudo access** to the server.
    
* **Basic familiarity** with the Linux command line and text editors like `nano` or `vim`.
    

## Section 2: Step 1 (Key-Based Authentication)

## 2\. Step 1: Switch to Key-Based Authentication 🔑

The single most effective defense is to disable password logins entirely and rely on **SSH Key Pairs**. This makes brute-force attacks virtually impossible, as guessing a key is mathematically infeasible.

### A. Generate Your Key Pair (On Your Local Machine)

If you don't already have one, generate an ED25519 key pair. This is more secure and faster than RSA.

```bash
ssh-keygen -t ed25519
```

---

* You'll be prompted to save the key. The default locations (`~/.ssh/id_ed25519` for the **private key** and `~/.ssh/id_`[`ed25519.pub`](http://ed25519.pub) for the **public key**) are usually fine.
    
* **Set a strong passphrase** for your private key.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759244949975/84ce6e8c-cbde-4a99-9342-86a22228d07f.png align="center")

### B. Copy the Public Key to the Server

Use ssh-copy-id to easily transfer your public key to your server:.

```bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub your_username@your_server_ip
```

* You will be asked for your **password** one last time.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759244914555/df657f1f-dcbf-4a3e-aff5-cb4711a41717.png align="center")

### C. Test Key-Based Login

Log out and try to log back in using your key:

```bash
ssh your_username@your_server_ip
```

* If successful, you should be prompted for your key's **passphrase** instead of your server password.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759244802964/d53244d6-4fc9-4fad-9509-4a8e74e3d93d.png align="center")

## 3\. Step 2: Disable Password Authentication

Once you confirm key-based login works, you must disable password logins to close the door on brute-force attackers.

### A. Edit the SSH Configuration File

Open the SSH daemon configuration file, typically located at `/etc/ssh/sshd_config`.

```bash
sudo nano /etc/ssh/sshd_config
```

### B. Apply Hardening Changes

Find and modify (or add) the following lines:

| Directive | Recommended Setting | Purpose |
| --- | --- | --- |
| `PasswordAuthentication` | `no` | **Crucial:** Disables all password logins. |
| `PermitRootLogin` | `no` | Prevents direct login as the **root** user. |
| `X11Forwarding` | `no` | Disable if you don't use graphical applications over SSH. |

Your changes should look like this:

```ini
# /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin no
X11Forwarding no"
```

### C. Restart the SSH Service

Apply the changes by restarting the SSH service:

**On Debian/Ubuntu:**

```bash
sudo systemctl restart ssh
```

**On CentOS/RHEL:**

```bash
sudo systemctl restart sshd
```

## 4\. Step 3: Change the Default SSH Port 🚪

Brute-force bots typically target the **default SSH port, 22**. Changing this to a non-standard, high-numbered port (e.g., 2222, 58491) won't stop a determined attacker, but it will eliminate the vast majority of automated scanning noise.

### A. Edit the SSH Configuration File

Open `/etc/ssh/sshd_config` again:

```bash
sudo nano /etc/ssh/sshd_config
```

### B. Change the Port

Find the line for `Port` and change it to a port between 1024 and 65535. For example, we'll use `2222`.

```ini
# /etc/ssh/sshd_config
Port 2222
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759235978467/146ebc8e-0b48-4b58-8c20-503a6d738a79.png align="center")

### C. Open the New Port in the Firewall

You **must** open the new port in your server's firewall *before* restarting SSH. Otherwise, you will lock yourself out!

**Using UFW (Ubuntu/Debian):**

```bash
sudo ufw allow 2222/tcp
sudo ufw delete allow 22/tcp  # Remove old port access
```

**Using firewalld (CentOS/RHEL):**

```bash
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759236099893/5a673fb2-fd4b-4ef5-abf0-35dd693b2bc4.png align="center")

**D. Restart the SSH Service**

```bash
sudo systemctl restart ssh
```

### E. Connecting to the New Port

From now on, you'll need to specify the port when connecting:

```bash
ssh -p 2222 your_username@your_server_ip
```

Successfully logged in the server with the customized port (sometimes restart may require)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1759241362185/3e97f1ef-6e28-4b88-a38f-b54ed9e5f1ac.png align="center")

## 🔧 4.1 Troubleshooting: SSH Key Authentication Issues

Switching to key-based login is secure, but you might run into connection errors when logging in from a new computer or after copying your key. Here are the most common issues and their fixes.

### A. Permission Denied (Public Key)

The most frequent error is **"Permission denied (publickey)."** This usually means the server either can't find your key or the local machine's permissions are too open.

#### **On Your Local Machine (The machine you are connecting from):**

* **Issue:** Your private key file (`id_ed25519` or `id_rsa`) has incorrect permissions. SSH requires very strict, secure permissions.
    
* **Fix:** Ensure only you can read the private key.
    
    ```bash
    chmod 400 ~/.ssh/id_ed25519
    ```
    

#### On the Server (The machine you are connecting to):

* **Issue:** The `.ssh` directory or the `authorized_keys` file on the server has incorrect permissions.
    
* **Fix:** Use these secure permissions for the key files on the server:
    
    ```bash
    # Secure the .ssh directory
    chmod 700 ~/.ssh
    
    # Secure the authorized_keys file
    chmod 600 ~/.ssh/authorized_keys
    ```
    

### B. Key Agent Issues (Key Not Found)

If you are using a new local machine or are prompted for a password instead of your key's passphrase, the system might not be aware of your key.

* **Issue:** Your key is not loaded into the **SSH agent**, which manages your keys in memory.
    
* **Fix:** Manually start the agent and add your key:
    

```bash
# Start the SSH agent
eval "$(ssh-agent -s)"

# Add your key to the agent
ssh-add ~/.ssh/id_ed25519
# You will be prompted for your key's passphrase here.
```

If you have multiple keys, try running `ssh-add -l` to see which keys are loaded.

### C. Key Mismatch or Identity Not Specified

Sometimes, the SSH client tries to use the wrong key or doesn't know which key to use for a specific server.

* **Issue:** You are not using the default key name (like `id_ed25519`) or you have multiple keys.
    
* **Fix:** Explicitly tell the client which key file to use with the `-i` flag:
    

```bash
ssh -i ~/.ssh/my_special_server_key -p 2222 your_username@your_server_ip
```

(Note: Replace `2222` with your custom port if you followed Step 3.)

## 5\. Step 4: Install and Configure Fail2ban 🤖

Even with key-based authentication, you'll still see bots knocking on your door. **Fail2ban** is an intrusion prevention software that scans log files (like your SSH logs) for repetitive failed login attempts and dynamically bans the corresponding IP addresses using the firewall.

### A. Installation

**On Debian/Ubuntu:**

```bash
sudo apt update
sudo apt install fail2ban
```

**On CentOS/RHEL:**

```bash
sudo yum install fail2ban
sudo systemctl enable fail2ban
```

### B. Basic Configuration

Fail2ban uses configuration files called **jails**. Do **not** edit the main configuration file (`/etc/fail2ban/jail.conf`). Instead, create a copy for your local overrides:

```bash
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
```

### C. Modify Jail Settings

Under the `[DEFAULT]` section, check/modify the following:

| Setting | Default/Example | Purpose |
| --- | --- | --- |
| `bantime` | `1h` (or `3600`) | How long an IP is banned (1 hour). |
| `findtime` | `10m` (or `600`) | Time window for failed attempts (10 minutes). |
| `maxretry` | `5` | Number of failed attempts before a ban. |

### D. Enable the SSH Jail

Find the SSH-specific jail, which is typically called `[sshd]`, and ensure it is enabled.

```ini
[sshd]
enabled = true
port    = 2222  # IMPORTANT: Use your custom port!
logpath = %(sshd_log)s
backend = systemd
```

E. **Start and Enable Fail2ban**

```bash
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
sudo systemctl status fail2ban
```

To see which IPs are currently banned, use:

```bash
sudo fail2ban-client status sshd
```

## Summary of Hardening Steps

By implementing these four steps, you've created a robust defense:

1. **Eliminated the weakest link:** Disabled password authentication.
    
2. **Secured the front door:** Disabled direct root login.
    
3. **Achieved security through obscurity:** Changed the default SSH port.
    
4. **Automated attack defense:** Installed and configured Fail2ban.
    

Your Linux server is now significantly hardened against the most common type of attack: the SSH brute-force bot. Stay secure! 🔒

## ✅ SSH Hardening [Checklist](https://docs.yerravalliitsimplified.com/default-guide/checklist/ssh-hardening)

* \[x\] Use key-based authentication
    
* \[x\] Disable root login
    
* \[x\] Disable PasswordAuthentication
    
* \[x\] Change default SSH port
    
* \[x\] Restrict access by IP
    
* \[x\] Install Fail2Ban
    
* \[x\] Complexity Passwdqc
    
* \[x\] Monitor logs regularly
    

## 📣 Conclusion

SSH is powerful but vulnerable if left unprotected. By following these steps, you’ll greatly reduce the risk of brute force attacks and improve your server’s security posture.

## 🎥 Watch the Full Video

### 👉Y-iT Simplified - [SSH Hardening Tutorial](https://youtu.be/EooJ87GRWFs)

### 🔔 Call-to-Action

💬 Share your questions in the comments.

👍 If you found this useful, follow me here on [Blogs](https://it-forge.yerravalliitsimplified.com/).

🎥 Don’t forget to watch the full tutorial on my **<mark>YouTube</mark>** channel:

**SSH Brute Force Defense: A Step-by-Step Guide to Hardening Your Linux Server**

<iframe width="560" height="315" src="https://www.youtube.com/embed/EooJ87GRWFs?si=wS64J-8QwYsd1Cw6"></iframe>

## 👨‍💻 About the Author

I’m **Rajesh Yerravalli**, the creator of **Yerravalli IT Simplified**.

With over 20 **years of experience in IT**—covering IT Infrastructure, Linux, Windows, Networking, Servers, Cloud, and Cybersecurity—I’m passionate about breaking down complex technical topics into simple, hands-on tutorials.

📺 Watch tutorials on YouTube: [Yerravalli IT Simplified](https://www.youtube.com/@YerravalliITSimplified) (**Y-iT Simplified)**

✍️ Read more guides here on Hashnode.
