rg — Compliance Auditing
Configuration Auditing
rg excels at compliance scanning — stripping comments, finding enabled directives, auditing for risky patterns. The common thread: transform config files from noise-heavy to signal-only, then search the signal.
rg -v '^\s*(#|;|//|$)' /etc/ssh/sshd_config
-v inverts the match: lines starting with , ;, //, or that are blank are excluded. What remains is the effective configuration. Works for sshd_config, pacman.conf, nftables.conf, systemd units — any -commented format. For INI-style ; comments, the pattern already covers it.
rg -n '^\s*(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|X11Forwarding|AllowTcpForwarding|PermitEmptyPasswords)\s' /etc/ssh/sshd_config
Searches for specific security-relevant directives that are uncommented (active). Any directive starting with # is a default or disabled — this pattern skips those. Check the value column: PermitRootLogin yes is a finding.
cat <<'EOF' > /tmp/rg-sudoers
root ALL=(ALL:ALL) ALL
%wheel ALL=(ALL:ALL) ALL
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
admin ALL=(ALL) NOPASSWD: ALL
EOF
rg -n 'NOPASSWD.*ALL|ALL=\(ALL\).*ALL' /tmp/rg-sudoers
NOPASSWD: ALL grants password-less sudo for every command — a high-severity finding. ALL=(ALL)…ALL with no command restriction is similarly broad. On a live system, use rg -rn 'NOPASSWD' /etc/sudoers /etc/sudoers.d/ 2>/dev/null to search all sudoers fragments.
cat <<'EOF' > /tmp/rg-nginx.conf
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
listen 443 ssl;
root /var/www/html;
}
}
EOF
rg -n 'listen\s+' /tmp/rg-nginx.conf
Finds every listen directive with its port and options. On a live system: rg -rn 'listen\s+' /etc/nginx/sites-enabled/ 2>/dev/null to see all active listeners. The \s+ ensures you match the directive, not a comment mentioning "listen".
cat <<'EOF' > /tmp/rg-nftables.conf
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 accept
tcp dport 80 accept
tcp dport 443 accept
}
}
EOF
rg -n 'accept|drop|reject' /tmp/rg-nftables.conf
Extracts every rule with a terminal action. On a live system: rg -n 'accept|drop|reject' /etc/nftables.conf 2>/dev/null || sudo nft list ruleset | rg 'accept|drop|reject'. Review accept lines — each is an open port or allowed flow.
cat <<'EOF' > /tmp/rg-dupes.conf
# SSH config
Port 22
PermitRootLogin no
PasswordAuthentication yes
PermitRootLogin yes
PasswordAuthentication no
EOF
rg -v '^\s*(#|$)' /tmp/rg-dupes.conf | awk '{print $1}' | sort | uniq -d
rg -v strips comments and blanks. awk '\{print $1\}' extracts the directive name. uniq -d shows only duplicates. Shadowed settings are a common misconfiguration — sshd uses the first occurrence, so a later PermitRootLogin yes has no effect if no appears first.
cat <<'EOF' > /tmp/rg-host-a.conf
Port 22
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
EOF
cat <<'EOF' > /tmp/rg-host-b.conf
Port 22
PermitRootLogin yes
PasswordAuthentication no
PubkeyAuthentication yes
EOF
diff <(rg -v '^\s*(#|$)' /tmp/rg-host-a.conf | sort) <(rg -v '^\s*(#|$)' /tmp/rg-host-b.conf | sort)
Each side strips comments and sorts for consistent comparison. On live hosts: diff <(ssh host-a 'rg -v "^\s*(|$)" /etc/ssh/sshd_config' | sort) <(ssh host-b 'rg -v "^\s*(|$)" /etc/ssh/sshd_config' | sort). Differences indicate configuration drift.
cat <<'EOF' > /tmp/rg-unit.service
[Unit]
Description=Example Service
[Service]
ExecStart=/usr/bin/example
ProtectSystem=strict
ProtectHome=yes
NoNewPrivileges=yes
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
EOF
rg -n 'ProtectSystem|ProtectHome|NoNewPrivileges|PrivateTmp|ReadOnlyPaths|PrivateDevices|CapabilityBoundingSet' /tmp/rg-unit.service
Searches for systemd security directives. On a live system: rg -rn 'ProtectSystem|NoNewPrivileges' /etc/systemd/system/ /usr/lib/systemd/system/ 2>/dev/null | head -20. Services missing these directives are running with more privileges than necessary.