在 pod 中运行 Nginx,无需提权

问题描述 投票:0回答:1

我试图让 Nginx 以最小的权限运行,同时能够充当端口 80 上的代理。换句话说,这是我正在使用的 securityContext:

            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsNonRoot: true
              runAsUser: 12321
              runAsGroup: 12321
              privileged: false
              capabilities:
                drop:
                - all
                add: ["NET_BIND_SERVICE"]

据我收集到的有关该主题的大多数 stackoverflow 问题,设置为

allowPrivilegeEscalation
true
。除此之外,我发现 Bridcrew 的这个博客将其设置为
false
但我无法在我这边重现他们的示例。

我也尝试使用

nginxinc/nginx-unprivileged
基础图像,但也没有成功。


这是我的 Dockerfile。它由大量

chown
chmod
ing 组成,但我还安装了 libcap2,这样我就可以设置
NET_BIND_SERVICE
功能并移动一些文件以获得自定义入口点。

FROM nginx

ENV NGINX_USER="proxy-user" \
    NGINXR_UID="12321" \
    NGINX_GROUP="proxy-group" \
    NGINX_GID="12321"  

RUN set -ex; \
  groupadd -r --gid "$NGINX_GID" "$NGINX_GROUP"; \
  useradd -r --uid "$NGINXR_UID" --gid "$NGINX_GID" "$NGINX_USER" 


# Create empty pid file and assign it to the proxy user
RUN touch /var/run/nginx.pid && \
    chown -R proxy-user:proxy-group /var/run/nginx.pid

# Change permissions of other nginx files
RUN chmod +x /usr/sbin/nginx && \
    chown -R proxy-user:proxy-group /usr/share/nginx/html && \
    chown -R proxy-user:proxy-group /var/cache/nginx && \
    chown -R proxy-user:proxy-group /var/log/nginx && \
    chown -R proxy-user:proxy-group /etc/nginx/conf.d

# Install libcap and set the NET_BIND_SERVICE capability to the Nginx binary
RUN apt-get -qq update && \
    apt-get -qq install --no-install-recommends libcap2-bin -y && \
    setcap CAP_NET_BIND_SERVICE=ep /usr/sbin/nginx

COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx.conf.template /etc/nginx/templates/

# Move all nginx files to another directory. We will later mount a writable directory under /etc/nginx/ and copy these files back  before launching Nginx
RUN mv /etc/nginx /etc/nginx-defaults

# This file does the copying and launches nginx (via docker-entrypoint.sh)
COPY entrypoint.sh .
RUN chmod +x ./entrypoint.sh
USER proxy-user

ENTRYPOINT ./entrypoint.sh

正如评论中提到的,我们将安装几个 Nginx 可以使用的可写空目录:

            volumeMounts:
              - name: nginx-etc
                mountPath: /etc/nginx
              - name: nginx-cache
                mountPath: /var/cache/nginx
              - name: nginx-tmp
                mountPath: /tmp/nginx
              - name: nginx-pid
                mountPath: /var/run

在 nginx.conf 中,有几个路径指向这些目录,以防它们还不是默认值:

http {
    proxy_temp_path /tmp/nginx/proxy_temp;
    client_body_temp_path /tmp/nginx/client_temp;
    fastcgi_temp_path /tmp/nginx/fastcgi_temp;
    uwsgi_temp_path /tmp/nginx/uwsgi_temp;
    scgi_temp_path /tmp/nginx/scgi_temp;

    ...
}

这是自定义入口点

#!/bin/sh

echo "Running from custom entrypoint"

# Move the nginx files back to the default directory
cp -a /etc/nginx-defaults/. /etc/nginx/

# Launch nginx through the docker entrypoint
./docker-entrypoint.sh nginx

我收到的错误是由于权限被拒绝,它无法绑定到端口 80:

2023/03/31 12:31:03 [emerg] 11#11: bind() to 0.0.0.0:80 failed (13: Permission denied)
nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

allowPrivilegeEscalation
设置为
true
可解决此问题。以及绑定到非特权端口(>1024),但是有没有一种方法可以解决特权升级问题,而无需绑定到更高的端口?


根据要求编辑要使用的整个 pod 的 yaml。此示例使用未修改的 nginx 映像,该映像也尝试绑定到端口 80 并显示绑定错误。

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - name: proxy
      image: nginx
      imagePullPolicy: Always
      volumeMounts:
        - name: nginx-cache
          mountPath: /var/cache/nginx
        - name: nginx-tmp
          mountPath: /tmp/nginx
        - name: nginx-pid
          mountPath: /var/run
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        runAsNonRoot: true
        runAsUser: 12321
        runAsGroup: 12321
        privileged: false
        capabilities:
          drop:
          - all
          add: ["NET_BIND_SERVICE"]
  volumes:
  - name: nginx-cache
    emptyDir:
      sizeLimit: 1Mi
  - name: nginx-tmp
    emptyDir:
      sizeLimit: 1Mi
  - name: nginx-pid
    emptyDir:
      sizeLimit: 1Mi
docker kubernetes nginx security-context
1个回答
0
投票

如果没有特权访问,您无法找到特权端口(小于 1024)。 https://medium.com/@natrajrams4/binding-to-low-ports-as-non-root-user-in-kubernetes-79666f52c6ae有一些技巧。但我建议你使用更高数量的端口

© www.soinside.com 2019 - 2024. All rights reserved.