Posted on
Artificial Intelligence

Artificial Intelligence Linux Configuration Reviews

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

AI-Powered Linux Configuration Reviews with Bash

If your Linux boxes could talk, they’d probably complain about config drift, insecure defaults, and forgotten one-off fixes. The trouble is, reviewing system configuration is tedious, fragmented across dozens of files and commands, and always time-pressured. This is where Artificial Intelligence–assisted configuration reviews shine: use AI to summarize, spot risks, and suggest improvements—quickly—while you stay in control.

This article shows how to run safe, reproducible AI reviews of your Linux configuration using Bash. You’ll collect and sanitize config, prompt an AI model to analyze it, and turn findings into actionable tasks. Along the way, you’ll get ready-to-use scripts and distro-agnostic install commands.


Why AI configuration reviews are worth your time

  • Speed and coverage: AI can sift through large, messy config snapshots faster than manual reviews, highlighting likely issues, duplications, and inconsistencies.

  • Pattern recognition: Models can map your settings to well-known hardening guides and best practices, surfacing gaps you might miss.

  • Documentation on demand: Ask the AI to explain trade-offs and link back to relevant man pages or standards so changes are understood—not just applied.

  • Human in the loop: Treat the model as a sharp junior SRE: it proposes; you validate, test, and approve.

Caveat: never feed secrets to a cloud model. You’ll sanitize output first and/or use a local model in sensitive environments.


Prerequisites

We’ll use standard CLI tools to gather config and interact with an AI API. Install these packages:

  • curl: HTTP client for APIs

  • jq: JSON processor

  • ripgrep (rg): fast grep for filtering/redaction

  • tar/gzip: bundle results

Debian/Ubuntu (apt):

sudo apt update
sudo apt install -y curl jq ripgrep tar gzip

Fedora/RHEL/CentOS/Alma/Rocky (dnf):

sudo dnf install -y curl jq ripgrep tar gzip

openSUSE/SLES (zypper):

sudo zypper install -y curl jq ripgrep tar gzip

Optional but useful:

  • git (to version control your review artifacts)

  • shellcheck (to lint any custom scripts)

apt:

sudo apt install -y git shellcheck

dnf:

sudo dnf install -y git shellcheck

zypper:

sudo zypper install -y git ShellCheck

Note: On some SUSE variants, the ShellCheck package name can differ. If ShellCheck isn’t found, skip it or install from your preferred source.


The workflow at a glance

1) Define the review goal and scope
2) Collect configuration safely and consistently
3) Redact secrets before sending anywhere
4) Ask the AI for a focused review and structured output
5) Apply changes, verify, and automate the loop

Below you’ll find actionable steps and scripts for each.


1) Define your review goal and scope

Decide what you want out of the review. Examples:

  • Security hardening: SSH, PAM, kernel sysctl, firewall, logging, users/groups.

  • Performance: I/O scheduler, network tuning, service limits, resource contention.

  • Compliance baseline: CIS-like checks, password policies, auditing coverage.

Then pick scope by host role (e.g., “web nodes”), environment (“staging”), or criticality (“prod-only”). This keeps reviews targeted and cheaper to run while yielding higher-quality recommendations.


2) Collect configuration into a single bundle

Use a Bash script to gather system facts and configs you care about. The script below:

  • Runs cross-distro-safe commands when possible

  • Checks if a command/file exists before reading it

  • Writes everything into a timestamped folder

Save as collect-config.sh:

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

OUTDIR="conf-snapshot-$(hostname)-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$OUTDIR"/{cmd,files,service}

log() { printf '[%s] %s\n' "$(date +%F\ %T)" "$*" >&2; }

run() {
  local name="$1"; shift
  if command -v "$1" >/dev/null 2>&1; then
    log "Running: $*"
    { echo "### $*"; "$@" 2>&1; } > "$OUTDIR/cmd/$name.txt" || true
  else
    log "Skipping (not found): $1"
  fi
}

copy_if_exists() {
  local p="$1"
  if [ -e "$p" ]; then
    log "Collecting file: $p"
    # Avoid following symlinks outside etc
    cp -L --preserve=mode,timestamps "$p" "$OUTDIR/files/$(echo "$p" | tr '/' '_')" 2>/dev/null || true
  fi
}

# OS and kernel
run uname uname -a
[ -r /etc/os-release ] && cp /etc/os-release "$OUTDIR/files/os-release"
run lsblk lsblk -f
run df df -hT
run free free -h
run lscpu lscpu

# Services and packages
if command -v systemctl >/dev/null 2>&1; then
  run systemd_units systemctl list-units
  run systemd_sockets systemctl list-sockets
  run systemd_failed systemctl --failed
  run systemd_timers systemctl list-timers
fi

# Package inventory (best effort across distros)
if command -v dpkg >/dev/null 2>&1; then
  run packages dpkg -l
elif command -v rpm >/dev/null 2>&1; then
  run packages rpm -qa
elif command -v zypper >/dev/null 2>&1; then
  run packages zypper se -i
fi

# Networking
run ip_addr ip -br a
run ip_route ip route show
run ss_listen ss -tulpen
run firewall_cmd firewall-cmd --list-all
run ufw_status ufw status verbose

# Kernel and limits
run sysctl_all sysctl -a
copy_if_exists /etc/sysctl.conf
if [ -d /etc/sysctl.d ]; then
  tar -czf "$OUTDIR/files/etc_sysctl_d.tgz" -C / etc/sysctl.d 2>/dev/null || true
fi

# SSH and auth
copy_if_exists /etc/ssh/sshd_config
if [ -d /etc/ssh/sshd_config.d ]; then
  tar -czf "$OUTDIR/files/etc_ssh_sshd_config_d.tgz" -C / etc/ssh/sshd_config.d 2>/dev/null || true
fi
copy_if_exists /etc/pam.d/common-password
copy_if_exists /etc/pam.d/system-auth
copy_if_exists /etc/login.defs
copy_if_exists /etc/security/limits.conf

# Cron and timers
run crontab_root crontab -l
copy_if_exists /etc/crontab
if [ -d /etc/cron.d ]; then
  tar -czf "$OUTDIR/files/etc_cron_d.tgz" -C / etc/cron.d 2>/dev/null || true
fi

# Logging
copy_if_exists /etc/rsyslog.conf
if [ -d /etc/rsyslog.d ]; then
  tar -czf "$OUTDIR/files/etc_rsyslog_d.tgz" -C / etc/rsyslog.d 2>/dev/null || true
fi
copy_if_exists /etc/systemd/journald.conf

# Filesystems
copy_if_exists /etc/fstab
run mount mount

# Users and groups (names only; no hashes)
run passwd_cut awk -F: '{print $1\":\"$3\":\"$4\":\"$6\":\"$7}' /etc/passwd
run group_cut awk -F: '{print $1\":\"$3}' /etc/group
# Don’t collect /etc/shadow

# Summarize directory
log "Snapshot written to: $OUTDIR"

Run it:

bash collect-config.sh

This creates a snapshot folder like conf-snapshot-host-YYYYMMDD-HHMMSS with text files and small archives.

Tip: Version-control the output folder (or a sanitized copy) in a private Git repo to track drift over time.


3) Redact secrets before sharing

Before any upload to a cloud model, scrub tokens, keys, and passwords. The following script replaces common secret patterns with placeholders. Adjust it to your environment.

Save as redact.sh:

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

SRC="${1:-}"
DST="${2:-}"
[ -z "$SRC" ] && { echo "Usage: $0 <source_dir> <dest_dir>"; exit 1; }
[ -z "$DST" ] && { echo "Usage: $0 <source_dir> <dest_dir>"; exit 1; }

mkdir -p "$DST"
shopt -s globstar nullglob

for f in "$SRC"/**/*; do
  [ -f "$f" ] || continue
  rel="${f#"$SRC"/}"
  out="$DST/$rel"
  mkdir -p "$(dirname "$out")"

  # Redact obvious secrets (customize as needed)
  sed -E \
    -e 's/(password\s*[=:]\s*)[^#\s]+/\1<REDACTED>/Ig' \
    -e 's/(passwd\s*[=:]\s*)[^#\s]+/\1<REDACTED>/Ig' \
    -e 's/(secret(_key)?\s*[=:]\s*)[^#\s]+/\1<REDACTED>/Ig' \
    -e 's/(api[_-]?key\s*[=:]\s*)[^#\s]+/\1<REDACTED>/Ig' \
    -e 's/(Authorization:\s*Bearer\s+)[A-Za-z0-9\._-]+/\1<REDACTED>/Ig' \
    -e 's/([A-Za-z0-9+\/]{20,}={0,2})/<REDACTED_BASE64>/g' \
    -e 's/(PRIVATE KEY-----)(.*)(-----END)/\1<REDACTED>\3/g' \
    "$f" > "$out"
done

echo "Redacted copy written to: $DST"

Use it:

bash redact.sh conf-snapshot-host-20240601-120000 conf-snapshot-host-20240601-120000-redacted

If you must keep everything 100% local, stop here and use a local model you manage inside your network. Otherwise, proceed with an API call to a cloud model and keep your redaction rules strict.


4) Ask the AI for a focused, structured review

You’ll send the sanitized text to an AI model with a clear prompt and request a JSON report for easy parsing. Below shows a curl + jq flow using an environment variable OPENAI_API_KEY. Replace the model name with one you’re entitled to use.

Set your key and model:

export OPENAI_API_KEY="YOUR_API_KEY"
MODEL="gpt-4o-mini"

Create a concise system prompt in prompt-system.txt:

You are a Linux configuration auditor. 
Task: assess security hardening, obvious misconfigurations, and risky defaults. 
Be precise. Cite files/lines. Offer concrete, minimal, reversible changes. 
Output in strict JSON with keys: findings[], each with {severity, area, file, line_hint, issue, recommendation, reference}.

Create a user prompt template in prompt-user.txt:

Review the following sanitized configuration snapshot. 
Assume missing files are default. Only respond with JSON as specified.

Concatenate snapshot files into a single payload (keep it modest—chunk if large):

SNAP="conf-snapshot-host-20240601-120000-redacted"
cat "$SNAP"/cmd/*.txt "$SNAP"/files/* 2>/dev/null | head -c 200000 > snapshot.txt

Call the API:

curl -s https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<'JSON' | jq -r '.choices[0].message.content' > ai-report.json
{
  "model": "'"$MODEL"'",
  "temperature": 0,
  "messages": [
    {"role": "system", "content": "'"$(tr -d '\n' < prompt-system.txt | sed 's/"/\\"/g')"'"},
    {"role": "user", "content": "'"$(tr -d '\n' < prompt-user.txt | sed 's/"/\\"/g')"'\n\nSNAPSHOT START\n"'"$(sed 's/"/\\"/g' snapshot.txt)"'" \nSNAPSHOT END"}
  ]
}
JSON

Pretty-print and summarize top items:

jq '.findings | sort_by(.severity) | .[:10]' ai-report.json

Notes:

  • Chunking: If your snapshot exceeds model limits, split by file and run multiple calls. Merge results with jq.

  • Reproducibility: Keep prompts in version control. Set temperature=0 for deterministic output.

  • Privacy: Assume the provider may retain inputs as per their policy—redact accordingly.


5) Apply changes safely and verify

Always validate recommendations. Test on a staging host or during a maintenance window. Keep a live SSH session when modifying SSH settings.

Example: apply SSH hardening via a drop-in (recommended over editing the main file):

Create /etc/ssh/sshd_config.d/ai-hardening.conf:

sudo sh -c 'cat > /etc/ssh/sshd_config.d/ai-hardening.conf <<EOF
# AI-reviewed hardening: minimal, reversible
PasswordAuthentication no
PermitRootLogin prohibit-password
MaxAuthTries 3
LoginGraceTime 20
AllowAgentForwarding no
X11Forwarding no
EOF'

Validate and reload:

sudo sshd -t && sudo systemctl reload sshd

If something goes wrong:

  • Your existing session stays active.

  • You can revert by removing the drop-in and reloading again.

For kernel tunables, prefer drop-ins:

sudo sh -c 'cat > /etc/sysctl.d/99-ai-review.conf <<EOF
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
kernel.kptr_restrict = 2
EOF'
sudo sysctl --system

Track the change and result:

  • Commit the change to your infra-as-code or config management repo.

  • Re-run the collector and confirm the AI no longer flags the same issue.


Real-world examples to model

  • Security: AI flags PermitRootLogin yes in sshd_config, recommends prohibit-password and key-only auth. It cites the file and suggests a drop-in, minimizing merge conflicts with your config management.

  • Reliability: AI notices fs.inotify.max_user_watches too low for workloads that watch many files (e.g., Kubernetes components or dev tools), suggests a value and rationale.

  • Logging: AI spots missing Storage=persistent in journald.conf, recommends enabling persistent logs and caps to avoid disk overuse.

  • Network hygiene: AI detects wide-open firewall or no default deny, proposes minimal rules by service/port.

  • Compliance: AI compares password policy from login.defs/PAM and suggests aligning with your stated baseline.


Automate the loop

Run weekly on a cron or as part of CI/CD for your images:

Example cron (Sundays at 02:30):

( crontab -l 2>/dev/null; echo '30 2 * * 0 /usr/local/bin/collect-config.sh && /usr/local/bin/redact.sh "$(ls -dt conf-snapshot-* | head -1)" "$(ls -dt conf-snapshot-* | head -1)-redacted" && /usr/local/bin/run-ai-review.sh' ) | crontab -

Where run-ai-review.sh wraps the curl call, writes ai-report.json, and emails or posts the top findings to your team chat. Keep API keys in a protected env file readable only by root.


Common pitfalls and how to avoid them

  • Over-collection: Don’t include logs or large binaries; you’ll hit token limits and costs. Keep snapshots lean and focused.

  • Secret spillage: Test redact.sh on sample files and review diffs. Add organization-specific patterns.

  • Blind trust: Treat AI output as suggestions. Verify with man pages, upstream docs, and your own SLOs/compliance needs.

  • One-shot fixes: Encode accepted changes in your config management (Ansible, Puppet, Chef, Salt) to avoid drift.


Conclusion and next steps (CTA)

AI-assisted Linux configuration reviews turn sprawling system state into actionable insights—fast. Start today:

1) Install prerequisites with your package manager.
2) Run collect-config.sh and redact.sh on a test host.
3) Prompt an AI model for a structured review and triage the top 5 items.
4) Apply fixes via drop-ins, validate, and encode them in your config management.
5) Automate the process on a schedule and track your drift over time.

Want to go deeper? Extend the collector to include service-specific configs (Nginx, PostgreSQL, systemd unit overrides), add stronger redaction rules, and create team-friendly HTML/Markdown reports from ai-report.json. Your future self—and your audits—will thank you.