mirror of
https://github.com/kuhyx/scripts.git
synced 2026-07-04 13:23:07 +02:00
Add custom entries protection to hosts install.sh
- Track custom blocked entries in /etc/hosts.custom-entries.state - Block installation if any previously blocked entries are removed - No bypass option - manual chattr removal required for changes - Protects against impulsive unblocking of sites - State file is also protected with chattr +i
This commit is contained in:
parent
b33385671f
commit
4cb3a62491
155
hosts/install.sh
155
hosts/install.sh
@ -25,6 +25,145 @@ for arg in "$@"; do
|
||||
esac
|
||||
done
|
||||
|
||||
# ============================================================================
|
||||
# CUSTOM ENTRIES PROTECTION MECHANISM
|
||||
# ============================================================================
|
||||
# This prevents easy removal of custom blocked entries by requiring that:
|
||||
# 1. New installation has AT LEAST as many custom entries as before, OR
|
||||
# 2. Any removed entries are replaced by NEW entries not previously blocked
|
||||
# If neither condition is met, installation is blocked.
|
||||
# ============================================================================
|
||||
|
||||
CUSTOM_ENTRIES_STATE_FILE="/etc/hosts.custom-entries.state"
|
||||
|
||||
# Extract custom blocked entries from a hosts file or heredoc section
|
||||
# Returns only the "0.0.0.0 domain.com" lines (normalized, sorted, unique)
|
||||
extract_custom_entries_from_script() {
|
||||
# Extract entries from the heredoc in this script (between EOF markers after "Custom blocking entries")
|
||||
local script_path="$1"
|
||||
sed -n '/^# Custom blocking entries$/,/^EOF$/p' "$script_path" |
|
||||
grep -E '^0\.0\.0\.0[[:space:]]+' |
|
||||
awk '{print $2}' |
|
||||
sort -u
|
||||
}
|
||||
|
||||
# Extract custom entries from the current /etc/hosts (entries after "# Custom blocking entries" marker)
|
||||
extract_custom_entries_from_hosts() {
|
||||
local hosts_file="$1"
|
||||
if [[ ! -f "$hosts_file" ]]; then
|
||||
return
|
||||
fi
|
||||
sed -n '/^# Custom blocking entries$/,$p' "$hosts_file" |
|
||||
grep -E '^0\.0\.0\.0[[:space:]]+' |
|
||||
awk '{print $2}' |
|
||||
sort -u
|
||||
}
|
||||
|
||||
# Load previously saved custom entries state
|
||||
load_saved_custom_entries() {
|
||||
if [[ -f "$CUSTOM_ENTRIES_STATE_FILE" ]]; then
|
||||
sort -u "$CUSTOM_ENTRIES_STATE_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Save current custom entries to state file
|
||||
save_custom_entries_state() {
|
||||
local entries="$1"
|
||||
echo "$entries" | sort -u >"$CUSTOM_ENTRIES_STATE_FILE"
|
||||
chmod 644 "$CUSTOM_ENTRIES_STATE_FILE"
|
||||
chattr +i "$CUSTOM_ENTRIES_STATE_FILE" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Helper function to count non-empty lines
|
||||
count_lines() {
|
||||
local input="$1"
|
||||
if [[ -z "$input" ]]; then
|
||||
echo 0
|
||||
else
|
||||
echo "$input" | grep -c . 2>/dev/null || echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Main protection check
|
||||
check_custom_entries_protection() {
|
||||
local script_path
|
||||
script_path="$(readlink -f "$0")"
|
||||
|
||||
# Get new entries from the script's heredoc
|
||||
local new_entries
|
||||
new_entries=$(extract_custom_entries_from_script "$script_path")
|
||||
local new_count
|
||||
new_count=$(count_lines "$new_entries")
|
||||
|
||||
# Get saved/existing entries (prefer state file, fall back to current /etc/hosts)
|
||||
local saved_entries
|
||||
saved_entries=$(load_saved_custom_entries)
|
||||
if [[ -z "$saved_entries" ]]; then
|
||||
# First run or state file missing - extract from current /etc/hosts if it has our marker
|
||||
saved_entries=$(extract_custom_entries_from_hosts "/etc/hosts")
|
||||
fi
|
||||
local saved_count
|
||||
saved_count=$(count_lines "$saved_entries")
|
||||
|
||||
# If no saved state exists, this is first installation - allow it
|
||||
if [[ $saved_count -eq 0 ]]; then
|
||||
echo "ℹ️ First installation detected - no protection check needed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Find entries that were removed
|
||||
local removed_entries
|
||||
removed_entries=$(comm -23 <(echo "$saved_entries") <(echo "$new_entries"))
|
||||
local removed_count
|
||||
removed_count=$(count_lines "$removed_entries")
|
||||
|
||||
# Find entries that are new
|
||||
local added_entries
|
||||
added_entries=$(comm -13 <(echo "$saved_entries") <(echo "$new_entries"))
|
||||
local added_count
|
||||
added_count=$(count_lines "$added_entries")
|
||||
|
||||
echo ""
|
||||
echo "📊 Custom Entries Protection Check:"
|
||||
echo " Previously blocked: $saved_count entries"
|
||||
echo " Currently in script: $new_count entries"
|
||||
echo " Removed: $removed_count | Added: $added_count"
|
||||
|
||||
# RULE 1: No entries removed - always OK
|
||||
if [[ $removed_count -eq 0 ]]; then
|
||||
echo " ✅ No entries removed - protection check passed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# RULE 2: Entries were removed - BLOCK INSTALLATION
|
||||
echo ""
|
||||
echo "============================================================"
|
||||
echo " ❌ INSTALLATION BLOCKED - CUSTOM ENTRIES REMOVED"
|
||||
echo "============================================================"
|
||||
echo ""
|
||||
echo "You are attempting to REMOVE the following blocked entries:"
|
||||
while IFS= read -r entry; do
|
||||
echo " - $entry"
|
||||
done <<<"$removed_entries"
|
||||
echo ""
|
||||
echo "This is NOT allowed. The only way to unblock sites is to:"
|
||||
echo ""
|
||||
echo " 1. Manually edit /etc/hosts (requires removing chattr protection)"
|
||||
echo " 2. Delete the state file /etc/hosts.custom-entries.state"
|
||||
echo " (also protected with chattr)"
|
||||
echo ""
|
||||
echo "These manual steps are intentionally difficult to prevent"
|
||||
echo "impulsive unblocking. If you really need to unblock something,"
|
||||
echo "you'll have to work for it."
|
||||
echo ""
|
||||
return 1
|
||||
}
|
||||
|
||||
# Run the protection check
|
||||
if ! check_custom_entries_protection; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Enable systemd-resolved
|
||||
sudo systemctl enable systemd-resolved
|
||||
|
||||
@ -261,6 +400,17 @@ sudo chattr +i /etc/hosts
|
||||
sudo chattr -i /etc/hosts
|
||||
sudo chattr +a /etc/hosts
|
||||
|
||||
# ============================================================================
|
||||
# SAVE CUSTOM ENTRIES STATE FOR FUTURE PROTECTION CHECKS
|
||||
# ============================================================================
|
||||
echo "Saving custom entries state for protection mechanism..."
|
||||
script_path="$(readlink -f "$0")"
|
||||
current_custom_entries=$(extract_custom_entries_from_script "$script_path")
|
||||
# Remove immutable from state file if it exists
|
||||
chattr -i "$CUSTOM_ENTRIES_STATE_FILE" 2>/dev/null || true
|
||||
save_custom_entries_state "$current_custom_entries"
|
||||
echo "✅ Custom entries state saved to $CUSTOM_ENTRIES_STATE_FILE"
|
||||
|
||||
# Optionally flush DNS caches
|
||||
if [[ $FLUSH_DNS -eq 1 ]]; then
|
||||
echo "Flushing DNS caches..."
|
||||
@ -269,3 +419,8 @@ if [[ $FLUSH_DNS -eq 1 ]]; then
|
||||
else
|
||||
echo "DNS cache flush skipped (use --flush-dns to enable)."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Installation complete!"
|
||||
echo " Custom entries protection is now active."
|
||||
echo " Removing blocked entries from the script will be blocked."
|
||||
|
||||
Loading…
Reference in New Issue
Block a user