Skip to content

14 Agent Prompts Operations and Audit

Mikhail Deynekin edited this page Oct 20, 2026 · 1 revision

Agent Prompts: Operations & Audit

Recurring operational tasks: daily audit, missing reports, key rotation, updates, false-positive review, quota planning, incident bursts.


Prompt G — Daily / weekly security audit

Task: produce a daily security audit for this host. READ-ONLY.

Steps:
1. fail2ban state: fail2ban-client status (all jails), count banned per jail, failed per jail.
2. New bans in the last 24h: grep " Ban " /var/log/fail2ban.log | tail -50
   (or journalctl -u fail2ban --since "-24 hours").
3. Top attackers:
     journalctl -u ssh --since "-24 hours" | grep "Failed password" | grep -oE 'from [0-9.]+' \
       | awk '{print $2}' | sort | uniq -c | sort -rn | head -20
     grep -hE '"(GET|POST).*(\.env|\.git|wp-login|phpmyadmin|\.\./)' /var/www/httpd-logs/*.access.log \
       | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
4. AbuseIPDB pipeline:
     /usr/local/sbin/abuseipdb-report --stats
     tail -n 30 /var/log/abuseipdb-reporter.log | grep -E "reported|ERROR|WARNING"
5. Health: systemctl is-active fail2ban abuseipdb-report.timer; systemctl --failed;
   disk usage of /var/lib/abuseipdb; database size.
6. Red flags: queue growing over 24h, repeated 401/429, jail with zero matches but busy logs,
   bans not visible in nftables, timer not active.

Constraints: no changes. Mask the operator's own IPs and never print the API key.

Return: a compact table (jail | banned | failed | new bans 24h), top-10 attacker IPs with counts
and jails, queue/journal numbers, red-flag list with severity (P1/P2/P3), and 1-3 concrete
recommendations. If everything is healthy, say so explicitly.

Prompt H — Investigate missing or failing reports

Task: bans happen, but no reports appear on AbuseIPDB. Diagnose the pipeline end to end.

Steps (stop at the first broken link):
1. Is the action attached? for each relevant jail: fail2ban-client get <jail> actions
   Expected: nftables, abuseipdb-async.
2. Is the queue receiving events? /usr/local/sbin/abuseipdb-report --stats
   - pending events growing -> worker never runs or fails
   - pending 0 and reports 0 -> action not attached, or enqueue rejected the IP
3. Check enqueue logs: grep -i "enqueue" /var/log/abuseipdb-reporter.log | tail -30
4. Check the worker: systemctl status abuseipdb-report.timer; systemctl start abuseipdb-report;
   tail -n 50 /var/log/abuseipdb-reporter.log
5. Check the key: /usr/local/sbin/abuseipdb-report --key-status
   /usr/local/sbin/abuseipdb-report --check-key      (one API request)
6. Check API responses in the journal: grep -E "-> (4|5)[0-9][0-9]" /var/log/abuseipdb-reporter.log
   - 401 -> invalid key (rotate)
   - 429 -> throttle/daily budget (expected behaviour; events stay queued)
   - 422/400 -> invalid payload (inspect --dry-run, report as a bug)
7. Check configuration gates: grep -E "^(enabled|skip_jails|max_reports)" /etc/abuseipdb/reporter.conf
8. Check that the evidence DB is readable: ls -l /var/lib/fail2ban/fail2ban.sqlite3
   python3 -c 'import sqlite3;print(sqlite3.connect("file:/var/lib/fail2ban/fail2ban.sqlite3?mode=ro",uri=True).execute("select count(*) from bips").fetchone())'

Constraints: fix nothing without approval; do not delete the queue; do not make more than 2
check requests; never print the key.

Return: the first broken link, evidence (command output), likely cause, safe proposed fix, and
the next verification step. If everything works but AbuseIPDB does not show the report, explain
the 15-minute per-IP rule and how to verify via the check API.

Prompt I — Rotate the AbuseIPDB API key

Task: rotate the AbuseIPDB API key on this host with zero reporting downtime.

Parameters: NEW_KEY = <NEW_KEY>  (or read it from a file provided by the human)

Constraints:
- Never print the key; mask it in output.
- Keep one report window of old key validity if possible.
- Do not edit reporter.conf; the key lives in /etc/abuseipdb/.abuseipdb.key.

Steps:
1. Record: /usr/local/sbin/abuseipdb-report --version; ls -l /etc/abuseipdb/.abuseipdb.key;
   cp -a /etc/abuseipdb/.abuseipdb.key /root/abuseipdb-key-$(date +%s).bak
2. Write the new key atomically:
     install -m 600 /dev/stdin /etc/abuseipdb/.abuseipdb.key <<< "<NEW_KEY>"
   (or: umask 077; printf '%s\n' "<NEW_KEY>" > /etc/abuseipdb/.abuseipdb.key)
3. Verify: /usr/local/sbin/abuseipdb-report --key-status
           /usr/local/sbin/abuseipdb-report --check-key     (expect HTTP 200)
4. Send one pending report if the queue is non-empty: /usr/local/sbin/abuseipdb-report
5. Ask the human to revoke the old key in the AbuseIPDB account once the new one is confirmed.

Return: key source (masked), check-key result, one report result, backup path. Never return the key.

Prompt J — Safe self-update with rollback plan

Task: update Fail2Ban_AbuseIPDB to the latest release and verify that nothing was lost.

Steps:
1. Record before: version, sha256 of the key file and reporter.conf, queue stats, per-jail actions.
2. /usr/local/sbin/abuseipdb-upgrade --check       (0 = current, 10 = update, 1 = error)
3. Back up: /etc/abuseipdb, the queue, and (if present) the current code directory.
4. If update available: /usr/local/sbin/abuseipdb-upgrade --upgrade --yes
5. Verify after: version, key sha unchanged, config valid, queue preserved, actions present,
   fail2ban-client -t and status, /usr/local/sbin/abuseipdb-upgrade --check exit 0.
6. Run one worker tick and inspect the log tail.
7. If anything fails: stop, report, restore the key/config/queue from the backup and reinstall
   the previous release archive; do not attempt partial fixes.

Return: before/after table, checksums, queue stats, verification output, and the rollback plan
(executed or not).

Prompt K — Review false positives and tune thresholds

Task: review recent fail2ban bans for false positives and propose threshold changes.

Steps:
1. Extract the last 7 days of bans with context:
     grep " Ban " /var/log/fail2ban.log | tail -200
     grep " Ban " /var/log/fail2ban.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head
2. For the top banned IPs, find the triggering log lines (auth.log / access.log) and classify:
   bot, scanner, legitimate user, monitoring, CDN, unknown.
3. Look for bans of addresses in your own networks (ignoreip gaps), repeated bans of the same
   legitimate client, and bans caused by a filter that is too broad.
4. For each suspected false positive: name the filter/regex, show the line, propose a narrower
   regex, an ignoreregex entry, a higher maxretry for that jail, or an ignoreip addition.
5. Do NOT apply changes; produce a proposal with expected impact and risk.

Return: table (IP | jail | count | classification | evidence | proposed action), plus a summary
of filters that need narrowing and whitelist gaps. Ask for approval before any change.

Prompt L — Quota and capacity planning

Task: check whether the current ban volume fits the AbuseIPDB free plan and the configured
budgets, and propose safe settings.

Steps:
1. /usr/local/sbin/abuseipdb-report --stats
2. From the queue journal, compute: reports/day for the last 7 days (if enough history),
   unique IPs pending, max reports per day observed.
3. Compare with /etc/abuseipdb/reporter.conf: max_reports_per_day (default 900),
   max_reports_per_run (25), min_interval_ip (1200).
4. Estimate: unique banned IPs/day × expected report rate; note that the worker aggregates all
   bans of an IP into one report per throttle window.
5. Check the current AbuseIPDB plan limits (1000 requests/day on the free plan; per-IP 15 min).
6. Recommend: either keep 900/day (safe margin for `--check-key` and manual checks) or raise
   max_reports_per_day only if the plan allows it; never exceed the plan.

Return: observed volume table, headroom, bottleneck (per-run vs per-day vs per-IP), and a
configuration recommendation with the exact lines to change.

Prompt M — Incident: sudden attack burst

Task: the host is under a burst of attacks. Stabilize without breaking legitimate traffic.

Steps:
1. Quantify: top source IPs/countries for the last hour in auth/access logs; which jails are
   banning; CPU/network of the host; fail2ban queue depth.
2. Confirm fail2ban is working: fail2ban-client status, failed/banned counts, nftables set sizes.
3. Do NOT raise maxretry or bantime blindly; first ensure `port = 80,443` on web jails and
   `ignoreip` covers management/monitoring.
4. Consider, with approval:
   - enabling `recidive` (4w) for repeat offenders;
   - temporarily lowering maxretry for the specific abusive jail;
   - Cloudflare/WAF rules for volumetric L7 attacks (fail2ban is not a DDoS mitigator);
   - rate limiting at nginx for request floods.
5. Watch the reporting queue: a burst may create a backlog; the worker caps at 25/run and 900/day.
   Do not increase those values beyond the AbuseIPDB plan.

Return: evidence of the attack, actions taken (with approval), remaining risk, and the queue/API
state. Recommend when to revert temporary measures.

Next: Installation prompts · Fail2Ban setup prompts · Troubleshooting

Clone this wiki locally