Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Docker configuration #497

Merged
merged 11 commits into from
Jul 28, 2021
Merged

Conversation

Hritik14
Copy link
Collaborator

@Hritik14 Hritik14 commented Jul 13, 2021

This PR creates an organized Docker environment with proper documentation inspired from scancodeio.
A Makefile is introduced which eases the installation greatly. Also, now SECRET_KEY is no longer optional. Commit messages contain further descriptive text.

With Makefile at hand, documentation of other parts also needs to be improved but that is out of realm of this PR.

@sbs2001
Copy link
Collaborator

sbs2001 commented Jul 17, 2021

While you're at it , maybe we could fix these misconfigs found via https://github.com/docker/docker-bench-security . Pasting he relevant misconfigs here.

[INFO] 4 - Container Images and Build File
[WARN] 4.1 - Ensure that a user for the container has been created (Automated)
[WARN]      * Running as root: vulnerablecode
[WARN]      * Running as root: vulnerablecode_db_1
[NOTE] 4.2 - Ensure that containers use only trusted base images (Manual)
[NOTE] 4.3 - Ensure that unnecessary packages are not installed in the container (Manual)
[NOTE] 4.4 - Ensure images are scanned and rebuilt to include security patches (Manual)
[WARN] 4.5 - Ensure Content trust for Docker is Enabled (Automated)
[WARN] 4.6 - Ensure that HEALTHCHECK instructions have been added to container images (Automated)
[WARN]      * No Healthcheck found: [vulnerablecode_web:latest]
[WARN]      * No Healthcheck found: a12ce5bf6f8e
[WARN]      * No Healthcheck found: 556a5c9bb265
[WARN]      * No Healthcheck found: 39bede3c7e7c
[WARN]      * No Healthcheck found: [postgres:latest]
[WARN]      * No Healthcheck found: 28a4c88cdbbf
[INFO] 4.7 - Ensure update instructions are not used alone in the Dockerfile (Manual)
[INFO]      * Update instruction found: [vulnerablecode_web:latest]
[INFO]      * Update instruction found: [postgres:latest]
[NOTE] 4.8 - Ensure setuid and setgid permissions are removed (Manual)
[INFO] 4.9 - Ensure that COPY is used instead of ADD in Dockerfiles (Manual)
[INFO]      * ADD in image history: [vulnerablecode_web:latest]
[NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles (Manual)
[NOTE] 4.11 - Ensure only verified packages are are installed (Manual)

[INFO] 5 - Container Runtime
[PASS] 5.1 - Ensure that, if applicable, an AppArmor Profile is enabled (Automated)
[WARN] 5.2 - Ensure that, if applicable, SELinux security options are set (Automated)
[WARN]      * No SecurityOptions Found: vulnerablecode
[WARN]      * No SecurityOptions Found: vulnerablecode_db_1
[PASS] 5.3 - Ensure that Linux kernel capabilities are restricted within containers (Automated)
[PASS] 5.4 - Ensure that privileged containers are not used (Automated)
[PASS] 5.5 - Ensure sensitive host system directories are not mounted on containers (Automated)
[PASS] 5.6 - Ensure sshd is not run within containers (Automated)
[PASS] 5.7 - Ensure privileged ports are not mapped within containers (Automated)
[NOTE] 5.8 - Ensure that only needed ports are open on the container (Manual)
[PASS] 5.9 - Ensure that the host's network namespace is not shared (Automated)
[WARN] 5.10 - Ensure that the memory usage for containers is limited (Automated)
[WARN]       * Container running without memory restrictions: vulnerablecode
[WARN]       * Container running without memory restrictions: vulnerablecode_db_1
[WARN] 5.11 - Ensure that CPU priority is set appropriately on containers (Automated)
[WARN]       * Container running without CPU restrictions: vulnerablecode
[WARN]       * Container running without CPU restrictions: vulnerablecode_db_1
[WARN] 5.12 - Ensure that the container's root filesystem is mounted as read only (Automated)
[WARN]       * Container running with root FS mounted R/W: vulnerablecode
[WARN]       * Container running with root FS mounted R/W: vulnerablecode_db_1
[WARN] 5.13 - Ensure that incoming container traffic is bound to a specific host interface (Automated)
[WARN]       * Port being bound to wildcard IP: 0.0.0.0 in vulnerablecode
[WARN] 5.14 - Ensure that the 'on-failure' container restart policy is set to '5' (Automated)
[WARN]       * MaximumRetryCount is not set to 5: vulnerablecode
[WARN]       * MaximumRetryCount is not set to 5: vulnerablecode_db_1
[PASS] 5.15 - Ensure that the host's process namespace is not shared (Automated)
[PASS] 5.16 - Ensure that the host's IPC namespace is not shared (Automated)
[PASS] 5.17 - Ensure that host devices are not directly exposed to containers (Manual)
[INFO] 5.18 - Ensure that the default ulimit is overwritten at runtime if needed (Manual)
[INFO]       * Container no default ulimit override: vulnerablecode
[INFO]       * Container no default ulimit override: vulnerablecode_db_1
[PASS] 5.19 - Ensure mount propagation mode is not set to shared (Automated)
[PASS] 5.20 - Ensure that the host's UTS namespace is not shared (Automated)
[PASS] 5.21 - Ensurethe default seccomp profile is not Disabled (Automated)
[NOTE] 5.22 - Ensure that docker exec commands are not used with the privileged option (Automated)
[NOTE] 5.23 - Ensure that docker exec commands are not used with the user=root option (Manual)
[PASS] 5.24 - Ensure that cgroup usage is confirmed (Automated)
[WARN] 5.25 - Ensure that the container is restricted from acquiring additional privileges (Automated)
[WARN]       * Privileges not restricted: vulnerablecode
[WARN]       * Privileges not restricted: vulnerablecode_db_1
[WARN] 5.26 - Ensure that container health is checked at runtime (Automated)
[WARN]       * Health check not set: vulnerablecode
[WARN]       * Health check not set: vulnerablecode_db_1
[INFO] 5.27 - Ensure that Docker commands always make use of the latest version of their image (Manual)
[WARN] 5.28 - Ensure that the PIDs cgroup limit is used (Automated)
[WARN]       * PIDs limit not set: vulnerablecode
[WARN]       * PIDs limit not set: vulnerablecode_db_1

@Hritik14
Copy link
Collaborator Author

@sbs2001 These results appear to be from the old docker configs. Can you confirm if you used the configs from this branch or from the main ?

@Hritik14 Hritik14 force-pushed the docker_bugfix branch 9 times, most recently from 8f1fa6a to 617b758 Compare July 18, 2021 02:48
@Hritik14 Hritik14 marked this pull request as ready for review July 18, 2021 02:50
@Hritik14
Copy link
Collaborator Author

Btw this has a side effect that it fixes #462

@Hritik14 Hritik14 linked an issue Jul 19, 2021 that may be closed by this pull request
@Hritik14
Copy link
Collaborator Author

@rolfschr can you please update the nix tests in this one

After 312160c docker-compose doesn't load static files as the server
runs in development mode without DEBUG enabled.
Also, this commit makes sure it is loud and heard that running via
docker is not safe.

Signed-off-by: Hritik Vijay <[email protected]>
DJANGO_DEV is obsolete and now nowhere exists in the entire codebase

Signed-off-by: Hritik Vijay <[email protected]>
The docker setup present earlier used django development server to host
vulnerablecode, this is neither recommended nor safe. Also the server
did not drop privileges.
Docker environment vars are now easily configured via docker.env, also
the nginx template present in etc/nginx could be used in a non docker
setup with slight modifications.

Signed-off-by: Hritik Vijay <[email protected]>
@Hritik14 Hritik14 linked an issue Jul 26, 2021 that may be closed by this pull request
@pombredanne pombredanne changed the title Docker bugfix Improve Docker configuration Jul 27, 2021
.travis.yml Outdated Show resolved Hide resolved
Copy link
Member

@pombredanne pombredanne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM... I have a few questions and nits though

Dockerfile Outdated Show resolved Hide resolved
Dockerfile Show resolved Hide resolved
Dockerfile Outdated Show resolved Hide resolved
Dockerfile Outdated Show resolved Hide resolved
Inspired by ScancodeIO. This Makefile makes the installation easy as
a cake.
The virtualenv zipapp used in this commit is obtained from
https://bootstrap.pypa.io/virtualenv/3.8/virtualenv.pyz
Note: sqlite support in this makefile is not implemented yet. It will be
done in next commits in this PR.

Signed-off-by: Hritik Vijay <[email protected]>
This will be essential after later commits as the existence of
SECRET_KEY in .env or environment is going to be non-optional.

Signed-off-by: Hritik Vijay <[email protected]>
This is not essential but promotes uniformity.
Also, `collectstatic` is removed from this test as this is not really
necessary.

Signed-off-by: Hritik Vijay <[email protected]>
Inspired by scancodeio, we now have a consistent ALLOWED_HOSTS
environment variable support. SECRET_KEY no longer defaults to insecure
values and is required to be generated. Static files are now served in
/var/vulnerablecode/static which is consistent to scancodeio.

Signed-off-by: Hritik Vijay <[email protected]>
File hierarchy inside docker container now looks similar to scancodeio.
postgres data is now a docker volume, so it will persist even after
recreation.  .dockerignores makes sure that we don't overpopulate docker
images, improving build times.  A common environment variable for
containers is kept in docker.env
The python image we are using now explicitly states python:3.8

NOTE: We should have a postgres health check script which uses python
manage.py check --database default which comes with max_retries and
backoffs for `vulnerablecode` container.  Currently, docker's `restart:`
option is used but it has a caveat that it'll restart on non-db errors
as well.

Signed-off-by: Hritik Vijay <[email protected]>
This calls for a lot of changes in other parts of documentation as well.
This will be done in later PRs. This commit marks the end of this PR.

Signed-off-by: Hritik Vijay <[email protected]>
@Hritik14 Hritik14 force-pushed the docker_bugfix branch 2 times, most recently from 1f097f4 to d696c72 Compare July 28, 2021 19:31
This commit gets rid of using any type of cache (introduced in 135c95f)
This is to ensure having no surprises in future. This was discussed in
https://github.com/nexB/vulnerablecode/wiki/WeeklyMeetings#meeting-on-tuesday-2021-07-27-at-1300-utc

Signed-off-by: Hritik Vijay <[email protected]>
These are redundant after PR# 295.

Signed-off-by: Hritik Vijay <[email protected]>
@Hritik14
Copy link
Collaborator Author

@pombredanne nits resolved. Merging this now

@Hritik14 Hritik14 merged commit 369897f into aboutcode-org:main Jul 28, 2021
@Hritik14
Copy link
Collaborator Author

Hritik14 commented Aug 2, 2021

@rolfschr ping...

WORKDIR /vulnerablecode
ADD . /vulnerablecode/
RUN pip install -r requirements.txt && \
DJANGO_DEV=1 python manage.py collectstatic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you remove collectstatic in the dockerfile?

For me it makes more sense to have the collectstatic in the base docker image rather to do it at every startup in the docker compose.

We have vulnerable code setup in kubernetes and this change did break it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tardyp sorry for the break.
@Hritik14 @tdruez do you have any insights?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No specific reason from my side, except that the same structure is being used in our other project.
https://github.com/nexB/scancode.io/blob/main/docker-compose.yml

If we revert, we should revert both.

Copy link
Contributor

@tardyp tardyp Aug 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see in docker-compose that you actully do the collectstatic in a shared volume so that the static is served by nginx.
I think this works well for this docker-compose design.

It won't work well in a kubernetes deployment as in kubernetes there is usually several instance of the webapp container which will compete doing the migration and doing the static collect.
In my kubernetes design I didn't bother serving the static files using a dedicated static server.

I think it make sense to ship the docker container with static files inside it, even if in the docker-compose you regenerate it. This will anyway allow the two strategies, with or without static file server.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, looks like django is not recommending serving static file by the app. I though this was only a performance best practice (which I don't bother with my 4 users), but they say it is also insecure.
https://docs.djangoproject.com/en/3.2/ref/contrib/staticfiles/#django.contrib.staticfiles.views.serve

So I think I will have to deploy an nginx as well..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Staticfiles are only supposed to be served by a proper webserver or cdn. You could serve them via the development server using the --insecure flag, and it is as it sounds like - insecure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see in docker-compose that you actully do the collectstatic in a shared volume so that the static is served by nginx.

I don't think we would have any trouble having the shared volume even if we invoke collectstatic inside the docker image. The best rationale I could think of is, because staticfiles is meant for production, it should be invoked in production.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants