nginx_mount_issue

Home

Nginx hostPath Mount Issue Demonstration

This document demonstrates a potential security concern when using hostPath volumes in Kubernetes. It shows how a symbolic link created in a hostPath volume by one pod can expose files from the underlying node to other pods that mount the same hostPath.

Caution: Using hostPath volumes can have security implications if not managed carefully. This example illustrates one such risk.

Scenario Setup

  1. Create a directory on the target node: On the Kubernetes node where you intend to run the pods (e.g., student4-2 as specified in the nodeSelector), create a directory. This directory will be used as the hostPath.

    # On node student4-2
    sudo mkdir /html
    sudo chmod 777 /html # For demonstration purposes; be cautious with permissions

Pod 1 (nginxer)

  1. Create the first Pod manifest (nginxer.yaml): This Pod mounts the /html directory from the node into /usr/share/nginx/html.

    cat >nginxer.yaml <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginxer
    spec:
      containers:
      - name: nginxer
        image: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      nodeSelector:
        kubernetes.io/hostname: student4-2 # Ensure this node exists and has /html
      volumes:
      - name: html
        hostPath:
          path: /html
          type: Directory
    EOF

    (Note: Changed the language to bash for the cat command, the inner content is YAML but created via bash)

  2. Apply the Pod manifest:

    kubectl apply -f nginxer.yaml
  3. Create a symbolic link inside Pod 1: Exec into nginxer and create a symbolic link from within the mounted hostPath to a file on the node (e.g., /etc/hostname which resolves to the node's hostname, but could be any file the pod's effective user on the node can access).

    kubectl exec -it nginxer -- bash -c "cd /usr/share/nginx/html && ln -s /etc/hostname linked_hostname"

    (Modified to be a single exec command for clarity and to ensure it runs sequentially. Also changed the link name for clarity.)

Pod 2 (nginxer2)

  1. Create the second Pod manifest (nginxer2.yaml): This Pod is identical to the first one and mounts the same /html hostPath.

    (Note: Changed the language to bash for the cat command)

  2. Apply the Pod manifest:

  3. Access the linked content from Pod 2: Exec into nginxer2 and observe that it can now access the content of /etc/hostname from the node via the symbolic link created by Pod 1.

    (Changed to directly cat the file to show the content)

Explanation of the Issue

When nginxer creates a symbolic link (linked_hostname) within its /usr/share/nginx/html directory (which is the /html directory from the host node), that symbolic link becomes part of the node's filesystem at /html/linked_hostname.

Since nginxer2 mounts the same /html hostPath from the node, it sees the symbolic link created by nginxer. When nginxer2 (or any process accessing Nginx served from nginxer2) tries to read linked_hostname, the operating system on the node resolves this symbolic link. If the link points to a sensitive file on the node (e.g., /etc/shadow, service account tokens, or other configuration files), and the Nginx process (or the exec'd user) in nginxer2 has permissions to read it (often running as root inside the container, which might map to a privileged user or root on the node depending on setup), then nginxer2 can effectively read that file from the node.

This demonstrates that actions within one pod using a shared hostPath can expose node files to other pods using the same hostPath, potentially leading to information disclosure if not carefully managed.

Home

Last updated