From f67cfd0494d5d35d6b4ee39bb77c24a07fef0e6c Mon Sep 17 00:00:00 2001 From: Alexander Cherepanov Date: Thu, 8 Jun 2023 13:12:00 +0600 Subject: [PATCH] Run containers as a non-root user (#2053) # What this PR does Create a custom non-root user and use it to start an app. So uwsgi does not require to use `setUid` and `setGid` system calls. It handles errors while starting in Kubernetes with `runAsNonRoot: true` check. ## Which issue(s) this PR fixes closes https://github.com/grafana/oncall/issues/445 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --------- Co-authored-by: Joey Orlando Co-authored-by: Joey Orlando --- CHANGELOG.md | 10 ++++++++-- docker-compose-developer.yml | 7 +++++++ engine/Dockerfile | 24 ++++++++++++++++++------ engine/uwsgi.ini | 2 -- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 227b97a0..ed5dc29e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Run containers as a non-root user by @alexintech [#2053](https://github.com/grafana/oncall/pull/2053) + ## v1.2.41 (2023-06-08) ### Added -- Twilio Provider improvements by @Konstantinov-Innokentii, @mderynck and @joeyorlando -[#2074](https://github.com/grafana/oncall/pull/2074) [#2034](https://github.com/grafana/oncall/pull/2034) +- Twilio Provider improvements by @Konstantinov-Innokentii, @mderynck and @joeyorlando + [#2074](https://github.com/grafana/oncall/pull/2074) [#2034](https://github.com/grafana/oncall/pull/2034) ## v1.2.40 (2023-06-07) diff --git a/docker-compose-developer.yml b/docker-compose-developer.yml index d840c3a3..cf2be034 100644 --- a/docker-compose-developer.yml +++ b/docker-compose-developer.yml @@ -3,6 +3,9 @@ version: "3.9" x-labels: &oncall-labels - "com.grafana.oncall.env=dev" +x-user: &oncall-user + "appuser" + x-oncall-build: &oncall-build-args context: ./engine target: ${ONCALL_IMAGE_TARGET:-dev} @@ -65,6 +68,7 @@ services: labels: *oncall-labels build: *oncall-build-args restart: always + user: *oncall-user command: sh -c "uwsgi --disable-logging --py-autoreload 3 --ini uwsgi.ini" env_file: *oncall-env-files environment: *oncall-env-vars @@ -86,6 +90,7 @@ services: container_name: oncall_engine_commands labels: *oncall-labels build: *oncall-build-args + user: *oncall-user env_file: *oncall-env-files environment: *oncall-env-vars volumes: *oncall-volumes @@ -99,6 +104,7 @@ services: labels: *oncall-labels build: *oncall-build-args restart: always + user: *oncall-user command: "python manage.py start_celery" env_file: *oncall-env-files environment: *oncall-env-vars @@ -129,6 +135,7 @@ services: container_name: oncall_db_migration labels: *oncall-labels build: *oncall-build-args + user: *oncall-user command: "python manage.py migrate --noinput" env_file: *oncall-env-files environment: *oncall-env-vars diff --git a/engine/Dockerfile b/engine/Dockerfile index 0b8c98ad..1568b005 100644 --- a/engine/Dockerfile +++ b/engine/Dockerfile @@ -1,4 +1,10 @@ FROM python:3.11.3-slim-buster AS base + +# Create a group and user to run an app +ENV APP_USER=appuser +RUN groupadd --system --gid 2000 ${APP_USER} && \ + useradd --no-log-init --system --uid 1000 --gid ${APP_USER} ${APP_USER} + RUN apt-get update && apt-get install -y \ python3-dev \ gcc \ @@ -24,14 +30,22 @@ COPY ./ ./ # Collect static files RUN DJANGO_SETTINGS_MODULE=settings.prod_without_db DATABASE_TYPE=sqlite3 DATABASE_NAME=/var/lib/oncall/oncall.db SECRET_KEY="ThEmUsTSecretKEYforBUILDstage123" SILK_PROFILER_ENABLED="True" python manage.py collectstatic --no-input +# Change permissions for the app folder, as previous commands run as root +RUN chown -R ${APP_USER}:${APP_USER} /etc/app + # Create SQLite database and set permissions RUN mkdir -p /var/lib/oncall RUN DATABASE_TYPE=sqlite3 DATABASE_NAME=/var/lib/oncall/oncall.db python manage.py create_sqlite_db -RUN chown -R 1000:2000 /var/lib/oncall +RUN chown -R ${APP_USER}:${APP_USER} /var/lib/oncall # This is required for silk profilers to sync between uwsgi workers RUN mkdir -p /tmp/silk_profiles; -RUN chown -R 1000:2000 /tmp/silk_profiles +RUN chown -R ${APP_USER}:${APP_USER} /tmp/silk_profiles + +# This is required for prometheus_client to sync between uwsgi workers +RUN mkdir -p /tmp/prometheus_django_metrics; +RUN chown -R ${APP_USER}:${APP_USER} /tmp/prometheus_django_metrics +ENV prometheus_multiproc_dir "/tmp/prometheus_django_metrics" FROM base AS dev RUN apt-get install -y sqlite3 default-mysql-client postgresql-client @@ -41,9 +55,7 @@ RUN pip install -r requirements-enterprise-docker.txt FROM base AS prod -# This is required for prometheus_client to sync between uwsgi workers -RUN mkdir -p /tmp/prometheus_django_metrics; -RUN chown -R 1000:2000 /tmp/prometheus_django_metrics -ENV prometheus_multiproc_dir "/tmp/prometheus_django_metrics" +# Change to a non-root user (number is required by Kubernetes runAsNonRoot check) +USER 1000 CMD [ "uwsgi", "--ini", "uwsgi.ini" ] diff --git a/engine/uwsgi.ini b/engine/uwsgi.ini index 2425c79a..ab1fc170 100644 --- a/engine/uwsgi.ini +++ b/engine/uwsgi.ini @@ -6,8 +6,6 @@ master=True pidfile=/tmp/project-master.pid http=0.0.0.0:8080 processes=5 -uid=1000 -gid=2000 harakiri=620 max-requests=5000 vacuum=True