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

Running nats as non-root user #43

Closed
wants to merge 5 commits into from
Closed

Running nats as non-root user #43

wants to merge 5 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Dec 29, 2020

Hi,
please note that it aint secure to run services as root user - also if they are in a docker container.

I fixed the build file that nats is running as user "nats" instead of root. In my personal environment it worked and the container built + started successful.

So i want to please you to check my changes and merge my PR.

Thanks! :)

@kozlovic
Copy link
Member

@tunnelpr0 Thank you for the contribution. I would hope that there are no condition where running as root was actually required. This would possibly break lot of users.

As a first step, would you mind rebasing from the main branch? I have just merged PR #44 so that GitHub Actions (GA) will now be running on user PRs? After the rebase, git push --force so that this PR is updated and hopefully runs GA. Thanks!

@ghost
Copy link
Author

ghost commented Dec 31, 2020

Sorry if this sounds quite dumb...

I made the changes in the browser, because it was the fastest way. So i am having my changes in a branch called patch-1 in a personal fork of your repository.

Now i am not shure, how to get your new commits from your repo in the master branch of my personal repo - if i do a simple git pull, it says that everything is up to date. But git log shows, that #44 is missing.
Without your new commits, a rebase from my side will be quite useless...

May you can give me a hint? Thanks! :D

@kozlovic
Copy link
Member

@tunnelpr0 You need first to update the main branch on your fork. To do that, I would do this:

git remote -v

Depending on the result of the command above, you may need to update the following commands:

git checkout master
git fetch origin
git merge origin/master

Once you see that your local copy's "git log" shows that you now have the latest changes, you can rebase your branch:

git checkout patch-1
git rebase master
git push --force

Let me know if that works.

tunnelpr0 added 5 commits December 31, 2020 15:34
Changing the user which nats uses
Fixed permissions for running as non-root user
Running nats as non-root user
Fixed shell
Scratch only works as root, removed nats user ._.
@ghost
Copy link
Author

ghost commented Dec 31, 2020

Well, this looks like it actually worked. Thank you for the hints! :D

@kozlovic
Copy link
Member

@tunnelpr0 Thanks, that worked indeed and the PR has been running on GA. I am going to ask help from some folks in our group to ask their input regarding the "safety" of this change. In other words, do they know if this is going to cause trouble or think that it is ok.
But due to the holidays, please allow some time before we get back to you. Thanks and Happy New Year!

@kozlovic
Copy link
Member

@wallyqs and @variadico After the holidays break, if you don't mind have a look at this PR and do you know if the change (not running as root user) could cause any problem? I am not sure if that could have an impact (maybe with TLS or access to certs)? Thanks!

@ghost
Copy link
Author

ghost commented Jan 1, 2021

Hi,
just a few additional thoughts from my side...

I am using nats in the context of the Nextcloud Spreed (Talk) High-Performance Backend and do not need TLS, because its running in the backend. (There is a reverse proxy who is doing TLS termination + a middleware who talks to nats)

But if there is anybody who needs TLS, there could be definitively problems, since certificates as well as those private keys are stored with root:root and 640 permissions (or something similiar), because mostly those services who request the certificates from e.g. letsencrypt, are running as root. I personally use caddy and i know the problematic.

Normally i would say: this is the problem of the people who are using the software, but if nobody knows that they have to change a few things in their infrastructure, it could crash a few installations.

One way for easier implementation could be, that we give the nats user a specific user id. Just as a suggestion.

In regard to the topic docker security - i normally recommend this talk from the cccs, but poorly its only on german available and dont have any english subtitles. But this guy explains really good, why running as root is also not a good idea in a docker container.

@kozlovic
Copy link
Member

kozlovic commented Jan 4, 2021

But if there is anybody who needs TLS, there could be definitively problems, since certificates as well as those private keys are stored with root:root and 640 permissions (or something similiar), because mostly those services who request the certificates from e.g. letsencrypt, are running as root. I personally use caddy and i know the problematic.

Well, this is what I was afraid of. So not sure we can merge this PR as-is. Maybe the alternative is to add an additional image with non-root user?

@ghost
Copy link
Author

ghost commented Jan 5, 2021

Well, this is what I was afraid of. So not sure we can merge this PR as-is. Maybe the alternative is to add an additional image with non-root user?

Not a bad idea... would be the safest possibility for the begin.

If it works, there would be the possibilty to say, that the non-root image is the new "default" image and mark the root image as deprecated. But thats just a idea from my side, i would leave this decision definitively to you.

@variadico
Copy link
Contributor

Here's what I found using nats-operator and cert-manager.

/etc/nats-server-tls-certs/..2021_01_06_02_26_58.288640383 $ ls -al
total 12
drwxr-xr-x    2 root     root           100 Jan  6 02:26 .
drwxrwxrwt    3 root     root           140 Jan  6 02:26 ..
-rw-r--r--    1 root     root          1155 Jan  6 02:26 ca.crt
-rw-r--r--    1 root     root          1253 Jan  6 02:26 tls.crt
-rw-r--r--    1 root     root          1675 Jan  6 02:26 tls.key

The documentation says this:

If you don't specify any permissions, 0644 is used by default.

The file permissions are configurable like this.

secret:
  secretName: mysecret
  items:
  - key: username
  path: my-group/my-username
  mode: 0777

I suppose if someone set the permissions to 400, then this change will break them. Although not sure if this applies if they're using our nats-operator.

Also, not sure about other environments. Should keep digging.

@JnMik
Copy link

JnMik commented Apr 30, 2021

Any follow up on this ? That would be a nice security improvement

@nitinsh99
Copy link

@kozlovic any update on this? We are not able to use nats because of this issue. Running containers as root in production is not a safe practise is all and I believe this MR is in right direction.

@kozlovic
Copy link
Member

kozlovic commented Nov 4, 2021

Sorry about the delay. I just did a release of v2.6.4 right now, without those changes. I may start looking at adding alpine3.14_no_root image or something. I will need to experiment.

kozlovic added a commit that referenced this pull request Nov 9, 2021
Based on @tunnelpr0 PR #43

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
@variadico
Copy link
Contributor

While we're working out all the details, would this command be a temporary workaround? (Note --user)

docker run --user 1000:1000 -p 4222:4222 nats:2.6.5-alpine -js

Exec-ing into the container shows nats-server running as non-root user 1000. The JS storage directory is owned by user 1000.

$ docker exec -it 75c8bc294bba sh
/ $ ps aux
PID   USER     TIME  COMMAND
    1 1000      0:00 nats-server -js
   40 1000      0:00 sh
   46 1000      0:00 ps aux
/ $ ls -al /tmp/nats
total 12
drwxr-x---    3 1000     1000          4096 Dec  1 00:10 .
drwxrwxrwt    1 root     root          4096 Dec  1 00:10 ..
drwxr-x---    3 1000     1000          4096 Dec  1 00:10 jetstream

Without the --user 1000:1000 flag, then root does run the nats-server.

$ docker exec -it eac57f6a159c sh
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 nats-server -js
   14 root      0:00 sh
   20 root      0:00 ps
/ # ls -al /tmp/nats/
total 12
drwxr-x---    3 root     root          4096 Dec  1 00:14 .
drwxrwxrwt    1 root     root          4096 Dec  1 00:14 ..
drwxr-x---    3 root     root          4096 Dec  1 00:14 jetstream

@bruth
Copy link
Member

bruth commented Jun 8, 2023

Closing as the last comment by @variadico appears to satisfy the requirement of "running NATS not as root" without needing to alter the Dockerfile itself.

@bruth bruth closed this Jun 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants