mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-08-09 06:32:31 +02:00
fix(elasticsearch): drop to uid 1000 before starting Elasticsearch
Elasticsearch refuses to bootstrap as root ("can not run elasticsearch
as root"). The previous fix in this PR kept the container root at
runtime to fix the /data permission failure, but never dropped
privileges again afterward — unlike 7.17.9, whose own entrypoint used
`chroot --userspec=1000:0` before launching Elasticsearch, the upstream
8.x entrypoint no longer does that. So every start, fresh or upgrade,
would fail once addon-init.sh's setup finished.
Fix: after addon-init.sh completes its root-only work (migration guard,
data/config relocation, chown), it re-execs the entrypoint itself as
uid 1000 via `chroot --userspec=1000:0 / ...` — the same mechanism
7.17.9 used, and exactly what the add-on's AppArmor profile already
grants (sys_chroot, setuid, setgid). On the re-exec'd pass the script
returns immediately (guarded by an exported sentinel) so none of the
setup work repeats; exported env vars (env_vars, the security default)
survive the exec normally.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,9 +8,10 @@
|
||||
- Removed the `ingest-attachment` plugin install: it is a bundled module since Elasticsearch 8.0.
|
||||
- Startup persistence logic rewritten as a proper init script (`/usr/local/bin/addon-init.sh`) instead of line-number-based entrypoint patching.
|
||||
- Added `updater.json` so upstream 8.19.x releases are tracked automatically (pinned to the 8.19 line: 9.x cannot read indices created in 7.x).
|
||||
- The upstream 8.x image ends the build as a non-root user with a read-only entrypoint; the Dockerfile now switches to root for the build steps that patch/install into it. The image stays root at runtime too (unchanged from 7.17.9): the upstream entrypoint no longer drops privileges itself, and `addon-init.sh` needs to chown/move pre-existing `/data` content that may be owned by root from earlier installs.
|
||||
- The upstream 8.x image ends the build as a non-root user with a read-only entrypoint; the Dockerfile now switches to root for the build steps that patch/install into it. The container also starts as root (unchanged from 7.17.9) so `addon-init.sh` can chown/move pre-existing `/data` content that may be owned by root from earlier installs; unlike 7.17.9's own entrypoint, the upstream 8.x entrypoint no longer drops privileges before starting Elasticsearch (which refuses to run as root), so `addon-init.sh` now does that itself via `chroot --userspec=1000:0` once its root-only work is done.
|
||||
- `env_vars` names starting with a digit are now rejected before export instead of crashing the entrypoint.
|
||||
- Fixed a startup failure (`mv: cannot move '/data/config' ... Permission denied`) on upgrade from an existing 7.17.9 install, caused by an earlier fix in this same release that switched the runtime user to non-root before this fix was in place.
|
||||
- Fixed a second regression from that same fix: without a privilege drop before starting Elasticsearch, both fresh installs and upgrades would fail Elasticsearch's own root-check ("can not run elasticsearch as root").
|
||||
|
||||
## 8.14.3-3 (2026-06-19)
|
||||
- Fix startup failing with `chroot: cannot change root directory` by allowing `capability sys_chroot` in the AppArmor profile (#2709)
|
||||
|
||||
@@ -141,9 +141,10 @@ HEALTHCHECK \
|
||||
--timeout=25s \
|
||||
CMD curl -A "HealthCheck: Docker/1.0" -s -f "http://127.0.0.1:${HEALTH_PORT}${HEALTH_URL}" &>/dev/null || exit 1
|
||||
|
||||
# Stay root at runtime: addon-init.sh must chown/mv pre-existing /data
|
||||
# content that may be owned by root from earlier installs, and the upstream
|
||||
# entrypoint no longer drops privileges itself, so a non-root container
|
||||
# can't touch that data at all. This matches the addon's own AppArmor
|
||||
# profile (chown, setuid, setgid, sys_chroot, mount capabilities), which
|
||||
# assumes a root process.
|
||||
# Start as root: addon-init.sh needs it to chown/move pre-existing /data
|
||||
# content that may be owned by root from earlier installs. It drops to
|
||||
# uid 1000 itself (via chroot --userspec) before Elasticsearch actually
|
||||
# starts, since Elasticsearch refuses to run as root and the upstream 8.x
|
||||
# entrypoint no longer does that drop on its own (7.x's did). This matches
|
||||
# the addon's own AppArmor profile (chown, setuid, setgid, sys_chroot,
|
||||
# mount capabilities).
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
#!/bin/bash
|
||||
# shellcheck shell=bash
|
||||
# Sourced by /usr/local/bin/docker-entrypoint.sh (right after "set -e"),
|
||||
# before Elasticsearch starts. Runs as root (the image stays root at
|
||||
# runtime - see Dockerfile); the official entrypoint does not drop
|
||||
# privileges itself, and Elasticsearch ends up running as root too.
|
||||
# before Elasticsearch starts. The container starts as root (see
|
||||
# Dockerfile) so this script can chown/move pre-existing /data content
|
||||
# that may be owned by root from earlier installs. Elasticsearch itself
|
||||
# refuses to run as root, and unlike 7.x the upstream 8.x entrypoint no
|
||||
# longer drops privileges on its own, so this script does it at the end
|
||||
# (section 6) by re-execing the entrypoint as uid 1000. On that re-exec'd
|
||||
# pass this script just returns immediately (see the guard right below).
|
||||
#
|
||||
# Responsibilities:
|
||||
# 1. Export user env_vars from /data/options.json
|
||||
# 2. Default xpack.security.enabled=false (7.x behavior) unless user overrides
|
||||
# 3. Relocate data & config to /data for persistence (idempotent)
|
||||
# 4. Guard major-version data migrations (7.x -> 8.x is automatic)
|
||||
# 5. Record the running version once Elasticsearch is confirmed healthy
|
||||
# 6. Drop root privileges before Elasticsearch actually starts
|
||||
|
||||
if [ -n "${_ADDON_INIT_REEXEC:-}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "-----------------------------------------------------------"
|
||||
echo " Add-on: Elasticsearch server"
|
||||
@@ -141,3 +151,17 @@ if [ "$data_version" != "$current_version" ]; then
|
||||
done
|
||||
) &
|
||||
fi
|
||||
|
||||
############################
|
||||
# 6 Drop privileges #
|
||||
############################
|
||||
|
||||
# Elasticsearch refuses to start as root ("can not run elasticsearch as
|
||||
# root"). 7.x's own entrypoint dropped to uid 1000 via chroot before
|
||||
# launching Elasticsearch; 8.x no longer does that, so do it here instead,
|
||||
# then let the entrypoint continue as uid 1000 (matches the sys_chroot /
|
||||
# setuid / setgid capabilities already granted in the AppArmor profile).
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
export _ADDON_INIT_REEXEC=1
|
||||
exec chroot --userspec=1000:0 / /usr/local/bin/docker-entrypoint.sh "$@"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user