diff --git a/netalertx/CHANGELOG.md b/netalertx/CHANGELOG.md index 48ff2dcd5..39c213791 100644 --- a/netalertx/CHANGELOG.md +++ b/netalertx/CHANGELOG.md @@ -1,5 +1,3 @@ -## 25.10.1-2 (18-12-2025) -- Minor bugs fixed ## 25.10.1-4 (01-12-2025) - Minor bugs fixed ## 25.10.1-3 (29-11-2025) diff --git a/netalertx/Dockerfile b/netalertx/Dockerfile index 70576c2e8..f5a4da735 100644 --- a/netalertx/Dockerfile +++ b/netalertx/Dockerfile @@ -10,38 +10,111 @@ # /` #=== Home Assistant Addon ===# -################# -# 1 Build Image # -################# +############################ +# 0) Tools stage (apk OK) # +############################ +# We build a tiny payload in /out containing: +# - jq + its shared libs (libjq, libonig, etc.) +# - gosu + its shared libs +# IMPORTANT: we do NOT bring sudo to avoid breaking NetAlertX hardened behavior. +FROM alpine:3.22 AS ha_tools +RUN apk add --no-cache \ + gosu \ + pax-utils + +RUN set -eux; \ + mkdir -p /out; \ + for bin in /usr/bin/gosu; do \ + mkdir -p "/out$(dirname "$bin")"; \ + cp -a "$bin" "/out$bin"; \ + # Copy runtime deps. Skip musl loader to avoid clobbering base image libc/loader. + lddtree -l "$bin" | while read -r dep; do \ + case "$dep" in \ + /lib/ld-musl-*.so.1) \ + continue ;; \ + /*) \ + mkdir -p "/out$(dirname "$dep")"; \ + cp -a "$dep" "/out$(dirname "$dep")/"; \ + ;; \ + esac; \ + done; \ + done + +################## +# 1) Final image # +################## ARG BUILD_FROM -ARG BUILD_VERSION -FROM ${BUILD_FROM} +FROM ghcr.io/jokob-sk/netalertx:latest -################## -# 2 Modify Image # -################## +# S6 settings (keep yours) +ENV S6_CMD_WAIT_FOR_SERVICES=1 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_SERVICES_GRACETIME=0 -ENV NETALERTX_DATA=/config -ENV READ_WRITE_FOLDERS="$READ_WRITE_FOLDERS $NETALERTX_DATA" - -################## -# 3 Install apps # -################## +USER 0 # Add rootfs -COPY --chown=102:102 rootfs/ / +COPY rootfs/ / + +# Bring in jq + gosu (and their libs). NO apk in final stage. +COPY --from=ha_tools /out/ / + RUN BASHIO_VERSION="0.14.3" && \ mkdir -p /tmp/bashio && \ - curl -f -L -s -S "https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz" | tar -xzf - --strip 1 -C /tmp/bashio - #mv /tmp/bashio/lib /usr/lib/bashio && \ - #ln -s /usr/lib/bashio/bashio /usr/bin/bashio && \ - #rm -rf /tmp/ + curl -f -L -s -S "https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz" | tar -xzf - --strip 1 -C /tmp/bashio && \ + mv /tmp/bashio/lib /usr/lib/bashio && \ + ln -s /usr/lib/bashio/bashio /usr/bin/bashio && \ + rm -rf /tmp/bashio + +ARG TARGETARCH +RUN curl -L -o /usr/local/bin/jq "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-$TARGETARCH" && \ + chmod +x /usr/local/bin/jq + +########### +# Modules # +########### +ARG MODULES="00-banner.sh" + +# Automatic modules download +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_automodules.sh" "/ha_automodules.sh" +RUN chmod 744 /ha_automodules.sh \ + && /ha_automodules.sh "$MODULES" \ + && rm /ha_automodules.sh + +################# +# Manual apps # +################# +ENV PACKAGES="" + +# Automatic apps & bashio +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_autoapps.sh" "/ha_autoapps.sh" +RUN chmod 744 /ha_autoapps.sh \ + && /ha_autoapps.sh "$PACKAGES" \ + && rm /ha_autoapps.sh + +################ +# 4 Entrypoint # +################ +ENV S6_STAGE2_HOOK=/ha_entrypoint.sh +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_entrypoint.sh" "/ha_entrypoint.sh" + +# Entrypoint modifications +ADD "https://raw.githubusercontent.com/alexbelgium/hassio-addons/master/.templates/ha_entrypoint_modif.sh" "/ha_entrypoint_modif.sh" +RUN chmod 777 /ha_entrypoint.sh /ha_entrypoint_modif.sh \ + && /ha_entrypoint_modif.sh \ + && rm /ha_entrypoint_modif.sh + +#WORKDIR / +ENTRYPOINT [ "/usr/bin/env" ] +CMD [ "/ha_entrypoint.sh" ] + +# Your preferred shell +SHELL ["/bin/bash", "-o", "pipefail", "-c"] ############ # 5 Labels # ############ - ARG BUILD_ARCH ARG BUILD_DATE ARG BUILD_DESCRIPTION @@ -68,12 +141,3 @@ LABEL \ org.opencontainers.image.created=${BUILD_DATE} \ org.opencontainers.image.revision=${BUILD_REF} \ org.opencontainers.image.version=${BUILD_VERSION} - -#################### -# 6 HealthcheckNOT # -#################### -# # In the dockerfile Changing hard links if possible -# RUN for folder in config db; do \ -# echo "Adapting hard links" && \ -# grep -rl "/app/$folder" / 2>/dev/null | xargs sed -i "s|/app/$folder|/config/$folder|g"; \ -# done diff --git a/netalertx/config.yaml b/netalertx/config.yaml index 29506f66d..f0126c8e0 100644 --- a/netalertx/config.yaml +++ b/netalertx/config.yaml @@ -3,14 +3,16 @@ arch: - amd64 description: "\U0001F5A7\U0001F50D WIFI / LAN scanner, intruder, and presence detector" environment: - PGID: "102" + PGID: "20211" PORT: "20211" - PUID: "102" + PUID: "20211" TZ: Europe/Berlin - SKIP_STARTUP_CHECKS: "true" + NETALERTX_DATA: /config + NETALERTX_CONFIG: /config/config + NETALERTX_DB: /config/db + TMP_DIR: /tmp/tmp hassio_api: true host_network: true -image: ghcr.io/alexbelgium/netalertx-{arch} ingress: true ingress_port: 0 ingress_stream: true diff --git a/netalertx/rootfs/etc/cont-init.d/32-ingress.sh b/netalertx/rootfs/etc/cont-init.d/32-ingress.sh index 62c379826..1b5faa6cb 100755 --- a/netalertx/rootfs/etc/cont-init.d/32-ingress.sh +++ b/netalertx/rootfs/etc/cont-init.d/32-ingress.sh @@ -1,4 +1,4 @@ -#!/usr/bin/with-contenv /tmp/bashio/lib/bashio +#!/usr/bin/with-contenv bashio # shellcheck shell=bash set -e diff --git a/netalertx/rootfs/etc/cont-init.d/91-configure.sh b/netalertx/rootfs/etc/cont-init.d/91-configure.sh new file mode 100755 index 000000000..2361d3803 --- /dev/null +++ b/netalertx/rootfs/etc/cont-init.d/91-configure.sh @@ -0,0 +1,118 @@ +#!/usr/bin/with-contenv bashio +# shellcheck shell=bash +set -e + +#################### +# Update structure # +#################### + +APP_UID=20211 + +# 1. Fix the directories +for folder in /tmp/run/tmp /tmp/api /tmp/log /tmp/run /tmp/nginx/active-config "$TMP_DIR" "$NETALERTX_DATA" "$NETALERTX_DB" "$NETALERTX_CONFIG"; do + if [ -n "$folder" ]; then + mkdir -p "$folder" + chown -R $APP_UID:$APP_UID "$folder" + chmod 755 "$folder" + fi +done + +# 2. Fix /tmp and Standard Streams (CRITICAL) +chmod -R 1777 /tmp +# This allows the non-root user to write to the container logs +chmod 666 /dev/stdout /dev/stderr + +# 3. Pre-create and chown log files +touch /tmp/log/app.php_errors.log /tmp/log/cron.log /tmp/log/stdout.log /tmp/log/stderr.log +chown $APP_UID:$APP_UID /tmp/log/*.log + +# 4. Create Symlinks +for item in db config; do + rm -rf "/data/$item" + ln -sf "/config/$item" "/data/$item" + chown -R $APP_UID:$APP_UID "/data/$item" + chmod -R 755 "/data/$item" +done + +# Fix php +sed -i 's|>>"\?/tmp/log/app\.php_errors\.log"\? 2>/dev/stderr|>>"/tmp/log/app.php_errors.log"|g' /services/start-php-fpm.sh +sed -i 's|TEMP_CONFIG_FILE=$(mktemp "${TMP_DIR}/netalertx\.conf\.XXXXXX")|TEMP_CONFIG_FILE=$(mktemp -p "${TMP_DIR:-/tmp}" netalertx.conf.XXXXXX)|' /services/start-php-fpm.sh +sed -i "/default_type/a include /etc/nginx/http.d/ingress.conf;" "${SYSTEM_NGINX_CONFIG_TEMPLATE}" + +##################### +# Configure network # +##################### + +# Configuration file path +config_file="/config/config/app.conf" + +if [ -f /config/db/app.db ]; then + chmod a+rwx /config/db/app.db +fi + +# Function to execute the main logic +execute_main_logic() { + bashio::log.info "Initiating scan of Home Assistant network configuration..." + + # Get the local IPv4 address + local_ip="$(bashio::network.ipv4_address)" + local_ip="${local_ip%/*}" # Remove CIDR notation + echo "... Detected local IP: $local_ip" + echo "... Scanning network for changes" + + # Ensure arp-scan is installed + if ! command -v arp-scan &> /dev/null; then + bashio::log.error "arp-scan command not found. Please install arp-scan to proceed." + exit 1 + fi + + # Get current settings + if ! grep -q "^SCAN_SUBNETS" "$config_file"; then + bashio::log.fatal "SCAN_SUBNETS is not found in your $config_file, please correct your file first" + fi + + # Iterate over network interfaces + for interface in $(bashio::network.interfaces); do + echo "Scanning interface: $interface" + + # Check if the interface is already configured + if grep -q "$interface" "$config_file"; then + echo "... $interface is already configured in app.conf" + else + # Update SCAN_SUBNETS in app.conf + SCAN_SUBNETS="$(grep "^SCAN_SUBNETS" "$config_file" | head -1)" + if [[ "$SCAN_SUBNETS" != *"$local_ip"*"$interface"* ]]; then + # Add to the app.conf + NEW_SCAN_SUBNETS="${SCAN_SUBNETS%]}, '${local_ip}/24 --interface=${interface}']" + sed -i "/^SCAN_SUBNETS/c\\$NEW_SCAN_SUBNETS" "$config_file" + # Check availability of hosts + VALUE="$(arp-scan --interface="$interface" "${local_ip}/24" 2> /dev/null \ + | grep "responded" \ + | awk -F'.' '{print $NF}' \ + | awk '{print $1}' || true)" + echo "... $interface is available in Home Assistant (with $VALUE devices), added to app.conf" + fi + fi + done + + bashio::log.info "Network scan completed." + +} + +# Function to wait for the config file +wait_for_config_file() { + echo "Waiting for $config_file to become available..." + while [ ! -f "$config_file" ]; do + sleep 5 # Wait for 5 seconds before checking again + done + echo "$config_file is now available. Starting the script." + execute_main_logic +} + +# Main script logic +if [ -f "$config_file" ]; then + execute_main_logic +else + wait_for_config_file & + true +fi diff --git a/netalertx/rootfs/etc/cont-init.d/99-run.sh b/netalertx/rootfs/etc/cont-init.d/99-run.sh index ba5fea839..1675ed83e 100755 --- a/netalertx/rootfs/etc/cont-init.d/99-run.sh +++ b/netalertx/rootfs/etc/cont-init.d/99-run.sh @@ -2,102 +2,5 @@ # shellcheck shell=bash set -e -#################### -# Update structure # -#################### - -bashio::log.info "Update structure" - -# In the addon script, make symlinks on the fly -echo "Creating symlinks" -for folder in config db; do - echo "Creating for $folder" - # Create symlinks - mkdir -p /config/"$folder" - if [ -d /app/"$folder" ] && [ "$(ls -A /app/"$folder")" ]; then - cp -rn /app/"$folder"/* /config/"$folder"/ - fi - rm -r /app/"$folder" - ln -sf /config/"$folder" /app/"$folder" -done - -sudo chown -R nginx:www-data /config/db/ -sudo chown -R nginx:www-data /config/config/ -if [ -f /config/db/app.db ]; then - chmod a+rwx /config/db/app.db -fi - -##################### -# Configure network # -##################### - -# Configuration file path -config_file="/config/config/app.conf" - -# Function to execute the main logic -execute_main_logic() { - bashio::log.info "Initiating scan of Home Assistant network configuration..." - - # Get the local IPv4 address - local_ip="$(bashio::network.ipv4_address)" - local_ip="${local_ip%/*}" # Remove CIDR notation - echo "... Detected local IP: $local_ip" - echo "... Scanning network for changes" - - # Ensure arp-scan is installed - if ! command -v arp-scan &> /dev/null; then - bashio::log.error "arp-scan command not found. Please install arp-scan to proceed." - exit 1 - fi - - # Get current settings - if ! grep -q "^SCAN_SUBNETS" "$config_file"; then - bashio::log.fatal "SCAN_SUBNETS is not found in your $config_file, please correct your file first" - fi - - # Iterate over network interfaces - for interface in $(bashio::network.interfaces); do - echo "Scanning interface: $interface" - - # Check if the interface is already configured - if grep -q "$interface" "$config_file"; then - echo "... $interface is already configured in app.conf" - else - # Update SCAN_SUBNETS in app.conf - SCAN_SUBNETS="$(grep "^SCAN_SUBNETS" "$config_file" | head -1)" - if [[ "$SCAN_SUBNETS" != *"$local_ip"*"$interface"* ]]; then - # Add to the app.conf - NEW_SCAN_SUBNETS="${SCAN_SUBNETS%]}, '${local_ip}/24 --interface=${interface}']" - sed -i "/^SCAN_SUBNETS/c\\$NEW_SCAN_SUBNETS" "$config_file" - # Check availability of hosts - VALUE="$(arp-scan --interface="$interface" "${local_ip}/24" 2> /dev/null \ - | grep "responded" \ - | awk -F'.' '{print $NF}' \ - | awk '{print $1}' || true)" - echo "... $interface is available in Home Assistant (with $VALUE devices), added to app.conf" - fi - fi - done - - bashio::log.info "Network scan completed." -} - -# Function to wait for the config file -wait_for_config_file() { - echo "Waiting for $config_file to become available..." - while [ ! -f "$config_file" ]; do - sleep 5 # Wait for 5 seconds before checking again - done - echo "$config_file is now available. Starting the script." - execute_main_logic -} - -# Main script logic -if [ -f "$config_file" ]; then - execute_main_logic -else - wait_for_config_file & - true -fi - -sudo -u "#${PUID}" -g "#${PGID}" /bin/sh /entrypoint.sh +bashio::log.info "Starting upstream app" +gosu netalertx /entrypoint.sh diff --git a/netalertx/rootfs/etc/nginx/http.d/ingress.conf b/netalertx/rootfs/etc/nginx/http.d/ingress.conf index 3bbe1f863..03f14b7cb 100644 --- a/netalertx/rootfs/etc/nginx/http.d/ingress.conf +++ b/netalertx/rootfs/etc/nginx/http.d/ingress.conf @@ -1,3 +1,8 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + server { listen %%interface%%:%%port%% default_server; server_name netalertx; diff --git a/netalertx/updater.json b/netalertx/updater.json index 23194dc57..2d1f4ac49 100644 --- a/netalertx/updater.json +++ b/netalertx/updater.json @@ -3,6 +3,7 @@ "repository": "alexbelgium/hassio-addons", "slug": "netalertx", "source": "github", + "paused": true, "upstream_repo": "jokob-sk/NetAlertX", - "upstream_version": "25.11.29" + "upstream_version": "25.5.24" }