{"id":24308917,"url":"https://github.com/szwendacz99/securing-linux-containers","last_synced_at":"2026-04-10T16:37:14.963Z","repository":{"id":270732281,"uuid":"911191132","full_name":"Szwendacz99/Securing-Linux-Containers","owner":"Szwendacz99","description":"Short document about how to keep Linux containers secure","archived":false,"fork":false,"pushed_at":"2025-01-04T00:22:04.000Z","size":99,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-06T00:30:45.388Z","etag":null,"topics":["containers","cybersecurity","docker","kubernetes","linux","podman","security"],"latest_commit_sha":null,"homepage":"https://forgejo.maciej.cloud/Szwendacz/Securing-Linux-Containers","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Szwendacz99.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-02T12:55:29.000Z","updated_at":"2025-01-03T16:09:49.000Z","dependencies_parsed_at":"2025-01-02T18:34:03.492Z","dependency_job_id":"b01c9cae-2b24-4caa-bb58-79bcb0ea09d2","html_url":"https://github.com/Szwendacz99/Securing-Linux-Containers","commit_stats":null,"previous_names":["szwendacz99/securing-linux-containers"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Szwendacz99%2FSecuring-Linux-Containers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Szwendacz99%2FSecuring-Linux-Containers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Szwendacz99%2FSecuring-Linux-Containers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Szwendacz99%2FSecuring-Linux-Containers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Szwendacz99","download_url":"https://codeload.github.com/Szwendacz99/Securing-Linux-Containers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242277694,"owners_count":20101545,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["containers","cybersecurity","docker","kubernetes","linux","podman","security"],"created_at":"2025-01-17T05:11:55.459Z","updated_at":"2026-04-10T16:37:14.914Z","avatar_url":"https://github.com/Szwendacz99.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Securing Linux Containers\n\n## 1. Table of contents\n\n\u003c!--toc:start--\u003e\n\n- [Securing Linux Containers](#securing-linux-containers)\n  - [1. Table of contents](#1-table-of-contents)\n  - [2. Introduction](#2-introduction)\n  - [3. Secrets](#3-secrets)\n    - [3.1 Alternatives](#31-alternatives)\n      - [3.1.1 Files](#311-files)\n      - [3.1.2 Secrets Management Services (kubernetes)](#312-secrets-management-services-kubernetes)\n  - [4. Users and groups](#4-users-and-groups)\n    - [Setting user and group](#setting-user-and-group)\n      - [Containerfile/Dockerfile](#containerfiledockerfile)\n      - [Changing user/group arbitrarily on container startup](#changing-usergroup-arbitrarily-on-container-startup)\n    - [Additional security](#additional-security)\n  - [5. Filesystem](#5-filesystem)\n    - [Read-only](#read-only)\n    - [Additional Protection with nosuid, noexec, and nodev](#additional-protection-with-nosuid-noexec-and-nodev)\n  - [6. Resources limits](#6-resources-limits)\n    - [CPU](#cpu)\n    - [RAM](#ram)\n  - [7. Network](#7-network)\n    - [Desktop tools](#desktop-tools)\n    - [Kubernetes](#kubernetes)\n  - [8. OCI Images](#8-oci-images)\n  - [8.1 Building](#81-building)\n  - [8.2 Scanning](#82-scanning)\n  - [9. Selinux](#9-selinux)\n\n\u003c!--toc:end--\u003e\n\n## 2. Introduction\n\nThis document is a collection of simple, very generic tips and best\npractices related to security of Linux containers. Contenerization is\nconsidered safer by default, but then one can hear about discovered\nvulnerabilities that are primarly bad for applications in containers\n(Example: [CVE-2023-49103](https://nvd.nist.gov/vuln/detail/CVE-2023-49103)).\nTips and best practices collected here should help raise awarness about\nhow to keep containers really secure. Contents are kept container-engine\nagnostic, but examples will be based on actual implementations (Podman, k8s).\n\n## 3. Secrets\n\nSecret is the most vulnerable data, as it usually can open access to other\nprivate data. They might also allow modification of the environment, which\nmeans possibilities for further access or many other forms of attack.\n\n\u003e [!WARNING]\n\u003e Don't use environment variables for secrets\n\nContainer isolation made providing and managing secrets somewhat harder, as\nthey need to cross the additional barier. This casued the rather dangerous\ntrend of providing secrets among many other configuration data in form of\nenvironment variables. At first sight it might look like good idea, but when\nactually compared to other means of storing secrets it turns out that\nenvironment variables might be much easier to access by attacker, than\nfor example arbitrary files. [CVE-2023-49103](https://nvd.nist.gov/vuln/detail/CVE-2023-49103)\nis only an example of vulnerability which was considered to be more\ndangerous for contenerized apps, because of the vulnerability\nbeing based on gaining access to env variables.\n\n### 3.1 Alternatives\n\n#### 3.1.1 Files\n\nFiles with secrets are common and broadly supported. With proper setup they can\nbe also very secure.\n\n- Keep configuration and secret files on entirely different path than other data\n- If application runs main process under different user than worker processes\n  (worker usually have direct contact with user interaction), the configuration\n  should not be readable by the worker process user.\n- Depending on the technology used, storage of the secret files inside of a\n  container could be temporary/volatile. In kubernetes Secret objects are mounted\n  as tmpfs. Example for mounting secret as tmpfs in pod:\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: app\nspec:\n  containers:\n  - name: app\n    image: registry.fedoraproject.org/fedora-minimal:latest\n    command: [ \"sleep\", \"infinity\" ]\n    volumeMounts:\n      - mountPath: /config\n        name: config\n  volumes:\n  - name: config\n    secret:\n      secretName: config\n```\n\nThis produces readonly tmpfs mount inside:\n\n```bash\nbash-5.2# df -h /config/\nFilesystem      Size  Used Avail Use% Mounted on\ntmpfs           4.8G  4.0K  4.8G   1% /config\n\nbash-5.2# ls -la /config/\ntotal 0\ndrwxrwxrwt. 3 root root 100 Nov  9 14:00 .\ndrwxr-xr-x. 1 root root  24 Nov  9 14:00 ..\ndrwxr-xr-x. 2 root root  60 Nov  9 14:00 ..2024_11_09_14_00_47.4065932771\nlrwxrwxrwx. 1 root root  32 Nov  9 14:00 ..data -\u003e ..2024_11_09_14_00_47.4065932771\nlrwxrwxrwx. 1 root root  18 Nov  9 14:00 secret.conf -\u003e ..data/secret.conf\n```\n\n#### 3.1.2 Secrets Management Services (kubernetes)\n\nThere are sophisticated tools for secret management and their deployment,\navailable for kubernetes. For example HashiCorp Vault. It offers dynamic\nsecrets, secret rotation, and access policies. Such tools are most helpfull in\nlarge environments and infrastructures, where secret management is split\namong many people.\n\n## 4. Users and groups\n\nUsers and groups are standard mechanisms for security and permissions limiting\nin unix-like systems. Contenerization engines usually have possibility to\narbitrarily assign them to the contenerized program process.\n\n\u003e [!NOTE]\n\u003e Both user and group can always be specified by numeric id even if no actual\n\u003e user or group is assigned to them. When specifying with string name, the user\n\u003e or group must exist **inside** of the container (`/etc/passwd`, `/etc/group`)\n\n\u003e [!NOTE]\n\u003e Processes of rootless containers or containers with uid/gid mapping have\n\u003e different id's inside of container and outside. This can complicate things\n\u003e even more, but that also usually greatly increases security.\n\u003e In some scenarios such mapping can also cause trouble with files in\n\u003e container image, if their id's are out of mapping range.\n\n### Setting user and group\n\nContainers have default user and group specified by Containerfile, but\nit can be changed when starting the container.\n\n#### Containerfile/Dockerfile\n\nIn Containerfile the user/group assignment might take place many times in\nsingle build. Typical reason for that is to have high privilige (root) during\nbuild, and then set default to unpriviliged user at the end of build, so that\ncontainers will use it by default.\n\nSetting just user to \"user1\"\n\n```Dockerfile\nUSER user1\n```\n\nSetting both user and group\n\n```Dockerfile\nUSER user1:group1\n```\n\nSetting just group\n\n```Dockerfile\nUSER :group1\n```\n\n#### Changing user/group arbitrarily on container startup\n\nPodman and Docker uses `--user` or shorter `-u` flag to specify both user and\ngroup. The syntax is the same as shown for Containerfile. Example of\nsetting both user and group to bin, but user is specified with number ID:\n\n```bash\n❯ podman run --rm -it --user 1:bin registry.fedoraproject.org/fedora-minimal\nbash-5.2$ whoami\nbin\nbash-5.2$ groups\nbin\nbash-5.2$ grep ^bin /etc/passwd\nbin:x:1:1:bin:/bin:/usr/sbin/nologin\nbash-5.2$ grep ^bin /etc/group\nbin:x:1:\n```\n\nFor Kubernetes, the user and group specification is located in pod definition:\n\n```yaml\napiVersion: v1\nkind: Pod\nspec:\n  securityContext:\n    runAsUser: 1\n    runAsGroup: 1\n```\n\n\u003e [!NOTE]\n\u003e In kubernetes you can't specify user nor group using string name.\n\u003e Only numeric values are allowed.\n\n### Additional security\n\nLinux kernel provides usefull feature - [No New Privileges Flag](https://docs.kernel.org/userspace-api/no_new_privs.html).\nIf set for process, it prevents the process from gaining more privileges than\nparent process. This effectively blocks use of capabilities, and setgid,setuid\nflags on files, which are known and powerfull tools for exploitation.\n\nIn Podman and Docker, the flag can be enabled using parameter `--security-opt no-new-privileges`\n\nIn Kubernetes, there is section related to security context per container:\n\n```yaml\n(....)\n  containers:\n  - name: mycontainer\n    securityContext:\n      allowPrivilegeEscalation: false\n(....)\n```\n\n## 5. Filesystem\n\nBy default the filesystem security of containers is quite good, specially\nwhen used with other mechanisms like selinux or mapped UIDs/GIDs, but it\nstill have field for improvement.\n\n### Read-only\n\nBoth base filesystem and mounted volumes can be set to readonly.\nWhen using a read-only filesystem, certain directories may still need to be\nwritable, such as /tmp or /var/tmp. This is where tmpfs (temporary filesystem)\ncan be used. tmpfs filesystem mounts a temporary filesystem in memory, allowing these\ndirectories to be writable without compromising the overall read-only nature\nof the filesystem. The directory will be empty and will vanish on container\nshutdown which also increases security, if the temporary data is vulnerable.\n\nRunning Podman container with readonly base filesystem using `--read-only`:\n\n```bash\npodman run --rm -it --read-only registry.fedoraproject.org/fedora-minimal\n```\n\n\u003e [!Note]\n\u003e Podman simplifies use of --read-only by automatically creating read-write\n\u003e tmpfs mounts inside in places where it is usually needed, like `/dev/shm`,\n\u003e `/tmp`, `/run`, etc...\n\nMounting tmpfs dir with specific size limit to Podman container using `--tmpfs`:\n\n```bash\npodman run --rm -it --read-only --tmpfs /tmp:rw,size=64m registry.fedoraproject.org/fedora-minimal\n```\n\nMounting podman volume as read-only is done by specifying `ro` mount option\nafter `:` separator, for example `--tmpfs /test:ro`, `-v /host/path:/container/path:ro`\n\nOn Kubernetes to set base filesystem of a container to read-only, there is\n`readOnlyRootFilesystem: true` attribute in container security context. To\nmount any volume as read-only, there is attribute `readOnly: true` in mount\nsection.\n\nFull kubernetes example of read-only base filesystem and example volume:\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: readonly-pod\nspec:\n  containers:\n  - name: mycontainer\n    image: registry.fedoraproject.org/fedora-minimal:latest\n    command: [\"sleep\", \"infinity\"]\n    securityContext:\n      readOnlyRootFilesystem: true\n    volumeMounts:\n    - mountPath: /test\n      readOnly: true\n      name: tmpfs\n  volumes:\n  - name: tmpfs\n    emptyDir:\n      medium: Memory\n      sizeLimit: 64Mi\n```\n\n### Additional Protection with nosuid, noexec, and nodev\n\nTo further enhance security, you can use the nosuid, noexec, and nodev mount\noptions for volumes. They can also be used for tmpfs mounts.\n\n- nosuid: Prevents the execution of set-user-identifier or set-group-identifier programs.\n- noexec: Prevents the execution of any binaries on the mounted filesystem.\n- nodev: Prevents the use of device files on the mounted filesystem.\n\nExample using Podman:\n\n```bash\n❯ podman run --rm -it --read-only --tmpfs /test:nodev,nosuid,noexec registry.fedoraproject.org/fedora-minimal\nbash-5.2# mount | grep /test\ntmpfs on /test type tmpfs (rw,nosuid,nodev,noexec,relatime,context=\"system_u:object_r:container_file_t:s0:c240,c646\",uid=1000,gid=1000,inode64)\n```\n\n## 6. Resources limits\n\nSetting resource limits for containers is required to ensure that no single\ncontainer can consume excessive resources, which could impact the performance\nand stability of the entire system or neighbour systems.\n\n### CPU\n\nSince there is no virtualization, the cpu is visible with all its cores and\nthreads inside of a container. Therefore cpu limiting is done by limiting\ncpu time using scheduler. Usually the limitation unit is vCPU. In Podman\nyou can set the limit using `--cpus` flag. For example `--cpus=2` will limit\ncpu time to 2/X of total cpu time current host have. In case of cpu with 16\nthreads this means that container can use up to 12.5% of whole cpu power. This\ndoes not mean assigning the cpu time to specific physical threads, therefore\nhigh load in that container will be loadbalanced on all physical threads,\nwithout allowing to utilize too much of time.\n\nIn case of Kubernetes this works the same, limits are specified per container:\n\n```yaml\n(....)\nspec:\n  containers:\n  - name: app\n    resources:\n      limits:\n        cpu: \"2\"\n(....)\n```\n\n### RAM\n\nLimiting RAM for container looks similar to cpu limiting. Except that\nwhen software inside of a container tries to cross the limits, it will be\nhandled more brutally - RAM hungry process will be killed. This might be\nnot that intuitive for application, as here again the app sees all the memory\navailable in host system, and it does not know about the limits (unless\nconfigured).\n\nPodman have simple flag `--memory` which configures the limit. `--memory=512MiB`\nwill limit to 512MiB.\n\nKubernetes works similar:\n\n```yaml\n(....)\nspec:\n  containers:\n  - name: app\n    resources:\n      limits:\n        memory: \"512Mi\"\n(....)\n```\n\n## 7. Network\n\nFor network isolation, Linux containers leverage network namespaces.\n\nA network namespace is a feature provided by the Linux kernel that allows for\nthe creation of isolated, independent network stacks. Each network namespace\nhas its own separate set of network interfaces, routing tables, firewall\nrules, and other network-related resources. This gives complex possibilities\nfor network configuration, but it stimulates differences between\ncontainer engine implementations.\nAdditionally rootless containers, which are considered safer, need\nto fallback to different network components, with reduced\npossibilities, as managing network is strictly root based.\n\n### Desktop tools\n\nContainer engines suitable for desktop like Podman usage usually have limited\noptions for network configuration. They allow to isolate pods from host and\neach other with different network addresses pools, and even disabling the\nnetwork at all, which is very safe, but very rare.\n\nFor such tools there could be few rules that should increase security:\n\n- Don't disable isolation. Isolation makes access harder for remote attacker,\n  even if he can access any port on the container host machine.\n- When opening ports to access the app from outside, set binding to the least\n  accessible but sufficient interface/address. For example If you expect only\n  to access the app locally over localhost, you could bind to localhost in\n  Podman using flag: `-p 127.0.0.1:8080:8080` to open the port 8080\n  only for localhost\n\n### Kubernetes\n\nKubernetes gives much greater possibilities for both ingress and egress.\nPrimary tools for that are Network Polcicies, which are implemented via plugins\n(therefore they might be not available on some k8s clusters).\n\nNetwork Policies allow for very accurate limitation of network traffic,\nthanks to their possibilities:\n\n- Using labels to select the pods to which the network policy\n  applies. This allows you to target specific groups of pods based on their labels.\n- Applying network policies across namespaces by selecting\n  namespaces based on their labels.\n- Defining rules based on specific protocols (TCP, UDP) and ports to allow or deny traffic.\n- Support for arbitrary CIDR-formatted network addresses ranges.\n\nExample network policy definition:\n\n```yaml\napiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n  name: example\nspec:\n  podSelector:\n    matchLabels:\n      app.kubernetes.io/name: app1\n  policyTypes:\n    - Ingress\n    - Egress\n  ingress:\n    - from:\n      - namespaceSelector:\n          matchLabels:\n            kubernetes.io/metadata.name: app\n      ports:\n      - protocol: TCP\n        port: 123\n      - protocol: TCP\n        port: 456\n    - from:\n      - ipBlock:\n          cidr: 10.43.0.0/16\n      - ipBlock:\n          cidr: fe80::8cb6:aff8:8dc9:f511/64\n      ports:\n      - protocol: TCP\n        port: 443\n  egress:\n    - to:\n      - namespaceSelector:\n          matchLabels:\n            kubernetes.io/metadata.name: kube-system\n      ports:\n      - protocol: UDP\n        port: 53\n    - to:\n      - namespaceSelector:\n          matchLabels:\n            kubernetes.io/metadata.name: db\n      ports:\n      - protocol: TCP\n        port: 5432\n```\n\n## 8. OCI Images\n\nContainers technically don't require images, the base filesystem can be\nprovided in different way, but OCI images become standard in the industry.\nImages are another important element of (in)security in contenerization.\nIt is crucial to understand basics of that format, as it can for example leak\nsecrets to the public, if used incorrectly.\n\n## 8.1 Building\n\nIt is obvious that one should not hardcode secrets into an image. Unfortunately\nless users is aware how not to do that. When building an image, any instruction\nthat can modify filesystem of the built image, will be saved separately as a\nlayer. By default each layer is kept in the image, even, when in the end all\ncontents of some of those layers was removed.\n\nExample of **insecure** Containerfile:\n\n```Dockerfile\nFROM registry.fedoraproject.org/fedora-minimal\n\n# Copy secret into the image (bad practice)\nCOPY secret.txt ./secret.txt\n\n# Use and delete secret (but it's still in a previous layer)\nRUN cat secret.txt \u0026\u0026 rm secret.txt\n```\n\nThere is a way to modify image-to-be filesystem in much more secure manner,\nwhich also brings other benefits. It is called multi-stage build and, as the\nname suggests, contains multiple stages, where only layers of the latest will\nbe saved in the resulting image.\n\nThe Containerfile can look like that:\n\n```dockerfile\n# Stage 1: Use secret during the build\nFROM registry.fedoraproject.org/fedora-minimal AS builder\n\nWORKDIR /app\n\n# Copy application files\nCOPY app/ /app/\n\n# Copy the secret into the build stage\nCOPY secret.txt /app/secret.txt\n\n# Use the secret securely (e.g., configure app)\nRUN cat /app/secret.txt \u0026\u0026 echo \"Configuring app with secret\" \u003e config.txt\n\n# Removing the secret in this example is needed, because in the next stage\n# the /app dir will be copied as a whole\nRUN rm /app/secret.txt\n\n# Stage 2: Final image without secrets\nFROM registry.fedoraproject.org/fedora-minimal\n\n# Nothing is saved from previous stage\nWORKDIR /app\n\n# Copy only the necessary files from the builder stage\nCOPY --from=builder /app/ /app/\n```\n\nThis approach also helps keeping the images minimal, without any other\nleftovers, which also can improve security.\n\n## 8.2 Scanning\n\nImages can be scanned for vulnerabilities. This is usefull for any type and\nsource if images, since vulnerabilities appear even in the most basic\ncomponents like language interpreters, libC libraries, etc. There are tools\nfor manual scanning like [trivy](https://github.com/aquasecurity/trivy), and\nsome registries like [Harbor](https://goharbor.io/) have builting optional\nautomatic vulnerability scanning for any stored image.\n\nThese tools can provide descriptive analysis of image contents, taking into\naccount versions of most software stored inside (if supported).\n\nExample fragment of output of trivy scanning a python image:\n\n![trivy](./trivy.jpg)\n\n## 9. Selinux\n\nSELinux (Security-Enhanced Linux) is a security module for Linux that enforces\nmandatory access control (MAC) policies to restrict the actions of users and\napplications based on predefined rules, enhancing system security. SELinux\nworks by labeling all files, processes, and resources on a system with security\ncontexts. Policies define rules about how these labels can interact. When an\naction is attempted, SELinux checks the labels against the policies and either\nallows or denies the action based on the rules, enforcing least-privilege access.\n\nThis document is too short to explain in detail how selinux works, but\nfor containers management most important concepts are MCS\n(Multi-Category Security) and MLS (Multi-Level Security), described in\nRedHat docs: [link](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html-single/using_selinux/index#multi-level-security-mls_using-multi-level-security-mls)\n\nSelinux additionally secures the contenerized program, not allowing to access\nresources from outside. Container engines like Podman randomize categories by\ndefault, so for example 2 different containers cannot access the same volume.\n\nProof of categories randomization by running subsequent containers and checking\ntheir selinux context:\n\n```bash\n❯ podman run --rm -it fedora-minimal cat /proc/self/attr/current\nsystem_u:system_r:container_t:s0:c340,c364\n~\n❯ podman run --rm -it fedora-minimal cat /proc/self/attr/current\nsystem_u:system_r:container_t:s0:c202,c993\n~\n❯ podman run --rm -it fedora-minimal cat /proc/self/attr/current\nsystem_u:system_r:container_t:s0:c259,c971\n```\n\nIf two or more containers have matching categories (sorted categories on the same\nposition match or are not set), then such containers can access the same\nshared volumes.\n\nFor example (podman uses :Z flag on volume to propagate selinux context on\nall files inside):\n\nFirst starting container with 2 categories:\n\n```bash\npodman run --rm -it -v ./test:/test:Z --security-opt label=level:s0:c222,c11 fedora-minimal\nbash-5.2# ls -Z /test/\nsystem_u:object_r:container_file_t:s0:c11,c222 test2\nsystem_u:object_r:container_file_t:s0:c11,c222 test2.txt\nsystem_u:object_r:container_file_t:s0:c11,c222 test3.txt\n```\n\nThen second container with a subset of categories in selinux level will change\nthe labels, but still both containers have full access to the volume:\n\n```bash\npodman run --rm -it -v ./test:/test:Z --security-opt label=level:s0:c11 fedora-minimal\nbash-5.2# ls -Z /test/\nsystem_u:object_r:container_file_t:s0:c11 test2 \nsystem_u:object_r:container_file_t:s0:c11 test2.txt\nsystem_u:object_r:container_file_t:s0:c11 test3.txt\n```\n\nChanging the level in second container to something like\n`label=level:s0:c11,c33` will prevent access for the first container.\n\nFor shared volumes container engines like Podman or Docker have flag `:z`,\nwhich in contrast to `:Z` does not apply any categories, just plain level `s0`:\n\n```bash\n❯ podman run --rm -it -v ./test:/test:z fedora-minimal ls -Z /test\nsystem_u:object_r:container_file_t:s0 test2\nsystem_u:object_r:container_file_t:s0 test2.txt\nsystem_u:object_r:container_file_t:s0 test3.txt\n```\n\nThis allows any container with any categories potentially access this volume.\nAnd this is place for improvement - if the files inside of a volume are\nmain protected resource, it would be safer to label it with categories.\nIf there are multiple containers that need access to the volume, they\njust need to have matching categories. This somewhat reduces isolation\nbetween those containers in terms of other filesystems and other resources\nprotected by selinux, but that usually will be not much of a problem,\nconsidering they use shared volume.\n\nIn kubernetes specifying labels happens for whole pod, which can have\nmultiple containers:\n\n```yaml\napiVersion: v1\nkind: Pod\nspec:\n  securityContext:\n    seLinuxOptions:\n      level: \"s0:c12,c45\"\n(....)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fszwendacz99%2Fsecuring-linux-containers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fszwendacz99%2Fsecuring-linux-containers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fszwendacz99%2Fsecuring-linux-containers/lists"}