nginx/docker-nginx-unprivileged

proxy_bind transparent whithout root user

Closed this issue · 1 comments

As mentioned in documents, when proxy_bind directive is specified with the transparent parameter, the worker processes can run as a non-root user when the master process has the CAP_NET_RAW capability.
I've specified both NET_ADMIN and CAP_NET_RAW capabilities within the compose file and even privileged is set to true. But, if the NGINX does not run as the root user, I get this error: (or the IPv4 equivalent)

2023/12/16 15:42:36 [alert] 94#94: *182 setsockopt(IPV6_TRANSPARENT) failed (1: Operation not permitted) while connecting to upstream, udp client: 2a01:***, server: [::]:53, upstream: "[2a03:***]:53", bytes from/to client:27/0, bytes from/to upstream:0/0

However, if NGINX explicitly runs as the root user in the Dockerfile and the worker processes run as a non-privileged user such as nginx (user nginx; directive) then there are no socket issues.

By setting the kernel capabilities in the Dockerfile for the NGINX process, there are no permission errors anymore without the root user:

FROM nginx:mainline
RUN \
    apt-get update && apt-get install -y --no-install-recommends libcap2-bin && apt-get clean; \
    setcap cap_net_raw=pe /usr/sbin/nginx;

Probably the 40-warn-bind-transparent.sh can warn the user about it:

#!/bin/sh

if grep -q -Po '^[^#]?\s*proxy_bind .* transparent' /etc/nginx/nginx.conf; then
    if capsh --has-b=cap_net_raw 2>/dev/null; then
        if ! getcap /usr/sbin/nginx | grep -q cap_net_raw; then
            echo "You should set 'cap_net_raw' capability for '/usr/sbin/nginx'"
        fi
    else
        >&2 echo "The container has no 'cap_net_raw' capability set"
    fi
fi

exit 0