testsAndMisc/linux_configuration/hosts/guard/enforce-nsswitch.sh
Krzysztof Rudnicki 09e85cd914 feat: LeechBlock default config, Chrome repo, nsswitch fixes, extended checker
- Add leechblock_defaults.js with pre-configured blocking rules matching
  hosts/install.sh (YouTube, food delivery, fast food — 3 block sets)
- install_leechblock.sh: switch to LeechBlockNG-chrome repo, download
  jQuery UI, inject defaults.js into extension, patch background.js to
  seed storage on first run, replace browser binary in-place
- remove_guest_mode.sh: fix associative array key spacing
- enforce-nsswitch.sh: handle 'resolve' without 'dns' in emergency fix
- setup_hosts_guard.sh: ensure 'files' in nsswitch hosts line before
  snapshotting, remove erroneous 'local' outside function
- check_and_enable_services.sh: extend from 5 to 12 services, add
  nsswitch.conf validation and auto-fix
2026-02-20 20:24:13 +01:00

110 lines
3.6 KiB
Bash
Executable File

#!/bin/bash
# Template guard script to enforce canonical /etc/nsswitch.conf
# Ensures "hosts:" line always contains "files" before "dns"
# This prevents bypassing /etc/hosts by removing "files" from nsswitch.conf
# Installed to /usr/local/sbin/enforce-nsswitch.sh by setup_hosts_guard.sh
set -euo pipefail
CANONICAL_SOURCE="/usr/local/share/locked-nsswitch.conf"
TARGET="/etc/nsswitch.conf"
LOG_FILE="/var/log/nsswitch-guard.log"
log() {
printf '%s - %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" | tee -a "$LOG_FILE" >&2
}
# Function to validate that "hosts:" line has correct format
# Must contain "files" before "dns" (or "dns" not present)
validate_hosts_line() {
local line="$1"
# Check if "files" is present
if ! echo "$line" | grep -qw "files"; then
return 1
fi
# If dns is present, files must come before it
if echo "$line" | grep -qw "dns"; then
local files_pos dns_pos
files_pos=$(echo "$line" | grep -bo '\bfiles\b' | head -1 | cut -d: -f1)
dns_pos=$(echo "$line" | grep -bo '\bdns\b' | head -1 | cut -d: -f1)
if [[ -n "$files_pos" && -n "$dns_pos" && "$files_pos" -gt "$dns_pos" ]]; then
return 1
fi
fi
return 0
}
# Check current nsswitch.conf hosts line
current_hosts_line=$(grep '^hosts:' "$TARGET" 2>/dev/null || echo "")
if [[ -z "$current_hosts_line" ]]; then
log "CRITICAL: No 'hosts:' line found in $TARGET - restoring from canonical"
if [[ -f "$CANONICAL_SOURCE" ]]; then
chattr -i "$TARGET" 2>/dev/null || true
cp "$CANONICAL_SOURCE" "$TARGET"
chmod 644 "$TARGET"
chattr +i "$TARGET" 2>/dev/null || log "Failed to set immutable attribute on $TARGET"
log "Restored $TARGET from canonical copy"
else
log "ERROR: Canonical source not found at $CANONICAL_SOURCE"
exit 1
fi
exit 0
fi
if ! validate_hosts_line "$current_hosts_line"; then
log "TAMPERING DETECTED: 'hosts:' line is invalid or missing 'files' before 'dns'"
log "Current line: $current_hosts_line"
if [[ -f "$CANONICAL_SOURCE" ]]; then
chattr -i "$TARGET" 2>/dev/null || true
cp "$CANONICAL_SOURCE" "$TARGET"
chmod 644 "$TARGET"
chattr +i "$TARGET" 2>/dev/null || log "Failed to set immutable attribute on $TARGET"
log "Restored $TARGET from canonical copy"
else
log "ERROR: Canonical source not found at $CANONICAL_SOURCE"
# Emergency fix: add "files" back to hosts line
chattr -i "$TARGET" 2>/dev/null || true
if grep -q '^hosts:.*dns' "$TARGET"; then
sed -i 's/^hosts:\(.*\)dns/hosts:\1files dns/' "$TARGET"
elif grep -q '^hosts:.*resolve' "$TARGET"; then
sed -i 's/^hosts:\(.*\)resolve/hosts: files\1resolve/' "$TARGET"
else
sed -i 's/^hosts:/hosts: files/' "$TARGET"
fi
chattr +i "$TARGET" 2>/dev/null || true
log "Emergency fix applied: added 'files' to hosts line"
fi
exit 0
fi
# If canonical exists, check for any drift
if [[ -f "$CANONICAL_SOURCE" ]]; then
if ! cmp -s "$CANONICAL_SOURCE" "$TARGET"; then
log "Drift detected in $TARGET (but hosts line valid) - restoring canonical"
chattr -i "$TARGET" 2>/dev/null || true
cp "$CANONICAL_SOURCE" "$TARGET"
chmod 644 "$TARGET"
chattr +i "$TARGET" 2>/dev/null || log "Failed to set immutable attribute"
log "Restored $TARGET from canonical copy"
else
log "No drift detected in $TARGET"
fi
else
log "Creating initial canonical snapshot"
mkdir -p "$(dirname "$CANONICAL_SOURCE")"
cp "$TARGET" "$CANONICAL_SOURCE"
chmod 644 "$CANONICAL_SOURCE"
chattr +i "$CANONICAL_SOURCE" 2>/dev/null || log "Failed to protect canonical copy"
fi
# Ensure immutable attribute is set
chattr -i "$TARGET" 2>/dev/null || true
chattr +i "$TARGET" 2>/dev/null || log "Failed to set immutable attribute on $TARGET"
log "nsswitch.conf enforcement complete"