From 21ca6e61d122ae8774e477e41df55c1bfd4decb5 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Fri, 4 Jul 2025 13:27:56 +0200 Subject: [PATCH] feat: automatically restore etc hosts file on edit or remove --- scripts/setup_periodic_system.sh | 195 ++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 4 deletions(-) diff --git a/scripts/setup_periodic_system.sh b/scripts/setup_periodic_system.sh index 1281a1e..22b5018 100755 --- a/scripts/setup_periodic_system.sh +++ b/scripts/setup_periodic_system.sh @@ -229,10 +229,168 @@ EOF echo "✓ Created startup service: $startup_service" } +# Function to create hosts file monitor service +create_hosts_monitor_service() { + echo "" + echo "6. Creating Hosts File Monitor Service..." + echo "========================================" + + local monitor_script="/usr/local/bin/hosts-file-monitor.sh" + local monitor_service="/etc/systemd/system/hosts-file-monitor.service" + + # Create the monitor script + cat > "$monitor_script" << EOF +#!/bin/bash +# Hosts file monitor script +# Watches /etc/hosts for changes and restores it if needed +# Created by setup_periodic_system.sh on $(date) + +LOG_FILE="/var/log/hosts-file-monitor.log" +HOSTS_FILE="/etc/hosts" +HOSTS_INSTALL_SCRIPT="$HOSTS_INSTALL_SCRIPT" + +# Function to log with timestamp +log_message() { + echo "\$(date '+%Y-%m-%d %H:%M:%S') - \$1" >> "\$LOG_FILE" + echo "\$(date '+%Y-%m-%d %H:%M:%S') - \$1" >&2 +} + +# Function to check if hosts file needs restoration +needs_restoration() { + # Check if file exists + if [[ ! -f "\$HOSTS_FILE" ]]; then + return 0 # File missing, needs restoration + fi + + # Check if file is empty or too small (less than 1000 lines indicates tampering) + local line_count=\$(wc -l < "\$HOSTS_FILE" 2>/dev/null || echo "0") + if [[ \$line_count -lt 1000 ]]; then + return 0 # File too small, likely tampered with + fi + + # Check if our custom entries are missing + if ! grep -q "Custom blocking entries" "\$HOSTS_FILE" 2>/dev/null; then + return 0 # Our custom entries missing, needs restoration + fi + + # Check if StevenBlack entries are missing + if ! grep -q "StevenBlack" "\$HOSTS_FILE" 2>/dev/null; then + return 0 # StevenBlack entries missing, needs restoration + fi + + return 1 # File seems intact +} + +# Function to restore hosts file +restore_hosts_file() { + log_message "Hosts file modification detected - initiating restoration" + + if [[ -f "\$HOSTS_INSTALL_SCRIPT" ]]; then + log_message "Running hosts installation script: \$HOSTS_INSTALL_SCRIPT" + + if bash "\$HOSTS_INSTALL_SCRIPT" >> "\$LOG_FILE" 2>&1; then + log_message "Hosts file restoration completed successfully" + else + log_message "Hosts file restoration failed with exit code \$?" + fi + else + log_message "ERROR: Hosts install script not found at \$HOSTS_INSTALL_SCRIPT" + fi +} + +# Function to monitor with inotifywait +monitor_with_inotify() { + log_message "Starting hosts file monitoring with inotify" + + # Monitor the hosts file and its directory for various events + inotifywait -m -e delete,move,modify,attrib,create --format '%w%f %e %T' --timefmt '%Y-%m-%d %H:%M:%S' "\$HOSTS_FILE" /etc/ 2>/dev/null | \ + while read file event time; do + # Check if the event is related to our hosts file + if [[ "\$file" == "\$HOSTS_FILE" ]] || [[ "\$file" == "/etc/hosts" ]]; then + log_message "Event detected: \$event on \$file at \$time" + + # Small delay to avoid rapid-fire events + sleep 2 + + # Check if restoration is needed + if needs_restoration; then + restore_hosts_file + else + log_message "Hosts file check passed - no restoration needed" + fi + fi + done +} + +# Function to monitor with polling (fallback) +monitor_with_polling() { + log_message "Starting hosts file monitoring with polling (fallback method)" + + while true; do + if needs_restoration; then + restore_hosts_file + fi + + # Check every 30 seconds + sleep 30 + done +} + +# Main execution +log_message "=== Hosts File Monitor Started ===" + +# Check if inotify-tools is available +if command -v inotifywait >/dev/null 2>&1; then + log_message "Using inotify for file monitoring" + monitor_with_inotify +else + log_message "inotify-tools not available, using polling method" + log_message "Consider installing inotify-tools for better performance: pacman -S inotify-tools" + monitor_with_polling +fi +EOF + + chmod +x "$monitor_script" + echo "✓ Created hosts monitor script: $monitor_script" + + # Create the systemd service + cat > "$monitor_service" << EOF +[Unit] +Description=Hosts File Monitor and Auto-Restore Service +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=root +ExecStart=$monitor_script +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal + +# Environment +Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +# Security settings +NoNewPrivileges=false +PrivateTmp=true + +# Resource limits +MemoryLimit=50M +CPUQuota=10% + +[Install] +WantedBy=multi-user.target +EOF + + echo "✓ Created hosts monitor service: $monitor_service" +} + # Function to enable and start services enable_services() { echo "" - echo "6. Enabling Services and Timer..." + echo "7. Enabling Services and Timer..." echo "=================================" # Reload systemd daemon @@ -248,11 +406,20 @@ enable_services() { systemctl enable periodic-system-startup.service echo "✓ Startup service enabled" + # Enable hosts file monitor service + systemctl enable hosts-file-monitor.service + systemctl start hosts-file-monitor.service + echo "✓ Hosts file monitor service enabled and started" + # Show timer status echo "" echo "Timer Status:" systemctl status periodic-system-maintenance.timer --no-pager -l + echo "" + echo "Hosts Monitor Status:" + systemctl status hosts-file-monitor.service --no-pager -l + echo "" echo "Next scheduled runs:" systemctl list-timers periodic-system-maintenance.timer --no-pager @@ -261,7 +428,7 @@ enable_services() { # Function to create log rotation configuration create_log_rotation() { echo "" - echo "7. Setting up Log Rotation..." + echo "8. Setting up Log Rotation..." echo "=============================" local logrotate_conf="/etc/logrotate.d/periodic-system-maintenance" @@ -279,6 +446,19 @@ create_log_rotation() { systemctl reload-or-restart rsyslog > /dev/null 2>&1 || true endscript } + +/var/log/hosts-file-monitor.log { + weekly + rotate 4 + compress + delaycompress + missingok + notifempty + create 644 root root + postrotate + systemctl reload-or-restart rsyslog > /dev/null 2>&1 || true + endscript +} EOF echo "✓ Created log rotation configuration: $logrotate_conf" @@ -287,7 +467,7 @@ EOF # Function to run initial execution run_initial_execution() { echo "" - echo "8. Running Initial Execution..." + echo "9. Running Initial Execution..." echo "===============================" echo "Would you like to run the system maintenance now to test the setup?" @@ -309,6 +489,7 @@ create_execution_script create_systemd_service create_systemd_timer create_startup_service +create_hosts_monitor_service enable_services create_log_rotation run_initial_execution @@ -322,21 +503,27 @@ echo "✓ Execution script created: /usr/local/bin/periodic-system-maintenance.s echo "✓ Systemd service created and enabled: periodic-system-maintenance.service" echo "✓ Systemd timer created and enabled: periodic-system-maintenance.timer" echo "✓ Startup service created and enabled: periodic-system-startup.service" +echo "✓ Hosts file monitor script and service created and enabled" echo "✓ Log rotation configured: /etc/logrotate.d/periodic-system-maintenance" echo "" echo "The system will now:" echo "• Run maintenance every hour" echo "• Run maintenance 5 minutes after system startup" -echo "• Log all activities to /var/log/periodic-system-maintenance.log" +echo "• Monitor hosts file for changes and restore if needed" +echo "• Log all activities to /var/log/periodic-system-maintenance.log and /var/log/hosts-file-monitor.log" echo "" echo "To check status:" echo " systemctl status periodic-system-maintenance.timer" echo " systemctl list-timers periodic-system-maintenance.timer" +echo " systemctl status hosts-file-monitor.service" echo "" echo "To view logs:" echo " tail -f /var/log/periodic-system-maintenance.log" echo " journalctl -u periodic-system-maintenance.service -f" +echo " tail -f /var/log/hosts-file-monitor.log" +echo " journalctl -u hosts-file-monitor.service -f" echo "" echo "To disable (if needed):" echo " sudo systemctl disable periodic-system-maintenance.timer" echo " sudo systemctl disable periodic-system-startup.service" +echo " sudo systemctl disable hosts-file-monitor.service"