332 lines
7.6 KiB
Bash
Executable File
332 lines
7.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
# ============================================================
|
|
# Linux Parental Control - Installer
|
|
# ============================================================
|
|
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "Please run with sudo:"
|
|
echo " sudo ./install.sh"
|
|
exit 1
|
|
fi
|
|
|
|
INSTALL_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
echo
|
|
echo "=================================="
|
|
echo "Linux Parental Control Installer"
|
|
echo "=================================="
|
|
echo
|
|
echo "Installing from:"
|
|
echo "$INSTALL_DIR"
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# Detect Linux distribution
|
|
# ============================================================
|
|
|
|
if [ -f /etc/os-release ]; then
|
|
. /etc/os-release
|
|
else
|
|
echo "ERROR: Cannot determine Linux distribution."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Detected:"
|
|
echo " Distribution: ${PRETTY_NAME:-Unknown}"
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# Detect package manager
|
|
# ============================================================
|
|
|
|
PACKAGE_MANAGER=""
|
|
|
|
if command -v pacman >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="pacman"
|
|
|
|
elif command -v apt-get >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="apt"
|
|
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="dnf"
|
|
|
|
elif command -v zypper >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="zypper"
|
|
|
|
elif command -v apk >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="apk"
|
|
|
|
elif command -v xbps-install >/dev/null 2>&1; then
|
|
PACKAGE_MANAGER="xbps"
|
|
|
|
else
|
|
echo "ERROR: Unsupported Linux distribution."
|
|
echo
|
|
echo "Supported package managers:"
|
|
echo " pacman"
|
|
echo " apt"
|
|
echo " dnf"
|
|
echo " zypper"
|
|
echo " apk"
|
|
echo " xbps"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Package manager:"
|
|
echo " $PACKAGE_MANAGER"
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# Check systemd
|
|
# ============================================================
|
|
|
|
if ! command -v systemctl >/dev/null 2>&1; then
|
|
echo "ERROR: systemd is required."
|
|
echo
|
|
echo "This installer installs a systemd service."
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d /run/systemd/system ]; then
|
|
echo "ERROR: systemd is not currently running."
|
|
echo
|
|
echo "This installer requires a running systemd system."
|
|
exit 1
|
|
fi
|
|
|
|
echo "systemd detected."
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# Install system dependencies
|
|
# ============================================================
|
|
|
|
echo "[1/5] Installing dependencies"
|
|
|
|
case "$PACKAGE_MANAGER" in
|
|
|
|
pacman)
|
|
# Do NOT use -Syu here. This installer must not upgrade the whole
|
|
# Arch system; it only installs the packages required by this app.
|
|
pacman -S --needed --noconfirm \
|
|
python \
|
|
python-pip
|
|
;;
|
|
|
|
apt)
|
|
apt-get update
|
|
|
|
DEBIAN_FRONTEND=noninteractive \
|
|
apt-get install -y \
|
|
python3 \
|
|
python3-pip \
|
|
python3-venv
|
|
;;
|
|
|
|
dnf)
|
|
dnf install -y \
|
|
python3 \
|
|
python3-pip
|
|
;;
|
|
|
|
zypper)
|
|
zypper --non-interactive install \
|
|
python3 \
|
|
python3-pip
|
|
;;
|
|
|
|
apk)
|
|
apk add \
|
|
python3 \
|
|
py3-pip \
|
|
py3-virtualenv
|
|
;;
|
|
|
|
xbps)
|
|
xbps-install -Sy \
|
|
python3 \
|
|
python3-pip
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
# ============================================================
|
|
# Verify Python
|
|
# ============================================================
|
|
|
|
if ! command -v python3 >/dev/null 2>&1; then
|
|
echo "ERROR: python3 was not installed."
|
|
exit 1
|
|
fi
|
|
|
|
PYTHON="$(command -v python3)"
|
|
|
|
echo
|
|
echo "Python:"
|
|
"$PYTHON" --version
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# Prepare PAM administration group
|
|
# ============================================================
|
|
|
|
echo "Preparing PAM administration group"
|
|
|
|
if ! getent group pam >/dev/null 2>&1; then
|
|
echo "Creating system group: pam"
|
|
groupadd --system pam
|
|
fi
|
|
|
|
if ! id -nG root | tr " " "\n" | grep -qx "pam"; then
|
|
echo "Adding root to group: pam"
|
|
usermod -aG pam root
|
|
fi
|
|
|
|
echo "PAM group:"
|
|
getent group pam
|
|
echo
|
|
|
|
|
|
# ============================================================
|
|
# Create virtual environment
|
|
# ============================================================
|
|
|
|
echo "[2/5] Creating virtual environment"
|
|
|
|
if [ ! -d "$INSTALL_DIR/.venv" ]; then
|
|
"$PYTHON" -m venv "$INSTALL_DIR/.venv"
|
|
else
|
|
echo "Virtual environment already exists."
|
|
fi
|
|
|
|
|
|
# ============================================================
|
|
# Install Python packages
|
|
# ============================================================
|
|
|
|
echo
|
|
echo "[3/5] Installing Python packages"
|
|
|
|
"$INSTALL_DIR/.venv/bin/python" -m pip install \
|
|
-r "$INSTALL_DIR/requirements.txt"
|
|
|
|
|
|
# ============================================================
|
|
# Remove legacy SQLite storage
|
|
# ============================================================
|
|
|
|
LEGACY_DB="$INSTALL_DIR/data/parental-control.db"
|
|
|
|
if [ -f "$LEGACY_DB" ]; then
|
|
echo
|
|
echo "Removing legacy SQLite database:"
|
|
echo " $LEGACY_DB"
|
|
rm -f "$LEGACY_DB"
|
|
fi
|
|
|
|
mkdir -p "$INSTALL_DIR/data"
|
|
chmod 700 "$INSTALL_DIR/data"
|
|
|
|
# Keep the configuration and runtime state readable/writable only by root.
|
|
[ -f "$INSTALL_DIR/data/config.yaml" ] && chmod 600 "$INSTALL_DIR/data/config.yaml"
|
|
[ -f "$INSTALL_DIR/data/state.json" ] && chmod 600 "$INSTALL_DIR/data/state.json"
|
|
|
|
|
|
# ============================================================
|
|
# Install systemd service
|
|
# ============================================================
|
|
|
|
echo
|
|
echo "[4/5] Installing systemd service"
|
|
|
|
SERVICE_FILE="/etc/systemd/system/parental-control.service"
|
|
SECRET_DIR="/etc/parental-control"
|
|
SECRET_FILE="$SECRET_DIR/session-secret"
|
|
SECRET_ENV_FILE="$SECRET_DIR/session-secret.env"
|
|
|
|
install -d -m 700 "$SECRET_DIR"
|
|
|
|
if [ ! -s "$SECRET_FILE" ]; then
|
|
"$INSTALL_DIR/.venv/bin/python" -c \
|
|
'import secrets; print(secrets.token_urlsafe(48))' \
|
|
> "$SECRET_FILE"
|
|
chmod 600 "$SECRET_FILE"
|
|
fi
|
|
|
|
# systemd reads the environment file; the raw secret is kept separately
|
|
# so it is easy to rotate without changing the service definition.
|
|
printf 'PARENTAL_CONTROL_SESSION_SECRET=%s\n' "$(cat "$SECRET_FILE")" > "$SECRET_ENV_FILE"
|
|
chmod 600 "$SECRET_ENV_FILE"
|
|
|
|
sed \
|
|
"s|%INSTALL_DIR%|$INSTALL_DIR|g" \
|
|
"$INSTALL_DIR/parental-control.service" \
|
|
> "$SERVICE_FILE"
|
|
|
|
|
|
|
|
# ============================================================
|
|
# Enable and start service
|
|
# ============================================================
|
|
|
|
systemctl daemon-reload
|
|
|
|
systemctl enable parental-control.service
|
|
|
|
systemctl restart parental-control.service
|
|
|
|
|
|
# ============================================================
|
|
# Verify service
|
|
# ============================================================
|
|
|
|
echo
|
|
echo "[5/5] Verifying installation"
|
|
|
|
if systemctl is-active --quiet parental-control.service; then
|
|
SERVICE_STATUS="running"
|
|
else
|
|
SERVICE_STATUS="FAILED"
|
|
fi
|
|
|
|
|
|
# ============================================================
|
|
# Result
|
|
# ============================================================
|
|
|
|
echo
|
|
echo "=================================="
|
|
echo "Parental Control installed"
|
|
echo "=================================="
|
|
echo
|
|
echo "Distribution:"
|
|
echo " ${PRETTY_NAME:-Unknown}"
|
|
echo
|
|
echo "Python:"
|
|
"$INSTALL_DIR/.venv/bin/python" --version
|
|
echo
|
|
echo "Installation directory:"
|
|
echo " $INSTALL_DIR"
|
|
echo
|
|
echo "Service:"
|
|
echo " $SERVICE_STATUS"
|
|
echo
|
|
echo "Admin panel:"
|
|
echo " http://127.0.0.1:8765/admin"
|
|
echo
|
|
echo "Service commands:"
|
|
echo " sudo systemctl status parental-control"
|
|
echo " sudo systemctl restart parental-control"
|
|
echo " sudo journalctl -u parental-control -f"
|
|
echo
|
|
echo "=================================="
|