diff --git a/src/bci_build/package/appcontainers.py b/src/bci_build/package/appcontainers.py index 0025b9906..b747a8269 100644 --- a/src/bci_build/package/appcontainers.py +++ b/src/bci_build/package/appcontainers.py @@ -251,6 +251,7 @@ def _generate_prometheus_family_healthcheck(port: int) -> str: "LICENSE", "20-envsubst-on-templates.sh", "30-tune-worker-processes.sh", + "40-unprivileged-mode.sh", "index.html", ): _NGINX_FILES[filename] = (Path(__file__).parent / "nginx" / filename).read_bytes() @@ -278,6 +279,8 @@ def _get_nginx_kwargs(os_version: OsVersion): "nginx", "findutils", _envsubst_pkg_name(os_version), + "sed", + "grep", ] ) + (["libcurl-mini4"] if os_version.is_sl16 else []), @@ -293,13 +296,14 @@ def _get_nginx_kwargs(os_version: OsVersion): ), "custom_end": textwrap.dedent(f""" {DOCKERFILE_RUN} mkdir /docker-entrypoint.d - COPY [1-3]0-*.sh /docker-entrypoint.d/ + COPY [1-4]0-*.sh /docker-entrypoint.d/ COPY docker-entrypoint.sh /usr/local/bin COPY index.html /srv/www/htdocs/ {DOCKERFILE_RUN} chmod +x /docker-entrypoint.d/*.sh /usr/local/bin/docker-entrypoint.sh - {DOCKERFILE_RUN} install -d -o nginx -g nginx -m 750 /var/log/nginx; \ - ln -sf /dev/stdout /var/log/nginx/access.log; \ - ln -sf /dev/stderr /var/log/nginx/error.log + {DOCKERFILE_RUN} set -euo pipefail; mkdir -p /var/cache/nginx /var/run/nginx /tmp/client_temp /tmp/proxy_temp /tmp/fastcgi_temp /tmp/uwsgi_temp /tmp/scgi_temp;\ + ln -sf /dev/stdout /var/log/nginx/access.log;\ + ln -sf /dev/stderr /var/log/nginx/error.log;\ + chmod -R 777 /var/cache/nginx /etc/nginx /var/run/nginx /var/log/nginx /tmp/client_temp /tmp/proxy_temp /tmp/fastcgi_temp /tmp/uwsgi_temp /tmp/scgi_temp; STOPSIGNAL SIGQUIT"""), } diff --git a/src/bci_build/package/nginx/40-unprivileged-mode.sh b/src/bci_build/package/nginx/40-unprivileged-mode.sh new file mode 100644 index 000000000..7936cc6cf --- /dev/null +++ b/src/bci_build/package/nginx/40-unprivileged-mode.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +set -e + +CURRENT_UID=$(id -u) +if [ "$CURRENT_UID" -gt "0" ]; then + echo "$0: Running as unprivileged user (UID: $CURRENT_UID). Configuring for unprivileged mode (Port 8080)." + + CONF_FILES="/etc/nginx/conf.d/default.conf /etc/nginx/nginx.conf" + + for FILE in $CONF_FILES; do + if [ -w "$FILE" ]; then + if grep -q "listen .*80;" "$FILE"; then + echo "Changing port 80 to 8080 in $FILE" + sed 's/listen\s*80;/listen 8080;/g' "$FILE" > /tmp/client_temp/nginx_swap.conf && \ + cat /tmp/client_temp/nginx_swap.conf > "$FILE" && \ + rm -f /tmp/client_temp/nginx_swap.conf + fi + + if [ "$FILE" = "/etc/nginx/nginx.conf" ]; then + echo "Redirecting NGINX temp paths and setting PID to /tmp in $FILE" + sed -e '/^user/d' \ + -e 's,^#\?\s*pid\s\+.*;$,pid /var/run/nginx/nginx.pid;,' \ + -e '/http {/a \ client_body_temp_path /tmp/client_temp;\n proxy_temp_path /tmp/proxy_temp;\n fastcgi_temp_path /tmp/fastcgi_temp;\n uwsgi_temp_path /tmp/uwsgi_temp;\n scgi_temp_path /tmp/scgi_temp;' \ + "$FILE" > /tmp/client_temp/nginx_ultra.conf && \ + cat /tmp/client_temp/nginx_ultra.conf > "$FILE" && \ + rm -f /tmp/client_temp/nginx_ultra.conf + echo "$0: Removed 'user' directive and updated PID path." + fi + fi + done + + echo "$0: Listening on port 8080." +fi diff --git a/src/bci_build/package/nginx/README.md.j2 b/src/bci_build/package/nginx/README.md.j2 index 2ac2f2be2..5343bfdad 100644 --- a/src/bci_build/package/nginx/README.md.j2 +++ b/src/bci_build/package/nginx/README.md.j2 @@ -41,6 +41,12 @@ The template above is then rendered to `/etc/nginx/conf.d/default.conf` as follo ```nginx listen 80; ``` +## Running nginx as a non-root user +To run the image as a less privileged user using the `nginx` user, do the following: +```ShellSession +$ podman run -it --user nginx --rm -p 8080:8080 -v /path/to/html/:/srv/www/htdocs/:Z {{ image.pretty_reference }} +``` +**Note:** When running as the `nginx` user the default port is 8080. ## Environment variables