DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Containerization and Helm Templatization Best Practices for Microservices in Kubernetes
  • Demystifying Kubernetes in 5 Minutes
  • Building Secure Containers: Reducing Vulnerabilities With Clean Base Images
  • Strengthening Your Kubernetes Cluster With Pod Security Admission

Trending

  • A Deep Dive Into Firmware Over the Air for IoT Devices
  • Top Book Picks for Site Reliability Engineers
  • Intro to RAG: Foundations of Retrieval Augmented Generation, Part 1
  • Revolutionizing Financial Monitoring: Building a Team Dashboard With OpenObserve
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Docker Without Root Privileges

Docker Without Root Privileges

By 
Vaibhav Raizada user avatar
Vaibhav Raizada
DZone Core CORE ·
Mar. 12, 20 · Tutorial
Likes (18)
Comment
Save
Tweet
Share
66.4K Views

Join the DZone community and get the full member experience.

Join For Free

Docker as Root

Docker runs its containers as root. But does your workload really needs root permissions? The answer is rarely. Still, your containers, by default, continue to run as a root-user. This could have serious security concerns. A process that runs inside the container as root is in fact a process running as root on the host itself. This provides an opportunity for a malicious attempt to gain unrestricted access to the host itself.

You can check it by yourself, just use the following command on any image that you commonly use:

Shell
 




xxxxxxxxxx
1


 
1
$ kubectl run -i --tty hello-world --image=hello-world --restart=Never -- sh
2
/ # ps aux
3
PID   USER     TIME  COMMAND
4
  1   root     0:10  sh




Clearly, as a best practice, we should avoid running containers as root. So, how do we fix this, let us see how we can run a container as non-root user.

Add a Non-Root User to Dockerfile

Create a user with only as many permissions as is required by the workload inside the container. You can create a user with RUN command in the Dockerfile of the container’s image itself.

Dockerfile
 




xxxxxxxxxx
1


 
1
RUN groupadd --gid 5000 newuser \
2
    && useradd --home-dir /home/newuser --create-home --uid 5000 \
3
        --gid 5000 --shell /bin/sh --skel /dev/null newuser




The above line of code creates a user, newuser, together with a home and shell for the user. Now, simply add the user in your Dockerfile, like the following example:

Dockerfile
 




xxxxxxxxxx
1


 
1
FROM ubuntu:18.04
2
COPY . /myapp
3
RUN make /myapp
4
...
5
USER newuser
6
CMD python /myapp/hello.py




From line 5 onward, every command is run as newuser and not as root. Simple, isn’t it?

But, we do not always make use of only our custom images; we also use many third-party images, and we won't be able to inject an unprivileged user into them like above.

These third-party Docker images will run as root user by default, unless we do something about them. If you use an image from a not-so popular source, then it may even be embedded with a malicious command, which could compromise the security of your cluster.

Kubernetes pod security context and pod security policies come to our rescue.

You may also like: Securing Your Docker Containers.

Use Pod Security Context

You may use a Pod Security Context to restrict the execution of a Pod to a particular non-root user. To specify these security settings for a Pod, add a securityContext field in Pod specification.

YAML
 




xxxxxxxxxx
1
21


 
1
apiVersion: v1
2
kind: Pod
3
metadata:
4
  name: my-pod
5
spec:
6
  securityContext:
7
    runAsUser: 5000
8
    runAsGroup: 5000
9
  volumes:
10
  - name: my-vol
11
    emptyDir: {}
12
  containers:
13
  - name: my-container
14
    image: hello-world
15
    command: ["sh", "-c", "sleep 10 m"]
16
    volumeMounts:
17
    - name: my-vol
18
      mountPath: /data/hello
19
    securityContext:
20
      allowPrivilegeEscalation: false



In the above specification, runAsUser specifies that any container inside the pod will run with userID 5000 only. This is the user that we have created specifically as an unprivileged user. The runAsGroup specifies the group id of all processes. If we do not mention this, then the group ID will be root (0).

Now, you can create this pod and check the processes running inside the container:

Shell
 




xxxxxxxxxx
1


 
1
$ kubectl apply -f my-pod.yaml
2
$ kubectl exec -it my-pod – sh
3
ps
4
 
          
5
PID   USER     TIME  COMMAND
6
  1   5000     0:00  sleep 10 m
7
  6   5000     0:00  sh




As you can see above, the PID 1 is being run as userID 5000 and not as root.

Use Kubernetes Pod Security Policy

Kubernetes Pod Security Policy defines the conditions that a pod must run with; otherwise, it will not be provisioned in the cluster. In other words, if these conditions are not met, Kubernetes will prevent the pod from running.

A sample PodSecurityPolicy is given below: 

YAML
 




xxxxxxxxxx
1
28


 
1
apiVersion: policy/v1beta1
2
kind: PodSecurityPolicy
3
metadata:
4
  name: my-psp
5
spec:
6
  privileged: false
7
  #Required to prevent escalations to root.
8
  allowPrivilegeEscalation: false
9
  allowedCapabilities:
10
  - '*'
11
  volumes:
12
  - 'nfs'
13
  hostNetwork: true
14
  hostPorts:
15
  - min: 8000
16
    max: 8000
17
  hostIPC: true
18
  hostPID: true
19
  runAsUser:
20
    #Require the container to run without root.
21
    rule: 'MustRunAsNonRoot'
22
  seLinux:
23
    rule: 'RunAsAny'
24
  supplementalGroups:
25
    rule: 'RunAsAny'
26
  fsGroup:
27
    rule: 'RunAsAny'




This security policy achieves the following:

  • Restrict a container from running in privileged mode.
  • Restrict a container that needs a root.
  • Restrict a container that access esvolumes other than NFS volume.
  • Only allow containers to access host port 100.

Activate policy:

Shell
 




xxxxxxxxxx
1


 
1
$ kubectl create -f my-psp.yaml



Check the policy:

Shell
 




xxxxxxxxxx
1


 
1
$ kubectl get psp
2
NAME    PRIV   RUNASUSER         FSGROUP   SELINUX   VOLUMES
3
My-psp  false  MustRunAsNonRoot  RunAsAny  RunAsAny  [nfs]
4
 
          


Now that the policy has been created, you can test it by trying to run a container with root privileges.

Shell
 




xxxxxxxxxx
1


 
1
$ kubectl run --image=my-root-container



The pod security policy will disallow it to run and give an error message:

Shell
 




xxxxxxxxxx
1


 
1
$ kubectl get pods
2
NAME         READY    STATUS     
3
my-root-pod  0/1      container has runAsNonRoot and image will run as root
4
 
          



Conclusion

In this post, I have highlighted the inherent risk in running a Docker container under the default settings of a root user. I have also proposed multiple ways to overcome this risk.

  • If you are running a custom image, then create a new unprivileged user and specify it in your Dockerfile.
  • If you are using third party images then you can set security context at pod or container level.
  • Yet another way is to create a pod security policy that will not allow any container to run with root privileges.


Further Reading

  • Docker Container Resource Management: CPU, RAM and IO, Part 1.
  • The Complete Kubernetes Collection [Tutorials and Tools].
Docker (software) Kubernetes pods security

Opinions expressed by DZone contributors are their own.

Related

  • Containerization and Helm Templatization Best Practices for Microservices in Kubernetes
  • Demystifying Kubernetes in 5 Minutes
  • Building Secure Containers: Reducing Vulnerabilities With Clean Base Images
  • Strengthening Your Kubernetes Cluster With Pod Security Admission

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!