mirror of
https://github.com/kuhyx/scripts.git
synced 2026-07-04 15:23:11 +02:00
Add shutdown timer monitor service to prevent disabling
- Remove 'disable' option from setup_midnight_shutdown.sh - Add shutdown-timer-monitor.sh that watches the timer every 30s - Re-enables timer automatically if someone tries to disable it - Monitor service installed alongside the timer - Makes it significantly harder to bypass the shutdown schedule - Similar pattern to hosts-file-monitor.service
This commit is contained in:
parent
4cb3a62491
commit
a1b9200d19
@ -10,17 +10,19 @@ set -e # Exit on any error
|
|||||||
show_usage() {
|
show_usage() {
|
||||||
echo "Day-Specific Auto-Shutdown Setup for Arch Linux"
|
echo "Day-Specific Auto-Shutdown Setup for Arch Linux"
|
||||||
echo "==============================================="
|
echo "==============================================="
|
||||||
echo "Usage: $0 [enable|disable|status]"
|
echo "Usage: $0 [enable|status]"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Commands:"
|
echo "Commands:"
|
||||||
echo " enable - Set up automatic shutdown with day-specific windows (default)"
|
echo " enable - Set up automatic shutdown with day-specific windows (default)"
|
||||||
echo " disable - Remove automatic shutdown"
|
|
||||||
echo " status - Show current status"
|
echo " status - Show current status"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Shutdown Schedule:"
|
echo "Shutdown Schedule:"
|
||||||
echo " Monday-Wednesday: 21:00-05:00"
|
echo " Monday-Wednesday: 21:00-05:00"
|
||||||
echo " Thursday-Sunday: 22:00-05:00"
|
echo " Thursday-Sunday: 22:00-05:00"
|
||||||
echo ""
|
echo ""
|
||||||
|
echo "NOTE: There is no 'disable' option. This is intentional."
|
||||||
|
echo " The shutdown timer is protected by a monitor service."
|
||||||
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to check and request sudo privileges
|
# Function to check and request sudo privileges
|
||||||
@ -41,86 +43,6 @@ else
|
|||||||
USER_HOME="$HOME"
|
USER_HOME="$HOME"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Function to disable and remove midnight shutdown
|
|
||||||
disable_midnight_shutdown() {
|
|
||||||
echo "Disabling Day-Specific Auto-Shutdown"
|
|
||||||
echo "===================================="
|
|
||||||
echo "Current Date: $(date)"
|
|
||||||
echo "User: $ACTUAL_USER"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
local timer_file="/etc/systemd/system/day-specific-shutdown.timer"
|
|
||||||
local service_file="/etc/systemd/system/day-specific-shutdown.service"
|
|
||||||
local script_file="/usr/local/bin/day-specific-shutdown-manager.sh"
|
|
||||||
local check_script="/usr/local/bin/day-specific-shutdown-check.sh"
|
|
||||||
local removed_files=()
|
|
||||||
|
|
||||||
# Stop and disable timer if it exists
|
|
||||||
if systemctl is-active day-specific-shutdown.timer &> /dev/null; then
|
|
||||||
echo "Stopping day-specific-shutdown timer..."
|
|
||||||
systemctl stop day-specific-shutdown.timer
|
|
||||||
echo "✓ Timer stopped"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if systemctl is-enabled day-specific-shutdown.timer &> /dev/null; then
|
|
||||||
echo "Disabling day-specific-shutdown timer..."
|
|
||||||
systemctl disable day-specific-shutdown.timer
|
|
||||||
echo "✓ Timer disabled"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove timer file
|
|
||||||
if [[ -f $timer_file ]]; then
|
|
||||||
rm -f "$timer_file"
|
|
||||||
removed_files+=("$timer_file")
|
|
||||||
echo "✓ Removed timer file: $timer_file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove service file
|
|
||||||
if [[ -f $service_file ]]; then
|
|
||||||
rm -f "$service_file"
|
|
||||||
removed_files+=("$service_file")
|
|
||||||
echo "✓ Removed service file: $service_file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove management script
|
|
||||||
if [[ -f $script_file ]]; then
|
|
||||||
rm -f "$script_file"
|
|
||||||
removed_files+=("$script_file")
|
|
||||||
echo "✓ Removed management script: $script_file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove check script
|
|
||||||
if [[ -f $check_script ]]; then
|
|
||||||
rm -f "$check_script"
|
|
||||||
removed_files+=("$check_script")
|
|
||||||
echo "✓ Removed check script: $check_script"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Reload systemd daemon
|
|
||||||
if [[ ${#removed_files[@]} -gt 0 ]]; then
|
|
||||||
echo "Reloading systemd daemon..."
|
|
||||||
systemctl daemon-reload
|
|
||||||
echo "✓ Systemd daemon reloaded"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "============================================="
|
|
||||||
echo "Day-Specific Auto-Shutdown Removal Complete"
|
|
||||||
echo "============================================="
|
|
||||||
|
|
||||||
if [[ ${#removed_files[@]} -gt 0 ]]; then
|
|
||||||
echo "Removed files:"
|
|
||||||
printf " %s\n" "${removed_files[@]}"
|
|
||||||
echo ""
|
|
||||||
echo "✓ Automatic day-specific shutdown has been completely disabled"
|
|
||||||
echo "✓ Your PC will no longer shutdown automatically"
|
|
||||||
else
|
|
||||||
echo "No day-specific shutdown configuration was found to remove."
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to show current status
|
# Function to show current status
|
||||||
show_current_status() {
|
show_current_status() {
|
||||||
echo "Day-Specific Auto-Shutdown Status"
|
echo "Day-Specific Auto-Shutdown Status"
|
||||||
@ -151,6 +73,12 @@ show_current_status() {
|
|||||||
echo "✗ Management script missing"
|
echo "✗ Management script missing"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -f "/usr/local/bin/shutdown-timer-monitor.sh" ]]; then
|
||||||
|
echo "✓ Monitor script exists"
|
||||||
|
else
|
||||||
|
echo "✗ Monitor script missing"
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Check systemd status
|
# Check systemd status
|
||||||
@ -172,11 +100,29 @@ show_current_status() {
|
|||||||
echo "Status: NOT CONFIGURED"
|
echo "Status: NOT CONFIGURED"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Check monitor service status
|
||||||
|
echo "Monitor Service Status:"
|
||||||
|
if systemctl is-enabled shutdown-timer-monitor.service &>/dev/null; then
|
||||||
|
echo "✓ Monitor is enabled"
|
||||||
|
if systemctl is-active shutdown-timer-monitor.service &>/dev/null; then
|
||||||
|
echo "✓ Monitor is active (will re-enable timer if disabled)"
|
||||||
|
else
|
||||||
|
echo "✗ Monitor is not active"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "✗ Monitor is not enabled"
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Shutdown Schedule:"
|
echo "Shutdown Schedule:"
|
||||||
echo " Monday-Wednesday: 21:00-05:00"
|
echo " Monday-Wednesday: 21:00-05:00"
|
||||||
echo " Thursday-Sunday: 22:00-05:00"
|
echo " Thursday-Sunday: 22:00-05:00"
|
||||||
echo ""
|
echo ""
|
||||||
|
echo "NOTE: The shutdown timer is protected by a monitor service."
|
||||||
|
echo " If you try to disable the timer, it will be automatically re-enabled."
|
||||||
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to create the shutdown service
|
# Function to create the shutdown service
|
||||||
@ -420,10 +366,133 @@ enable_timer() {
|
|||||||
echo "✓ Started day-specific-shutdown timer"
|
echo "✓ Started day-specific-shutdown timer"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Function to install the monitor service
|
||||||
|
install_monitor_service() {
|
||||||
|
echo ""
|
||||||
|
echo "6. Installing Shutdown Timer Monitor Service..."
|
||||||
|
echo "=============================================="
|
||||||
|
|
||||||
|
local monitor_script="/usr/local/bin/shutdown-timer-monitor.sh"
|
||||||
|
local monitor_service="/etc/systemd/system/shutdown-timer-monitor.service"
|
||||||
|
|
||||||
|
# Create the monitor script
|
||||||
|
cat >"$monitor_script" <<'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
# Shutdown timer monitor script
|
||||||
|
# Watches the day-specific-shutdown timer and re-enables it if disabled
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
LOG_FILE="/var/log/shutdown-timer-monitor.log"
|
||||||
|
TIMER_NAME="day-specific-shutdown.timer"
|
||||||
|
SERVICE_NAME="day-specific-shutdown.service"
|
||||||
|
CHECK_INTERVAL=30
|
||||||
|
|
||||||
|
log_message() {
|
||||||
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_needs_restoration() {
|
||||||
|
if ! systemctl is-enabled "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Timer $TIMER_NAME is not enabled"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if ! systemctl is-active "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Timer $TIMER_NAME is not active"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ ! -f "/etc/systemd/system/$TIMER_NAME" ]]; then
|
||||||
|
log_message "Timer unit file missing"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ ! -f "/etc/systemd/system/$SERVICE_NAME" ]]; then
|
||||||
|
log_message "Service unit file missing"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ ! -f "/usr/local/bin/day-specific-shutdown-check.sh" ]]; then
|
||||||
|
log_message "Check script missing"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_timer() {
|
||||||
|
log_message "Shutdown timer tampering detected - initiating restoration"
|
||||||
|
systemctl daemon-reload
|
||||||
|
if ! systemctl is-enabled "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Re-enabling $TIMER_NAME"
|
||||||
|
systemctl enable "$TIMER_NAME" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
if ! systemctl is-active "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Re-starting $TIMER_NAME"
|
||||||
|
systemctl start "$TIMER_NAME" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
if systemctl is-active "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Timer restoration completed successfully"
|
||||||
|
else
|
||||||
|
log_message "WARNING: Timer restoration may have failed"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
log_message "=== Shutdown Timer Monitor Started ==="
|
||||||
|
log_message "Monitoring timer: $TIMER_NAME"
|
||||||
|
|
||||||
|
if timer_needs_restoration; then
|
||||||
|
log_message "Initial check: Timer needs restoration"
|
||||||
|
restore_timer
|
||||||
|
else
|
||||||
|
log_message "Initial check: Timer is properly configured"
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if timer_needs_restoration; then
|
||||||
|
restore_timer
|
||||||
|
fi
|
||||||
|
sleep "$CHECK_INTERVAL"
|
||||||
|
done
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "$monitor_script"
|
||||||
|
echo "✓ Created monitor script: $monitor_script"
|
||||||
|
|
||||||
|
# Create the monitor service
|
||||||
|
cat >"$monitor_service" <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Shutdown Timer Monitor and Auto-Restore Service
|
||||||
|
After=network-online.target day-specific-shutdown.timer
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
ExecStart=/usr/local/bin/shutdown-timer-monitor.sh
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
NoNewPrivileges=false
|
||||||
|
PrivateTmp=true
|
||||||
|
MemoryMax=50M
|
||||||
|
CPUQuota=10%
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "✓ Created monitor service: $monitor_service"
|
||||||
|
|
||||||
|
# Reload and enable monitor
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable shutdown-timer-monitor.service
|
||||||
|
systemctl start shutdown-timer-monitor.service
|
||||||
|
echo "✓ Enabled and started shutdown-timer-monitor.service"
|
||||||
|
}
|
||||||
|
|
||||||
# Function to test the setup
|
# Function to test the setup
|
||||||
test_setup() {
|
test_setup() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "6. Testing Setup..."
|
echo "7. Testing Setup..."
|
||||||
echo "=================="
|
echo "=================="
|
||||||
|
|
||||||
echo "Service files:"
|
echo "Service files:"
|
||||||
@ -439,6 +508,12 @@ test_setup() {
|
|||||||
echo "✗ Timer file missing"
|
echo "✗ Timer file missing"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -f "/etc/systemd/system/shutdown-timer-monitor.service" ]]; then
|
||||||
|
echo "✓ Monitor service file exists"
|
||||||
|
else
|
||||||
|
echo "✗ Monitor service file missing"
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Timer status:"
|
echo "Timer status:"
|
||||||
if systemctl is-enabled day-specific-shutdown.timer &>/dev/null; then
|
if systemctl is-enabled day-specific-shutdown.timer &>/dev/null; then
|
||||||
@ -453,6 +528,20 @@ test_setup() {
|
|||||||
echo "✗ Timer is not active"
|
echo "✗ Timer is not active"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Monitor status:"
|
||||||
|
if systemctl is-enabled shutdown-timer-monitor.service &>/dev/null; then
|
||||||
|
echo "✓ Monitor is enabled"
|
||||||
|
else
|
||||||
|
echo "✗ Monitor is not enabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if systemctl is-active shutdown-timer-monitor.service &>/dev/null; then
|
||||||
|
echo "✓ Monitor is active"
|
||||||
|
else
|
||||||
|
echo "✗ Monitor is not active"
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Next scheduled checks:"
|
echo "Next scheduled checks:"
|
||||||
systemctl list-timers day-specific-shutdown.timer --no-pager 2>/dev/null | head -5 | grep day-specific-shutdown || echo "Timer information not available"
|
systemctl list-timers day-specific-shutdown.timer --no-pager 2>/dev/null | head -5 | grep day-specific-shutdown || echo "Timer information not available"
|
||||||
@ -470,6 +559,7 @@ show_instructions() {
|
|||||||
echo "✓ Management script created (/usr/local/bin/day-specific-shutdown-manager.sh)"
|
echo "✓ Management script created (/usr/local/bin/day-specific-shutdown-manager.sh)"
|
||||||
echo "✓ Smart check script created (/usr/local/bin/day-specific-shutdown-check.sh)"
|
echo "✓ Smart check script created (/usr/local/bin/day-specific-shutdown-check.sh)"
|
||||||
echo "✓ Timer enabled and started"
|
echo "✓ Timer enabled and started"
|
||||||
|
echo "✓ Monitor service installed and started (protects timer from being disabled)"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Shutdown Schedule:"
|
echo "Shutdown Schedule:"
|
||||||
echo " Monday-Wednesday: 21:00-05:00 (9:00 PM to 5:00 AM)"
|
echo " Monday-Wednesday: 21:00-05:00 (9:00 PM to 5:00 AM)"
|
||||||
@ -482,7 +572,8 @@ show_instructions() {
|
|||||||
echo "How it works:"
|
echo "How it works:"
|
||||||
echo "• Timer checks every 30 minutes during potential shutdown windows"
|
echo "• Timer checks every 30 minutes during potential shutdown windows"
|
||||||
echo "• Smart logic determines shutdown eligibility based on day and time"
|
echo "• Smart logic determines shutdown eligibility based on day and time"
|
||||||
echo "• Prevents accidental shutdowns outside designated time windows"
|
echo "• Monitor service watches the timer and re-enables it if disabled"
|
||||||
|
echo "• There is NO disable option - this is intentional for digital wellbeing"
|
||||||
echo ""
|
echo ""
|
||||||
echo "WARNING: This will automatically shutdown your PC during designated hours."
|
echo "WARNING: This will automatically shutdown your PC during designated hours."
|
||||||
echo "Make sure to save your work before the shutdown windows!"
|
echo "Make sure to save your work before the shutdown windows!"
|
||||||
@ -506,6 +597,7 @@ confirm_setup() {
|
|||||||
echo "- Downloads/uploads in progress will be interrupted"
|
echo "- Downloads/uploads in progress will be interrupted"
|
||||||
echo "- You'll need to manually power on your PC each day"
|
echo "- You'll need to manually power on your PC each day"
|
||||||
echo "- Timer checks every 30 minutes during potential shutdown windows"
|
echo "- Timer checks every 30 minutes during potential shutdown windows"
|
||||||
|
echo "- There is NO disable option - this is protected by a monitor service"
|
||||||
echo ""
|
echo ""
|
||||||
read -r -p "Do you want to proceed? (y/N): " confirm
|
read -r -p "Do you want to proceed? (y/N): " confirm
|
||||||
|
|
||||||
@ -521,32 +613,6 @@ confirm_setup() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to confirm disable
|
|
||||||
confirm_disable() {
|
|
||||||
echo ""
|
|
||||||
echo "Disable Day-Specific Auto-Shutdown Confirmation"
|
|
||||||
echo "==============================================="
|
|
||||||
echo "This will completely remove the automatic day-specific shutdown configuration."
|
|
||||||
echo ""
|
|
||||||
echo "After disabling:"
|
|
||||||
echo "- Your PC will no longer shutdown automatically during any time windows"
|
|
||||||
echo "- All related systemd services and timers will be removed"
|
|
||||||
echo "- The management and check scripts will be deleted"
|
|
||||||
echo ""
|
|
||||||
read -r -p "Do you want to proceed with disabling? (y/N): " confirm
|
|
||||||
|
|
||||||
case "$confirm" in
|
|
||||||
[yY] | [yY][eE][sS])
|
|
||||||
echo "Proceeding with disable..."
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Disable cancelled."
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution flow for enable
|
# Main execution flow for enable
|
||||||
enable_midnight_shutdown() {
|
enable_midnight_shutdown() {
|
||||||
echo "Day-Specific Auto-Shutdown Setup for Arch Linux"
|
echo "Day-Specific Auto-Shutdown Setup for Arch Linux"
|
||||||
@ -568,6 +634,9 @@ enable_midnight_shutdown() {
|
|||||||
# Enable and start timer
|
# Enable and start timer
|
||||||
enable_timer
|
enable_timer
|
||||||
|
|
||||||
|
# Install monitor service (protects timer from being disabled)
|
||||||
|
install_monitor_service
|
||||||
|
|
||||||
# Test setup
|
# Test setup
|
||||||
test_setup
|
test_setup
|
||||||
|
|
||||||
@ -581,11 +650,6 @@ case "${1:-enable}" in
|
|||||||
check_sudo "$@"
|
check_sudo "$@"
|
||||||
enable_midnight_shutdown
|
enable_midnight_shutdown
|
||||||
;;
|
;;
|
||||||
"disable")
|
|
||||||
check_sudo "$@"
|
|
||||||
confirm_disable
|
|
||||||
disable_midnight_shutdown
|
|
||||||
;;
|
|
||||||
"status")
|
"status")
|
||||||
check_sudo "$@"
|
check_sudo "$@"
|
||||||
show_current_status
|
show_current_status
|
||||||
|
|||||||
131
scripts/system-maintenance/bin/shutdown-timer-monitor.sh
Normal file
131
scripts/system-maintenance/bin/shutdown-timer-monitor.sh
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Shutdown timer monitor script
|
||||||
|
# Watches the day-specific-shutdown timer and re-enables it if disabled
|
||||||
|
# This file is installed by setup_midnight_shutdown.sh
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
LOG_FILE="/var/log/shutdown-timer-monitor.log"
|
||||||
|
TIMER_NAME="day-specific-shutdown.timer"
|
||||||
|
SERVICE_NAME="day-specific-shutdown.service"
|
||||||
|
CHECK_INTERVAL=30
|
||||||
|
|
||||||
|
# Function to log with timestamp
|
||||||
|
log_message() {
|
||||||
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if timer needs to be re-enabled
|
||||||
|
timer_needs_restoration() {
|
||||||
|
# Check if timer is enabled
|
||||||
|
if ! systemctl is-enabled "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Timer $TIMER_NAME is not enabled"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if timer is active
|
||||||
|
if ! systemctl is-active "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Timer $TIMER_NAME is not active"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if timer unit file exists
|
||||||
|
if [[ ! -f "/etc/systemd/system/$TIMER_NAME" ]]; then
|
||||||
|
log_message "Timer unit file missing: /etc/systemd/system/$TIMER_NAME"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if service unit file exists
|
||||||
|
if [[ ! -f "/etc/systemd/system/$SERVICE_NAME" ]]; then
|
||||||
|
log_message "Service unit file missing: /etc/systemd/system/$SERVICE_NAME"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if check script exists
|
||||||
|
if [[ ! -f "/usr/local/bin/day-specific-shutdown-check.sh" ]]; then
|
||||||
|
log_message "Check script missing: /usr/local/bin/day-specific-shutdown-check.sh"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1 # Timer is properly configured
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to restore timer
|
||||||
|
restore_timer() {
|
||||||
|
log_message "Shutdown timer tampering detected - initiating restoration"
|
||||||
|
|
||||||
|
# Reload systemd daemon in case unit files were modified
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
# Re-enable timer if disabled
|
||||||
|
if ! systemctl is-enabled "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Re-enabling $TIMER_NAME"
|
||||||
|
systemctl enable "$TIMER_NAME" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Re-start timer if not active
|
||||||
|
if ! systemctl is-active "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Re-starting $TIMER_NAME"
|
||||||
|
systemctl start "$TIMER_NAME" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify restoration
|
||||||
|
if systemctl is-active "$TIMER_NAME" &>/dev/null; then
|
||||||
|
log_message "Timer restoration completed successfully"
|
||||||
|
else
|
||||||
|
log_message "WARNING: Timer restoration may have failed"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to monitor timer with systemd events
|
||||||
|
monitor_with_dbus() {
|
||||||
|
log_message "Starting shutdown timer monitoring with D-Bus events"
|
||||||
|
|
||||||
|
# Use busctl to monitor systemd unit changes
|
||||||
|
# Fall back to polling if this fails
|
||||||
|
if command -v busctl &>/dev/null; then
|
||||||
|
# Monitor for unit state changes
|
||||||
|
busctl monitor --system org.freedesktop.systemd1 2>/dev/null |
|
||||||
|
while read -r line; do
|
||||||
|
# Check if the line mentions our timer
|
||||||
|
if echo "$line" | grep -q "$TIMER_NAME\|$SERVICE_NAME"; then
|
||||||
|
log_message "Systemd event detected for shutdown timer"
|
||||||
|
sleep 2
|
||||||
|
if timer_needs_restoration; then
|
||||||
|
restore_timer
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
log_message "busctl not available, falling back to polling"
|
||||||
|
monitor_with_polling
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to monitor with polling (primary method for reliability)
|
||||||
|
monitor_with_polling() {
|
||||||
|
log_message "Starting shutdown timer monitoring with polling (interval: ${CHECK_INTERVAL}s)"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if timer_needs_restoration; then
|
||||||
|
restore_timer
|
||||||
|
fi
|
||||||
|
sleep "$CHECK_INTERVAL"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
log_message "=== Shutdown Timer Monitor Started ==="
|
||||||
|
log_message "Monitoring timer: $TIMER_NAME"
|
||||||
|
log_message "Monitoring service: $SERVICE_NAME"
|
||||||
|
|
||||||
|
# Initial check
|
||||||
|
if timer_needs_restoration; then
|
||||||
|
log_message "Initial check: Timer needs restoration"
|
||||||
|
restore_timer
|
||||||
|
else
|
||||||
|
log_message "Initial check: Timer is properly configured"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use polling for reliability (D-Bus monitoring can miss events)
|
||||||
|
monitor_with_polling
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Shutdown Timer Monitor and Auto-Restore Service
|
||||||
|
After=network-online.target day-specific-shutdown.timer
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
ExecStart=/usr/local/bin/shutdown-timer-monitor.sh
|
||||||
|
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
|
||||||
|
MemoryMax=50M
|
||||||
|
CPUQuota=10%
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Loading…
Reference in New Issue
Block a user