#!/bin/sh set -eu # This init script installs a minimal nginx reload wrapper and a sudoers # entry so the `yanpm-agent` user can perform a controlled reload via sudo. WRAPPER_PATH="/usr/local/sbin/yanpm-nginx-reload" SUDOERS_PATH="/etc/sudoers.d/yanpm-agent" AGENT_USER="${YANPM_AGENT_USER:-yanpm-agent}" # validate wrapper VALIDATE_PATH="/usr/local/sbin/yanpm-nginx-validate" # validate file wrapper VALIDATE_FILE_PATH="/usr/local/sbin/yanpm-nginx-validate-file" echo "[cont-init.d] install-reload-wrapper: setting up nginx reload helper" # find nginx binary NGINX_BIN="$(command -v nginx || true)" if [ -z "${NGINX_BIN}" ]; then echo "Warning: nginx binary not found in PATH; wrapper will still be created but may fail at runtime." >&2 NGINX_BIN="/usr/sbin/nginx" fi # Create wrapper mkdir -p /usr/local/sbin /etc/sudoers.d cat > "${WRAPPER_PATH}" <<- 'EOF' #!/bin/sh exec "@NGINX_BIN@" -c /etc/nginx/nginx.conf -s reload EOF # Replace placeholder with actual path sed -i "s|@NGINX_BIN@|${NGINX_BIN}|g" "${WRAPPER_PATH}" || true chmod 0750 "${WRAPPER_PATH}" chown root:root "${WRAPPER_PATH}" || true # # # # Create validate wrapper cat > "${VALIDATE_PATH}" <<- 'EOF' #!/bin/sh exec "@NGINX_BIN@" -c /etc/nginx/nginx.conf -t EOF # Replace placeholder with actual path in validate wrapper sed -i "s|@NGINX_BIN@|${NGINX_BIN}|g" "${VALIDATE_PATH}" || true chmod 0750 "${VALIDATE_PATH}" chown root:root "${VALIDATE_PATH}" || true # # # # Create validate file wrapper (secure) cat > "${VALIDATE_FILE_PATH}" <<-'EOF' #!/bin/sh set -eu if [ $# -ne 1 ]; then echo "Usage: $0 " >&2 exit 2 fi INPUT="$1" # Resolve absolute path if command -v readlink >/dev/null 2>&1; then TARGET="$(readlink -f -- "$INPUT" 2>/dev/null || true)" elif command -v realpath >/dev/null 2>&1; then TARGET="$(realpath -- "$INPUT" 2>/dev/null || true)" else echo "Error: no path resolver (readlink/realpath) available" >&2 exit 3 fi if [ -z "$TARGET" ]; then echo "Error: cannot resolve path: $INPUT" >&2 exit 4 fi # Must be a regular file and not a symlink if [ ! -f "$TARGET" ] || [ -L "$TARGET" ]; then echo "Error: ${TARGET} is not a regular file" >&2 exit 5 fi # must be created by agent user AGENT_UID="$(id -u yanpm-agent 2>/dev/null || true)" if [ -z "$AGENT_UID" ]; then echo "Error: yanpm-agent user not found" >&2 exit 6 fi FILE_UID="$(stat -c %u -- "$TARGET" 2>/dev/null || true)" if [ "$FILE_UID" != "$AGENT_UID" ]; then echo "Error: ${TARGET} not owned by yanpm-agent user" >&2 exit 7 fi # Ensure file is not world-writable; allow typical 664 (rw-rw-r--) if command -v stat >/dev/null 2>&1; then MODE="$(stat -c %a -- "$TARGET" 2>/dev/null || true)" if [ -n "$MODE" ]; then OTHERS=$(( MODE % 10 )) if [ $(( OTHERS & 2 )) -ne 0 ]; then echo "Error: ${TARGET} is world-writable" >&2 exit 8 fi fi elif command -v find >/dev/null 2>&1; then if find "$TARGET" -maxdepth 0 -perm /002 -print -quit >/dev/null 2>&1; then echo "Error: ${TARGET} is world-writable" >&2 exit 8 fi fi exec "@NGINX_BIN@" -c "$TARGET" -t EOF # Replace placeholder with actual path in validate file wrapper sed -i "s|@NGINX_BIN@|${NGINX_BIN}|g" "${VALIDATE_FILE_PATH}" || true chmod 0750 "${VALIDATE_FILE_PATH}" chown root:root "${VALIDATE_FILE_PATH}" || true echo "Created wrapper: ${WRAPPER_PATH} (owned by root, mode 750)" # # # # Ensure sudoers entry exists allowing the agent to run only this wrapper as root if command -v sudo >/dev/null 2>&1; then echo "sudo present; creating sudoers entry" cat > "${SUDOERS_PATH}" <<- EOF # Allow ${AGENT_USER} to run the nginx reload and validate wrappers without a password ${AGENT_USER} ALL=(root) NOPASSWD: ${WRAPPER_PATH}, ${VALIDATE_PATH}, ${VALIDATE_FILE_PATH} EOF chmod 0440 "${SUDOERS_PATH}" || true echo "Wrote sudoers entry: ${SUDOERS_PATH}" else echo "sudo not found; attempting to install" if command -v apk >/dev/null 2>&1; then apk add --no-cache sudo || true elif command -v apt-get >/dev/null 2>&1; then apt-get update || true apt-get install -y sudo || true elif command -v yum >/dev/null 2>&1; then yum install -y sudo || true else echo "No known package manager to install sudo; please ensure sudo is available in the image." >&2 fi if command -v sudo >/dev/null 2>&1; then cat > "${SUDOERS_PATH}" <<- EOF # Allow ${AGENT_USER} to run the nginx reload and validate wrappers without a password ${AGENT_USER} ALL=(root) NOPASSWD: ${WRAPPER_PATH}, ${VALIDATE_PATH}, ${VALIDATE_FILE_PATH} EOF chmod 0440 "${SUDOERS_PATH}" || true echo "Installed sudo and wrote sudoers entry: ${SUDOERS_PATH}" else echo "Failed to install sudo; the agent will not be able to reload nginx via sudo." >&2 fi fi exit 0