question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

The docker image should not require that it needs to be run as root.

See original GitHub issue

Environment:

  • CTFd Version/Commit:

master and 2.0.0 branch

  • Operating System:

MacOS X, but using docker so doesn’t matter.

  • Web Browser and Version:

N/A

What happened?

If you run the docker image on a container platform that prohibits you running the image as the root user it will fail. Running images as root is also not regarded as best practice.

Such a platform where this can occur is Kubernetes. In the case of OpenShift, which is a distribution of Kubernetes, and which enforces a quite strict security policy, images will be by default run as an effectively random user ID (based on project it runs in). This will result in an error of:

Traceback (most recent call last):
  File "manage.py", line 8, in <module>
    app = create_app()
  File "/opt/CTFd/CTFd/__init__.py", line 103, in create_app
    url = create_database()
  File "/opt/CTFd/CTFd/utils/migrations/__init__.py", line 29, in create_database
    create_database_util(url)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy_utils/functions/database.py", line 565, in create_database
    open(database, 'w').close()
IOError: [Errno 13] Permission denied: '/opt/CTFd/CTFd/ctfd.db'

This occurs because the application running as the assigned user ID, cannot write to the directories for the database file. It also wouldn’t have been able to write gunicorn log files, and actually would have failed before this point, but above is from after when change had been made to have gunicorn log to stdout/stderr.

For a plain Kubernetes distribution, this would similarly be an issue where role based access control (RBAC) had been configured in a more secure way, so as to implement a multi tenant capable environment.

If you are a cluster admin for an OpenShift cluster, one can override the security policies to allow images to run as root, but a normal user cannot do this, and best security practice is not to allow images to run as root.

What did you expect to happen?

The image should be able to run as an arbitrary non root user ID.

Note that it isn’t enough that the image be set up to run as fixed non root user ID as that would still fail to run on such environments, even though running as fixed non root user ID is still better than running as root inside of the container.

How to reproduce your issue

Run:

$ docker run -u 11111 --rm -p 8000:8000 ctfd

Any associated stack traces or error logs

See above.

Solution

A number of changes need to be made to the Dockerfile to create a more secure container image that doesn’t require root be used, and which can run in secure container platforms such as OpenShift or Kubernetes with multi tenant RBAC configuration. PR will be supplied, but the changes required are:

  • Create a non root UNIX account which has a group ID of 0. Group ID 0 is root group, but using this doesn’t give any special privileges and is required as is explained below.

  • Fix up permissions of any directories that need to be written to by the application such that owned by the new user, and with group root, plus with files/directories being group writable. Need to do this in a way that doesn’t result in duplicate layers in image so chown -R and chmod -R isn’t necessarily enough.

  • Make /etc/passwd file writable. This is needed so can add a user account entry for the randomly assigned user ID when container is run.

  • Install linux-pam package and enable pam_wheel module so that only users in group wheel can use su. This is so that not possible to use su to become root after adding a password for root in the /etc/passwd file, given the later would be writable.

  • In docker-entrypoint.sh, add entry into /etc/passwd file for the user ID the container runs as, if not already in the passwd file. This is necessary as some Python packages will fail when looking up user account information and there is no entry in the passwd file. Although image runs as random user ID, files/directories can still be written where permissions fixed up as per above, as a user with no initial entry in passwd file will default to using group root, thus matching where files/directories were made group root and writable to group.

  • Mark Dockerfile to run with USER corresponding to the integer user ID of the account created above. Do not use the username, as a container platform cannot verify that the user name might map to user ID 0 in the passwd file.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
romansilcommented, Feb 8, 2019

Thank you for your answer. I will take a look on the link.

0reactions
ColdHeatcommented, Mar 20, 2019

In my fix for this I’m not taking all of @GrahamDumpleton’s suggestions. It isn’t clear what the benefit is and to me it adds more mental complexity.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Processes In Containers Should Not Run As Root - Medium
Most containerized processes are application services and therefore don't require root access. While Docker requires root to run, containers ...
Read more >
Run the Docker daemon as a non-root user (Rootless mode)
Rootless mode allows running the Docker daemon and containers as a non-root user to mitigate potential vulnerabilities in the daemon and the container...
Read more >
Running as root on Docker images that don't use root
There are good reasons why running in a container as root is not a good idea, and that's why many images published nowadays...
Read more >
Should I run things inside a docker container as non root for ...
Running the container as root brings a lot of risks. Although being root inside the container is not the same as root on...
Read more >
HOWTO stop running containers as root in Kubernetes
Running containers as root is a bad idea for security. This has been shown time and time again. Hackers find new ways of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found