diff --git a/build/dev-apko.sh b/build/dev-apko.sh index ff578acef..e8a347918 100755 --- a/build/dev-apko.sh +++ b/build/dev-apko.sh @@ -63,7 +63,7 @@ if [ "${SKIP_IMAGE_CREATION:-false}" = "false" ]; then make build image docker tag "${REGISTRY}/controller:${TAG}" "${DEV_IMAGE}" fi -export K8S_VERSION=${K8S_VERSION:-v1.24.2@sha256:1f0cee2282f43150b52dc7933183ed96abdcfc8d293f30ec07082495874876f1} +export K8S_VERSION=${K8S_VERSION:-v1.25.2@sha256:9be91e9e9cdf116809841fc77ebdb8845443c4c72fe5218f3ae9eb57fdb4bace} KIND_CLUSTER_NAME="ingress-nginx-dev" @@ -106,7 +106,6 @@ controller: image: "${DEV_IMAGE}" tag: "${TAG}" digest: "${DIGEST}" - runAsUser: 0 config: worker-processes: "1" podLabels: diff --git a/distroless-build/Makefile b/distroless-build/Makefile index 8d6accf92..ed3fedaac 100644 --- a/distroless-build/Makefile +++ b/distroless-build/Makefile @@ -28,9 +28,9 @@ IMAGE ?= $(REGISTRY)/controller ARCH := $(shell uname -m) MELANGE_DIR ?= melange APKO_DIR ?= apko -MELANGE ?= docker run --rm --privileged -v "${PWD}":/work distroless.dev/melange:latest -MELANGE_DETACHED ?= docker run -d --rm --privileged -v "${PWD}":/work distroless.dev/melange:latest -APKO ?= docker run --rm -v "${PWD}":/work distroless.dev/apko:latest +MELANGE ?= docker run --rm --privileged -w /work -v "${PWD}":/work distroless.dev/melange:latest +MELANGE_DETACHED ?= docker run -d -w /work --rm --privileged -v "${PWD}":/work distroless.dev/melange:latest +APKO ?= docker run --rm -w /work -v "${PWD}":/work ko.local:38f15a95ae791cd5deab7d054cb3c15129cedb25a2e30d0308a5f6c63c9865e3 KEY ?= melange.rsa REPO ?= packages TEMPLATE ?= melange/nginx-templates.json @@ -39,7 +39,7 @@ MELANGE_INGRESS_OPT ?= -k ${KEY}.pub --signing-key ${KEY} --arch ${ARCHS} --empt APKO_OPTS ?= -k ${KEY}.pub --debug --use-docker-mediatypes --sbom=false --build-arch ${ARCHS} ${APKO_DIR}/${FILE}.yaml KEY ?= melange.rsa REPO ?= $(shell pwd)/packages -ARCHS?="amd64,arm64,arm/v6,arm/v7,s390x" +ARCHS ?="amd64,arm64,arm/v6,arm/v7,s390x" define build-package docker run $(2) --rm --privileged -v "${PWD}":/work distroless.dev/melange:latest build ${MELANGE_DIR}/$(1).yaml ${MELANGE_OPTS} --template '$(shell cat ${TEMPLATE})' diff --git a/distroless-build/apko/ingress-debug.yaml b/distroless-build/apko/ingress-debug.yaml index 22785b2b0..0193e0972 100644 --- a/distroless-build/apko/ingress-debug.yaml +++ b/distroless-build/apko/ingress-debug.yaml @@ -39,7 +39,13 @@ contents: - lua-resty-string@local - lua-resty-upload@local accounts: - run-as: root + groups: + - groupname: www-data + gid: 101 + users: + - username: www-data + uid: 101 + run-as: www-data annotations: org.opencontainers.image.title: "NGINX Ingress Controller for Kubernetes" @@ -60,7 +66,16 @@ work-dir: /etc/nginx paths: - - path: /usr/bin/nginx + - path: /tmp/nginx/client-body + type: empty-file + permissions: 0o777 + recursive: true + - path: /nginx-ingress-controller + type: capabilities + capabilities: + - cap_net_bind_service=+ep + permissions: 0o777 + - path: /usr/bin/nginx type: hardlink source: /usr/local/nginx/sbin/nginx permissions: 0o777 diff --git a/distroless-build/apko/ingress.yaml b/distroless-build/apko/ingress.yaml index 49ebf3bd1..b0da99d07 100644 --- a/distroless-build/apko/ingress.yaml +++ b/distroless-build/apko/ingress.yaml @@ -36,7 +36,7 @@ accounts: users: - username: www-data uid: 101 - run-as: root + run-as: www-data annotations: org.opencontainers.image.title: "NGINX Ingress Controller for Kubernetes" diff --git a/distroless-build/melange/ingress-nginx-controller.yaml b/distroless-build/melange/ingress.yaml similarity index 100% rename from distroless-build/melange/ingress-nginx-controller.yaml rename to distroless-build/melange/ingress.yaml diff --git a/distroless-build/melange/nginx-templates.json b/distroless-build/melange/nginx-templates.json index 1672e5c46..4b9db0fb0 100644 --- a/distroless-build/melange/nginx-templates.json +++ b/distroless-build/melange/nginx-templates.json @@ -1,5 +1,5 @@ { - "INGRESS_NGINX_VERSION": "main", + "INGRESS_NGINX_VERSION": "debug", "PKG": "k8s.io/ingress-nginx", "TAG": "main", "COMMIT_SHA": "cee95b50a", diff --git a/internal/net/net.go b/internal/net/net.go index 712262f3a..4bb169295 100644 --- a/internal/net/net.go +++ b/internal/net/net.go @@ -17,8 +17,12 @@ limitations under the License. package net import ( + "errors" "fmt" + "k8s.io/klog/v2" + "kernel.org/pub/linux/libs/security/libcap/cap" _net "net" + "os" "os/exec" ) @@ -59,3 +63,32 @@ func IsIPv6Enabled() bool { return false } + +// CheckCapNetBind checks if cap_net_bind_service is set for ingress +func CheckCapNetBind() error { + processID := os.Getpid() + set, err := cap.GetPID(processID) + if err != nil { + return err + } + klog.InfoS("ingress-nginx capability set %v", set.String()) + + //check effective + // Value 10 = NET_BIND_SERVICE + effective, err := set.GetFlag(0, 10) + if err != nil { + return err + } + + //check permitted + permitted, err := set.GetFlag(1, 10) + if err != nil { + return err + } + klog.InfoS("ingress-nginx capabilities: permitted %v effective %v", permitted, effective) + if !permitted && !effective { + return errors.New(fmt.Sprintf("ingress-nginx capabilities: permitted %v effective %v", permitted, effective)) + } + + return nil +} diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go index 370510380..7a9d186c5 100644 --- a/pkg/flags/flags.go +++ b/pkg/flags/flags.go @@ -35,7 +35,7 @@ import ( "k8s.io/ingress-nginx/internal/ingress/status" ing_net "k8s.io/ingress-nginx/internal/net" "k8s.io/ingress-nginx/internal/nginx" - klog "k8s.io/klog/v2" + "k8s.io/klog/v2" ) // TODO: We should split the flags functions between common for all programs @@ -254,6 +254,13 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g parser.AnnotationsPrefix = *annotationsPrefix + //Check if ingress-nginx controller has cap_net_bind_service privileges + klog.InfoS("Ingress-nginx http port %v, https port %v", *httpPort, *httpsPort) + if *httpPort == 80 || *httpsPort == 443 { + klog.InfoS("Checking Ingress-nginx Capabilities, http port %v, https port %v", *httpPort, *httpsPort) + return false, nil, ing_net.CheckCapNetBind() + } + // check port collisions if !ing_net.IsPortAvailable(*httpPort) { return false, nil, fmt.Errorf("port %v is already in use. Please check the flag --http-port", *httpPort)