The docker image should not require that it needs to be run as root.See original GitHub issue
- CTFd Version/Commit:
master and 2.0.0 branch
- Operating System:
MacOS X, but using docker so doesn’t matter.
- Web Browser and Version:
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
$ docker run -u 11111 --rm -p 8000:8000 ctfd
Any associated stack traces or error logs
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
chmod -Risn’t necessarily enough.
/etc/passwdfile writable. This is needed so can add a user account entry for the randomly assigned user ID when container is run.
linux-pampackage and enable
pam_wheelmodule so that only users in group
su. This is so that not possible to use
suto become root after adding a password for root in the
/etc/passwdfile, given the later would be writable.
docker-entrypoint.sh, add entry into
/etc/passwdfile for the user ID the container runs as, if not already in the
passwdfile. This is necessary as some Python packages will fail when looking up user account information and there is no entry in the
passwdfile. 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
passwdfile will default to using group root, thus matching where files/directories were made group root and writable to group.
Dockerfileto run with
USERcorresponding 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.
- Created 5 years ago
- Comments:6 (1 by maintainers)
Top GitHub Comments
Thank you for your answer. I will take a look on the link.