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

non-root users for Dockerfiles #300

Merged
merged 9 commits into from
Jan 18, 2024
Merged

Conversation

hkiang01
Copy link
Contributor


category: Maintenance
authors: hkiang01

Non-root users for Dockerfiles

As a regular Node application, the default user doesn't need to be root. For why this is important, see Why non-root containers are important for security

@hkiang01
Copy link
Contributor Author

I tested this locally by altering docker-compose.yml to point to each edited Dockerfile. I was able to successfully build and start each corresponding built container to serve localhost:5006

@hkiang01
Copy link
Contributor Author

hkiang01 commented Jan 16, 2024

Syncing works as of the latest commit

Expand details below for some details related to confirming functionality Edit: This was not be due to this PR, but a mis-configured security context in my kubernetes cluster

hmmm got an error while syncing

Rejection: SqliteError: attempt to write a readonly database
    at WrappedDatabase.mutate (file:///app/src/db.js:39:21)
    at file:///app/src/sync-simple.js:31:23
    at sqliteTransaction (/app/node_modules/better-sqlite3/lib/methods/transaction.js:65:24)
    at WrappedDatabase.transaction (file:///app/src/db.js:47:35)
    at addMessages (file:///app/src/sync-simple.js:26:6)
    at Module.sync (file:///app/src/sync-simple.js:81:14)
    at file:///app/src/app-sync.js:111:42
    at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/app/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/app/node_modules/express/lib/router/route.js:114:3) {
  code: 'SQLITE_READONLY'

@hkiang01
Copy link
Contributor Author

I recommend bumping major version as the non-root user wouldn't have access to read/write files owned by root. This can be fixed by running chown -R 1001:1001 /data in the container

@twk3 twk3 self-requested a review January 16, 2024 22:44
Copy link
Contributor

@twk3 twk3 left a comment

Choose a reason for hiding this comment

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

@hkiang01 the app code should remain root, so the runtime user can't manipulate the code. Runtime users should just be able to influence the config and data dir.

@twk3
Copy link
Contributor

twk3 commented Jan 16, 2024

I recommend bumping major version as the non-root user wouldn't have access to read/write files owned by root. This can be fixed by running chown -R 1001:1001 /data in the container

This is a good point, but I think that's a bit of a blocker for us for now. We also have to consider users already running on pikapods and fly.io

@hkiang01 I think as an iteration, adding the user, but not setting it as the run user for entry. Chowning the data directory contents on entry to the new user, and then running the app as the new user will set us up to switchover in a major release.

@hkiang01 hkiang01 requested a review from twk3 January 16, 2024 23:35
@hkiang01
Copy link
Contributor Author

Requested changes made. I expect a retry of the build jobs will succeed. Please retry the jobs and re-review

@hkiang01
Copy link
Contributor Author

failing builds are due to #287 which is out of scope of this PR

@hkiang01
Copy link
Contributor Author

confirmed non-breaking change with manual steps:

  1. spin up container with default user (root)
  2. navigate to localhost:5006, perform some actions, sync
  3. re-create container with user appuser
  4. repeat step 2

Copy link
Contributor

@twk3 twk3 left a comment

Choose a reason for hiding this comment

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

@hkiang01 this looks like a good first step, and I think we can move forward with this change after a few minor tweaks for users who want to set the user to 1001 when running from their very first run. (Like in your helm chart). But the swap from root to app user does not currently work without manual chowning of the data. (database files will be readonly by the appuser)

A followup (doesn't have to block this PR). Would be to move our current RUN command to a startup script, then earlier in that script check if the running uid is 0, if so, chown all data (at runtime this time) to our non-root user, and then exec our tini command as that user. Else we just exec the tini command like normal.

Bitnami has some examples of using chroot to change the user at runtime if running as root by just chrooting to / again but with userspace. https://github.com/bitnami/containers/blob/8a67664e7a937c6aa603a9b0477561b9af7abb0e/bitnami/postgresql/16/debian-11/prebuildfs/opt/bitnami/scripts/libos.sh#L653

This would allow us to get everyone running as non-root, and in a later major change we could just drop the extra work for the USER line in the dockerfile.

Dockerfile Outdated Show resolved Hide resolved
upcoming-release-notes/300.md Outdated Show resolved Hide resolved
@hkiang01 hkiang01 requested a review from twk3 January 18, 2024 00:06
Copy link
Contributor

@twk3 twk3 left a comment

Choose a reason for hiding this comment

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

Thanks @hkiang01

This is a good first step towards moving the container to always run non-root.

@trafico-bot trafico-bot bot added ✅ Approved Pull Request has been approved and can be merged and removed 🔍 Ready for Review labels Jan 18, 2024
@twk3 twk3 merged commit d8c7a0a into actualbudget:master Jan 18, 2024
6 checks passed
@trafico-bot trafico-bot bot added ✨ Merged Pull Request has been merged successfully and removed ✅ Approved Pull Request has been approved and can be merged labels Jan 18, 2024
MMichotte pushed a commit to MMichotte/actual-server that referenced this pull request Sep 9, 2024
* Optional non-root users for Dockerfiles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Merged Pull Request has been merged successfully
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants