# How to install and schedule server_audit_notify.sh

> Download the script to /usr/local/bin, store your SMTP password in a file only root can read, run the script once as root, and then schedule it with cron or a systemd timer.

Source: https://serverauditing.com/install/

## Requirements

The script is written for Debian, Ubuntu and Red Hat style systems. The [FAQ](https://serverauditing.com/faq/#which-linux-distributions-does-it-support) covers other systems.

| Requirement | Why the script needs it |
| --- | --- |
| Root access | It writes to `/var/log/server_audit`, installs missing packages, reads system logs and searches the file system. |
| Bash | The script uses Bash syntax such as `[[ ]]` and arrays. |
| `curl` and `lynis` | It installs either one with `apt-get` or `yum` if it is missing. On other systems, install both yourself. |
| `ss` or `netstat` | Used for the listening ports check. Without either, the script skips that check and says so in the report. |
| SSH logs | It reads `/var/log/auth.log`, then `/var/log/secure`, then the journal with `journalctl -u ssh -u sshd`. |
| An SMTP account | A username and password for an SMTP server that supports TLS. The default is `smtp.forwardemail.net` on port 465. |

## Installation steps

### 1. Install the prerequisites

Install Lynis and curl. The script would install them on its own, but installing them first keeps the first run short.

```bash
# Debian and Ubuntu
apt-get update
apt-get install -y lynis curl

# Red Hat style systems (Lynis may need the EPEL repository)
yum install -y lynis curl
```

### 2. Download the script

Save the script to `/usr/local/bin` and make it executable. Read it before you run it as root; the [checks page](https://serverauditing.com/what-it-checks/) explains each part.

```bash
curl -fsSL -o /usr/local/bin/server_audit_notify.sh \
  https://raw.githubusercontent.com/forwardemail/serverauditing.com/main/server_audit_notify.sh
chmod 755 /usr/local/bin/server_audit_notify.sh
less /usr/local/bin/server_audit_notify.sh
```

### 3. Get SMTP credentials

With [Forward Email](https://forwardemail.net), outbound SMTP comes with all paid plans. Create an alias for the sender, use its full address as the username, and create a password with the alias "Generate Password" option. The [SMTP section of the Forward Email FAQ](https://forwardemail.net/en/faq#do-you-support-sending-email-with-smtp) covers setup.

For another provider, pass `--smtp` and `--port`. Ports 465 and 2465 use implicit TLS, and any other port uses STARTTLS. The script always requires TLS and verifies the server certificate.

### 4. Store the password in a root-only file

Put the password on the first line of a file that only root can read. The script refuses a password file that its group or other users can read.

```bash
install -m 600 /dev/null /root/.server-audit-pass
printf '%s\n' 'your-smtp-password' > /root/.server-audit-pass
```

You can also set the `SMTP_PASS` environment variable. The old `--pass` option still works, but the password is then visible in the process list, and the script prints a warning.

### 5. Run a test audit

Run the script once by hand and watch the output. It creates `/var/log/server_audit` with mode 700 if it does not exist.

```bash
/usr/local/bin/server_audit_notify.sh \
  --email ops@example.com \
  --user alerts@example.com \
  --pass-file /root/.server-audit-pass
```

Check that the files appear in `/var/log/server_audit` (the [file list](https://serverauditing.com/what-it-checks/#files-written-on-each-run) shows what to expect) and that the email arrives. The script exits with status 0 on success, 1 when the email fails, and 2 when an option is missing or wrong.

### 6. Schedule a daily run with cron

Cron starts jobs with a short `PATH`, so set it in the file. That way the script finds `lynis` and `ss`, which often live in `/usr/sbin` or `/sbin`.

```bash
cat > /etc/cron.d/server-audit <<'EOF'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
15 6 * * * root /usr/local/bin/server_audit_notify.sh --quiet --email ops@example.com --user alerts@example.com --pass-file /root/.server-audit-pass
EOF
```

Add `--only-on-issues` if you want an email only when the audit finds Lynis warnings, failed SSH logins or a file system at 90% or more.

### 7. Or schedule it with a systemd timer

A systemd timer logs each run to the journal and can catch up after downtime with `Persistent=true`. A failed email makes the service fail, so `systemctl --failed` shows it.

```ini
# /etc/systemd/system/server-audit.service
[Unit]
Description=Server audit with emailed report

[Service]
Type=oneshot
ExecStart=/usr/local/bin/server_audit_notify.sh --email ops@example.com --user alerts@example.com --pass-file /root/.server-audit-pass
```

```ini
# /etc/systemd/system/server-audit.timer
[Unit]
Description=Daily server audit

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
```

```bash
systemctl daemon-reload
systemctl enable --now server-audit.timer
```

### 8. Remove old reports

Each run adds about ten files to `/var/log/server_audit`, and the script never deletes them. Add a cleanup job that fits your retention needs. The [compliance page](https://serverauditing.com/compliance/) explains why some teams keep reports longer.

```bash
echo '30 6 * * * root find /var/log/server_audit -type f -mtime +90 -delete' > /etc/cron.d/server-audit-cleanup
```

## Command-line options

| Option | Default | What it does |
| --- | --- | --- |
| `-e`, `--email EMAIL` | none, required | Address that receives the report. Separate several with commas. |
| `-u`, `--user USERNAME` | none, required | SMTP username. |
| `--pass-file FILE` | none | Read the SMTP password from the first line of FILE. FILE must not be readable by group or others. |
| `SMTP_PASS` variable | none | SMTP password from the environment. |
| `-w`, `--pass PASSWORD` | none | SMTP password on the command line. Visible in the process list; kept for older setups. |
| `-f`, `--from ADDRESS` | the SMTP username | Sender address. |
| `-s`, `--smtp HOST` | `smtp.forwardemail.net` | SMTP server hostname. |
| `-p`, `--port PORT` | `465` | SMTP port. 465 and 2465 use implicit TLS; other ports use required STARTTLS. |
| `-l`, `--level LEVEL` | `standard` | `basic`, `standard` or `thorough`. See [audit levels](https://serverauditing.com/what-it-checks/#lynis-security-audit). Any other value falls back to `standard`. |
| `-i`, `--interval HOURS` | `0` | Repeat the audit every HOURS hours in a loop that never exits. |
| `-o`, `--only-on-issues` | off | Email only when the audit finds Lynis warnings, failed SSH logins or a file system at 90% or more. |
| `-d`, `--report-dir DIR` | `/var/log/server_audit` | Where report files go. |
| `-q`, `--quiet` | off | Stop printing log lines to the console. They still go to the log file. |
| `-h`, `--help` | | Print the usage text and exit with status 0. |

When more than one password source is set, `--pass` wins, then `--pass-file`, then `SMTP_PASS`.

The built-in `--interval` loop runs in the foreground and starts a new set of report files on each pass. Cron or a systemd timer is the better choice for regular runs, because it reports failures.

## Troubleshooting

| What you see | Cause and fix |
| --- | --- |
| "Error: ... is required" and exit status 2 | `--email`, `--user` or a password source is missing, or an option is misspelled. Run with `--help`. |
| "password file ... must not be readable by group or others" | Run `chmod 600` on the password file. |
| "Failed to send email notification" and exit status 1 | Read the curl error in `/var/log/server_audit/audit_*.log`. "(67) Login denied" means a wrong username or password; "(7) Failed to connect" usually means outbound port 465 is blocked, so try `--port 587`. |
| "Skipped: neither ss nor netstat is installed" | Install `iproute2` (for `ss`) or `net-tools` (for `netstat`). |
| "Source: none" under failed SSH attempts | The server has no `/var/log/auth.log` or `/var/log/secure` and no `journalctl`. |
| No email with `--only-on-issues` | The audit found nothing to report. The audit log says "email skipped". |
