- 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 yesinsshd_config, recommendsprohibit-passwordand 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_watchestoo low for workloads that watch many files (e.g., Kubernetes components or dev tools), suggests a value and rationale.Logging: AI spots missing
Storage=persistentinjournald.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.shon sample files and review diffs. Add organization-specific patterns.Blind trust: Treat AI output as suggestions. Verify with
manpages, 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.