# Understanding Failed Login Attempts with `lastb` and Securing Your Server

> Author: [Oussama Ghaieb](https://oussama.ghaieb.com/about-me)
> Canonical: https://oussama.ghaieb.com/posts/understanding-failed-login-attempts-with-lastb-and-securing-your-server

# <span class="hover:bg-yellow-100">Understanding Failed Login Attempts with `lastb` and Securing Your Server</span>

As a system administrator or hobbyist running a Linux server, keeping an eye on security is critical—especially if your machine is exposed to the internet. One powerful tool for spotting potential threats is the `lastb` command, which reveals failed login attempts. In this post, we’ll dissect a specific command—`sudo lastb -a | head -10 2>/dev/null || echo "No failed login data available"`—and use its output to highlight security risks and actionable steps to harden your server.  

## What Does the Command Do?  

Let’s break it down:  

- **`sudo lastb -a`**:  
  - `lastb` lists failed login attempts stored in `/var/log/btmp`, a binary log file tracking bad login tries (typically via SSH or local authentication).  
  - The `-a` flag appends the source IP or hostname to each entry, making it easier to track attack origins.  
  - `sudo` is required because reading `/var/log/btmp` needs elevated privileges.  

- **`| head -10`**:  
  - Pipes the output to `head -10`, limiting it to the 10 most recent failed attempts. Without this, you might get flooded with entries on a busy server.  

- **`2>/dev/null`**:  
  - Redirects any error messages (e.g., if `/var/log/btmp` is empty or inaccessible) to `/dev/null`, silencing them.  

- **`|| echo "No failed login data available"`**:  
  - If the command fails (e.g., no data exists or permissions are insufficient), this fallback prints a friendly message instead of leaving you with silence.  

Here’s a sample output from March 27, 2025:  

```bash
nobody   ssh:notty    Thu Mar 27 19:40 - 19:40  (00:00)     67.180.137.28
root     ssh:notty    Thu Mar 27 19:24 - 19:24  (00:00)     105.73.190.106
pi       ssh:notty    Thu Mar 27 18:38 - 18:38  (00:00)     2.51.27.140
pi       ssh:notty    Thu Mar 27 18:38 - 18:38  (00:00)     2.51.27.140
guest    ssh:notty    Thu Mar 27 18:22 - 18:22  (00:00)     23.121.67.63
guest    ssh:notty    Thu Mar 27 18:22 - 18:22  (00:00)     23.121.67.63
nobody   ssh:notty    Thu Mar 27 17:50 - 17:50  (00:00)     65.20.247.231
test1    ssh:notty    Thu Mar 27 17:34 - 17:34  (00:00)     65.20.205.147
test1    ssh:notty    Thu Mar 27 17:34 - 17:34  (00:00)     65.20.205.147
unknown  ssh:notty    Thu Mar 27 17:18 - 17:18  (00:00)     61.3.24.190
```  

Each line shows a failed attempt with:  
- **Username**: Common targets like `root`, `pi`, or `guest`.  
- **Connection Type**: `ssh:notty` indicates a non-interactive SSH session—typical in automated attacks where bots probe credentials without opening a shell.  
- **Timestamp**: Clustered attempts (e.g., 17:18–19:40) suggest automation.  
- **Source IP**: Geographically diverse IPs (e.g., `67.180.137.28` (US) or `105.73.190.106` (Africa)) hint at a botnet.  

## Security Risks  

These failed attempts signal real threats:  
1. **Brute-Force Attacks**: Automated scripts trying common username/password combinations.  
2. **System Takeover**: A successful breach could lead to malware installation or data theft.  
3. **Resource Abuse**: Mass attempts may slow your server or fill logs (`/var/log/btmp`).  

## How to Secure Your Server  

### 1. **Disable Root Login via SSH**  
Edit `/etc/ssh/sshd_config`:  
```plaintext
PermitRootLogin no
```  
Restart SSH: `sudo systemctl restart sshd`.  

**Why?** Forcing attackers to guess both a username *and* password raises the bar.  

---

### 2. **Enforce SSH Keys (Disable Passwords)**  
- Generate a key pair on your local machine:  
  ```sh
  ssh-keygen -t ed25519 -a 100  # Stronger than RSA
  ```  
- Copy the public key to the server:  
  ```sh
  ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server
  ```  
- Disable password logins in `/etc/ssh/sshd_config`:  
  ```plaintext
  PasswordAuthentication no
  ChallengeResponseAuthentication no
  ```  
- Restart SSH: `sudo systemctl restart sshd`.  

---

### 3. **Install and Configure Fail2Ban**  
- Install:  
  ```sh
  sudo apt install fail2ban
  ```  
- Customize `/etc/fail2ban/jail.local`:  
  ```plaintext
  [sshd]
  enabled   = true
  maxretry  = 3       # Ban after 3 failures
  bantime   = 1d      # Ban for 1 day
  ignoreip  = 192.168.1.0/24  # Whitelist your LAN
  ```  
- Restart: `sudo systemctl restart fail2ban`.  
- Verify: `sudo fail2ban-client status sshd`.  

---

### 4. **Change the SSH Port (Optional)**  
Edit `/etc/ssh/sshd_config`:  
```plaintext
Port 2222  # Replace 22 with a non-standard port
```  
Update firewall rules (`ufw`):  
```sh
sudo ufw allow 2222/tcp
sudo ufw deny 22/tcp
```  
**Note**: This is *not* a standalone fix—combine it with Fail2Ban and SSH keys.  

---

### 5. **Manage Logs and Rotate `btmp`**  
Prevent `/var/log/btmp` from growing unchecked:  
- Edit `/etc/logrotate.conf`:  
  ```plaintext
  /var/log/btmp {
      missingok
      monthly
      rotate 3
      compress
      maxsize 10M
  }
  ```  
- Test: `sudo logrotate -vf /etc/logrotate.conf`.  

---

### 6. **Investigate and Block Suspicious IPs**  
- Check IP reputation:  
  ```sh
  whois 61.3.24.190 | grep -i "country\|netname\|descr"
  curl -s "https://abuseipdb.com/check/61.3.24.190" | grep -A5 "ISP\|Usage"
  ```  
- Block manually in `/etc/hosts.deny`:  
  ```plaintext
  sshd: 61.3.24.190
  ```  
- For bulk blocking, use `ipset` or CrowdSec.  

---

### Final Thoughts  

The command `sudo lastb -a | head -10` is a quick security health check. If you see repeated failed logins:  
1. **Act immediately**: Disable weak authentication methods.  
2. **Layer defenses**: Combine SSH keys, Fail2Ban, and firewalls.  
3. **Monitor**: Schedule regular log reviews (`sudo lastb -a`) or use tools like `logwatch`.  

Stay proactive, and happy securing! 🔒
