feat: speedup hosts installation

This commit is contained in:
Krzysztof Rudnicki 2025-09-06 14:28:17 +02:00
parent 0ade08c6e2
commit 0650347903
3 changed files with 153 additions and 4 deletions

View File

@ -1,14 +1,107 @@
#!/bin/bash
# Re-run with sudo if not root
if [[ $EUID -ne 0 ]]; then
exec sudo -E bash "$0" "$@"
fi
# Enable systemd-resolved
sudo systemctl enable systemd-resolved
# Remove all attributes from /etc/hosts to allow modifications
sudo chattr -i -a /etc/hosts 2>/dev/null || true
# Download the hosts file from StevenBlack's repository
echo "Downloading hosts file from StevenBlack repository..."
sudo curl -o /etc/hosts https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn-social/hosts
# Source and local cache configuration
URL="https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-gambling-porn-social/hosts"
# Cache stores the RAW upstream file (without our custom modifications)
LOCAL_CACHE="/etc/hosts.stevenblack"
# Helpers
extract_date_epoch_from_file() {
# Grep "# Date:" line and convert to epoch seconds (UTC)
local f="$1"
local line
line=$(grep -m1 '^# Date:' "$f" 2>/dev/null | sed -E 's/^# Date:[[:space:]]*(.*)[[:space:]]*\(UTC\).*/\1 UTC/')
if [[ -n "$line" ]]; then
date -u -d "$line" +%s 2>/dev/null || echo ""
else
echo ""
fi
}
fetch_remote_header() {
# Try to fetch only the first ~4KB using HTTP Range; fallback to piping to head
local out="$1"
if curl -LfsS --max-time 10 -H 'Range: bytes=0-4095' "$URL" -o "$out"; then
return 0
fi
# Fallback may download more, but we only keep first lines
if curl -LfsS --max-time 10 "$URL" | head -n 20 > "$out"; then
return 0
fi
return 1
}
download_remote_full_to() {
local out="$1"
curl -LfsS "$URL" -o "$out"
}
# Decide whether to use cache or update
TMP_REMOTE_HEAD=$(mktemp)
trap 'rm -f "$TMP_REMOTE_HEAD"' EXIT
REMOTE_AVAILABLE=0
if fetch_remote_header "$TMP_REMOTE_HEAD"; then
REMOTE_AVAILABLE=1
fi
USE_CACHE=0
NEED_UPDATE=0
if [[ -f "$LOCAL_CACHE" ]]; then
local_epoch=$(extract_date_epoch_from_file "$LOCAL_CACHE")
else
local_epoch=""
fi
if [[ $REMOTE_AVAILABLE -eq 1 ]]; then
remote_epoch=$(extract_date_epoch_from_file "$TMP_REMOTE_HEAD")
if [[ -n "$local_epoch" && -n "$remote_epoch" && "$local_epoch" -ge "$remote_epoch" ]]; then
echo "Using cached StevenBlack hosts (up-to-date)."
USE_CACHE=1
else
echo "Cached version is missing or outdated; downloading latest StevenBlack hosts..."
NEED_UPDATE=1
fi
else
if [[ -f "$LOCAL_CACHE" ]]; then
echo "No internet; using cached StevenBlack hosts."
USE_CACHE=1
else
echo "Error: No internet and no cached StevenBlack hosts found." >&2
exit 1
fi
fi
# Ensure we have a fresh cache if needed
if [[ $NEED_UPDATE -eq 1 ]]; then
TMP_DL=$(mktemp)
if download_remote_full_to "$TMP_DL"; then
# Save raw upstream to cache
sudo mv "$TMP_DL" "$LOCAL_CACHE"
sudo chmod 644 "$LOCAL_CACHE"
echo "Saved latest StevenBlack hosts to cache: $LOCAL_CACHE"
else
rm -f "$TMP_DL"
echo "Error: Failed to download latest StevenBlack hosts." >&2
exit 1
fi
fi
# Install the base hosts from cache into /etc/hosts
echo "Installing base hosts from cache to /etc/hosts..."
sudo cp "$LOCAL_CACHE" /etc/hosts
# Comment out any 4chan blocking entries from the downloaded file
echo "Allowing 4chan by commenting out any blocking entries..."
@ -23,7 +116,7 @@ sudo sed -i 's/^0\.0\.0\.0 messenger\.com/#0.0.0.0 messenger.com/' /etc/hosts
# Add custom entries for YouTube and Discord
echo "Adding custom entries for YouTube and Discord..."
sudo cat >> /etc/hosts << 'EOF'
tee -a /etc/hosts > /dev/null << 'EOF'
# Custom blocking entries
# YouTube

View File

@ -77,6 +77,7 @@ LOGROTATE_TEMPLATES="$TEMPLATES_BASE/logrotate"
# Template files
TEMPLATE_MAINT_SCRIPT="$BIN_TEMPLATES/periodic-system-maintenance.sh"
TEMPLATE_HOSTS_MONITOR="$BIN_TEMPLATES/hosts-file-monitor.sh"
TEMPLATE_BROWSER_WRAPPER="$BIN_TEMPLATES/browser-preexec-wrapper.sh"
TEMPLATE_SVC_MAINT="$SYSTEMD_TEMPLATES/periodic-system-maintenance.service"
TEMPLATE_TIMER="$SYSTEMD_TEMPLATES/periodic-system-maintenance.timer"
TEMPLATE_STARTUP="$SYSTEMD_TEMPLATES/periodic-system-startup.service"
@ -107,6 +108,7 @@ verify_files() {
for tmpl in \
"$TEMPLATE_MAINT_SCRIPT" \
"$TEMPLATE_HOSTS_MONITOR" \
"$TEMPLATE_BROWSER_WRAPPER" \
"$TEMPLATE_SVC_MAINT" \
"$TEMPLATE_TIMER" \
"$TEMPLATE_STARTUP" \
@ -199,6 +201,40 @@ create_hosts_monitor_service() {
echo "✓ Installed hosts monitor service from template: $monitor_service"
}
# Function to install browser pre-exec wrapper and wire common browser names
install_browser_preexec_wrapper() {
echo ""
echo "6.1 Installing Browser Pre-Exec Wrapper..."
echo "========================================="
local wrapper="/usr/local/bin/browser-preexec-wrapper"
sed -e "s|__HOSTS_INSTALL_SCRIPT__|$HOSTS_INSTALL_SCRIPT|g" \
"$TEMPLATE_BROWSER_WRAPPER" > "$wrapper"
chmod +x "$wrapper"
echo "✓ Installed wrapper: $wrapper"
# Allow passwordless execution of hosts installer for root-only actions
local sudoers_file="/etc/sudoers.d/hosts-install-no-passwd"
if command -v visudo >/dev/null 2>&1; then
echo "${SUDO_USER:-$USER} ALL=(ALL) NOPASSWD: $HOSTS_INSTALL_SCRIPT" > "$sudoers_file"
chmod 440 "$sudoers_file"
# Validate syntax
visudo -c >/dev/null || echo "Warning: sudoers validation returned non-zero"
echo "✓ Sudoers drop-in created: $sudoers_file"
else
echo "visudo not found; skipping sudoers drop-in"
fi
# Create symlinks for common browser commands to the wrapper in /usr/local/bin
# This takes precedence over /usr/bin in PATH on most systems.
local browsers=( "thorium-browser" "google-chrome" "google-chrome-stable" "chromium" "brave" "brave-browser" "vivaldi-stable" "firefox" )
for b in "${browsers[@]}"; do
local link="/usr/local/bin/$b"
ln -sf "$wrapper" "$link"
done
echo "✓ Symlinked wrapper for common browsers in /usr/local/bin"
}
# Function to enable and start services
enable_services() {
echo ""
@ -284,6 +320,7 @@ create_systemd_service
create_systemd_timer
create_startup_service
create_hosts_monitor_service
install_browser_preexec_wrapper
enable_services
create_log_rotation
run_initial_execution

View File

@ -0,0 +1,19 @@
#!/bin/bash
# Generic pre-exec wrapper for browsers: ensures /etc/hosts is (re)installed
# before launching the actual browser binary.
set -euo pipefail
HOSTS_INSTALL_SCRIPT="__HOSTS_INSTALL_SCRIPT__"
prog_name="$(basename "$0")"
real_bin="/usr/bin/${prog_name}"
# Best-effort: install hosts file quietly; don't block browser startup
if command -v sudo >/dev/null 2>&1; then
sudo -n "$HOSTS_INSTALL_SCRIPT" >/dev/null 2>&1 || true
else
"$HOSTS_INSTALL_SCRIPT" >/dev/null 2>&1 || true
fi
exec "$real_bin" "$@"