# Linux Host Security: Top 10 Misconfigurations and a Fast Audit Playbook

> **Intro:** Most Linux security problems on cloud hosts are not exotic kernel exploits. They are ordinary, repeated, expensive mistakes: weak SSH settings, stale packages, sloppy permissions, no audit trail, and a machine that quietly drifted away from the intended baseline.
>
> **What this page includes**
>
> * ten high-value Linux misconfigurations worth checking first
> * how to detect them with fast commands and with a lightweight audit tool
> * a sample shell script for a quick host review
> * a sample report with six representative findings and short fixes
>
> **Working assumptions**
>
> * the target is a baseline Linux host in a cloud environment, often EC2
> * the goal is fast detection, triage, and remediation, not theoretical completeness
> * the audit should be safe enough to run on a live host with change control

## The top 10 Linux misconfigurations I would check first

| #  | Misconfiguration                                           | Why it is dangerous                                                                      | Fast detection                                                   |
| -- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| 1  | **PasswordAuthentication enabled in SSH**                  | Makes credential stuffing and password guessing far more useful                          | \`sshd -T                                                        |
| 2  | **PermitRootLogin enabled**                                | Gives attackers a direct admin target over SSH                                           | \`sshd -T                                                        |
| 3  | **Security updates are not applied or not automated**      | Known CVEs stay exploitable far longer than they should                                  | `apt list --upgradable` or `dnf check-update`                    |
| 4  | **Host firewall disabled or overly permissive**            | Attack surface grows well beyond the intended admin ports                                | `ufw status`, `firewall-cmd --list-all`, or `iptables -S`        |
| 5  | **auditd missing or inactive**                             | Post-incident reconstruction gets much harder                                            | `systemctl status auditd`                                        |
| 6  | **World-writable files or directories in sensitive paths** | Makes persistence and tampering easier                                                   | `find /etc /usr/local -xdev -type f -perm -0002`                 |
| 7  | **Weak permissions on private keys and SSH config**        | Private material leaks or is replaced                                                    | `stat -c '%a %n' ~/.ssh/* /etc/ssh/* 2>/dev/null`                |
| 8  | **Time sync disabled**                                     | Logs become unreliable and auth systems drift                                            | `timedatectl status`                                             |
| 9  | **Kernel/network hardening sysctls are weak**              | Increases abuse potential for ptrace, redirects, source routing, and similar abuse paths | `sysctl net.ipv4.conf.all.accept_redirects kernel.kptr_restrict` |
| 10 | **Unnecessary listening services**                         | Every open daemon is another attack surface and another patch burden                     | `ss -tulpn`                                                      |

## My preferred fast audit order

1. **SSH exposure**
2. **Patch state**
3. **Firewall**
4. **Audit and logging**
5. **Permissions**
6. **Listening services**
7. **Kernel/sysctl**
8. **Optional deeper audit with Lynis or OpenSCAP**

That order is not random. It gets you the highest-value findings early.

## Quick commands I would actually run

### SSH posture

```bash
sudo sshd -T | egrep 'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries|x11forwarding'
```

### Patch posture

```bash
# Debian / Ubuntu
sudo apt update -qq
apt list --upgradable

# RHEL / Amazon Linux
sudo dnf check-update || true
```

### Firewall

```bash
sudo ufw status verbose || true
sudo firewall-cmd --state || true
sudo iptables -S | sed -n '1,80p'
```

### Services and ports

```bash
sudo ss -tulpn
sudo systemctl list-unit-files --type=service --state=enabled
```

### auditd

```bash
sudo systemctl is-enabled auditd
sudo systemctl is-active auditd
```

### World-writable files

```bash
sudo find /etc /usr/local /opt -xdev -type f -perm -0002 2>/dev/null
```

### Time sync

```bash
timedatectl status
```

### sysctl spot checks

```bash
sysctl   kernel.kptr_restrict   kernel.yama.ptrace_scope   net.ipv4.conf.all.accept_redirects   net.ipv4.conf.all.send_redirects   net.ipv4.conf.all.rp_filter   fs.protected_hardlinks   fs.protected_symlinks
```

## Fast audit with Lynis

Lynis is useful when you want a broad host review without writing everything from scratch.

### Install

```bash
# Debian / Ubuntu
sudo apt-get update
sudo apt-get install -y lynis

# RHEL / Amazon Linux
sudo dnf install -y lynis
```

### Run

```bash
sudo lynis audit system
```

### What it gives you

* a broad system hardening review;
* warnings and suggestions;
* a quick sense of whether the host is obviously behind the expected baseline.

### What it does not do

It does not replace judgment, architecture context, or cloud-aware host review.

## Sample quick-audit script

```bash
#!/usr/bin/env bash
set -euo pipefail

echo "== SSH settings =="
sshd -T | egrep 'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries|x11forwarding' || true

echo
echo "== Patch state =="
if command -v apt >/dev/null 2>&1; then
  apt list --upgradable 2>/dev/null | sed -n '1,40p'
elif command -v dnf >/dev/null 2>&1; then
  dnf check-update || true
fi

echo
echo "== Firewall =="
ufw status verbose || true
firewall-cmd --list-all || true

echo
echo "== auditd =="
systemctl is-enabled auditd || true
systemctl is-active auditd || true

echo
echo "== Listening ports =="
ss -tulpn | sed -n '1,60p'

echo
echo "== World-writable files =="
find /etc /usr/local /opt -xdev -type f -perm -0002 2>/dev/null | sed -n '1,40p'

echo
echo "== Time sync =="
timedatectl status | sed -n '1,15p'
```

## Sample report

```
Host: ip-10-42-8-17
Audit timestamp: 2026-03-27T19:42:18Z

[HIGH] SSH password authentication enabled
  Evidence: passwordauthentication yes

[HIGH] SSH root login permitted
  Evidence: permitrootlogin yes

[MEDIUM] Host firewall inactive
  Evidence: ufw status -> inactive

[MEDIUM] auditd not enabled
  Evidence: systemctl is-enabled auditd -> disabled

[MEDIUM] 37 packages pending upgrade
  Evidence: apt list --upgradable

[LOW] World-writable file found
  Evidence: /usr/local/bin/deploy-helper.sh mode 0777
```

## How to read that report

<details>

<summary><strong>1) SSH password authentication enabled</strong></summary>

**What it means**\
The host accepts password-based SSH login.

**Why it is dangerous**\
This drastically lowers the cost of brute-force and credential stuffing attacks.

**Short fix**\
Set `PasswordAuthentication no`, validate that key-based or SSM-based access works, then reload SSH.

```bash
sudo sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl reload sshd
```

</details>

<details>

<summary><strong>2) SSH root login permitted</strong></summary>

**What it means**\
The most privileged account is directly reachable over SSH.

**Why it is dangerous**\
It gives attackers a single high-value target and weakens accountability.

**Short fix**\
Set `PermitRootLogin no` or at least `prohibit-password`, then verify admin access through named users or SSM.

```bash
sudo sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sudo systemctl reload sshd
```

</details>

<details>

<summary><strong>3) Host firewall inactive</strong></summary>

**What it means**\
The host is relying entirely on upstream controls such as security groups.

**Why it is dangerous**\
Defense-in-depth disappears. A later cloud-side mistake exposes the box immediately.

**Short fix**\
Enable the host firewall and keep the rules narrow.

```bash
sudo ufw allow OpenSSH
sudo ufw enable
```

</details>

<details>

<summary><strong>4) auditd not enabled</strong></summary>

**What it means**\
Security-relevant events are not being captured consistently.

**Why it is dangerous**\
Detection quality drops and incident reconstruction becomes guesswork.

**Short fix**\
Install and enable `auditd`, then add a minimal ruleset.

```bash
sudo apt-get install -y auditd audispd-plugins
sudo systemctl enable --now auditd
```

</details>

<details>

<summary><strong>5) Many packages pending upgrade</strong></summary>

**What it means**\
The host is carrying known bugs and often known vulnerabilities.

**Why it is dangerous**\
Exploitability rises over time, especially on internet-facing systems.

**Short fix**\
Patch on a schedule, validate workload compatibility, and enable unattended security updates where appropriate.

</details>

<details>

<summary><strong>6) World-writable deployment helper</strong></summary>

**What it means**\
Any local user or compromised service account may be able to modify executable logic.

**Why it is dangerous**\
This is a classic persistence and privilege pivot path.

**Short fix**\
Reset ownership and mode immediately.

```bash
sudo chown root:root /usr/local/bin/deploy-helper.sh
sudo chmod 0755 /usr/local/bin/deploy-helper.sh
```

</details>

## Common failure patterns in Linux audits

1. **Running checks without root**, then assuming “no output” means “no issue”.
2. **Checking SSH config files only**, instead of using `sshd -T` to see the effective settings.
3. **Looking only at the cloud firewall**, ignoring host-level exposure.
4. **Treating package count as the only patch metric**, instead of looking at the actual severity mix.
5. **Forgetting the systemd state**, where a package is installed but the service is still disabled.
6. **Running the audit once** and never comparing it against a known-good baseline.

## Where I would start remediating

If I inherited a messy host today, I would fix in this order:

1. SSH auth and admin access model
2. firewall and exposure
3. patching and reboot planning
4. auditd and central logs
5. permissions drift
6. unnecessary services
7. sysctl and hardening residue

That order gives you a fast reduction in real risk.

## Cross-links

* [Linux Base Image and Host Security Baseline](/cloud-kubernetes-and-infrastructure-security/index/linux-base-image-and-host-security-baseline.md)
* [Ansible for EC2 Host Security: 7 High-Value Tasks That Actually Matter](/cloud-kubernetes-and-infrastructure-security/index/ansible-for-ec2-host-security-7-high-value-tasks.md)
* [Ansible Security Baseline and Top 10 Misconfigurations](/cloud-kubernetes-and-infrastructure-security/index/ansible-security-baseline-and-misconfigurations.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/cloud-kubernetes-and-infrastructure-security/index/linux-express-audit-and-top-misconfigurations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
