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

nginx: do not run anything as root #56255

Merged
merged 1 commit into from Dec 20, 2019
Merged

nginx: do not run anything as root #56255

merged 1 commit into from Dec 20, 2019

Conversation

Izorkin
Copy link
Contributor

@Izorkin Izorkin commented Feb 23, 2019

Motivation for this change

Reopened and updated this PR #51551
Change location pidFile from /var/spool/nginx/log/nginx.pid to /run/nginx/nginx.pid

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Assured whether relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@Izorkin Izorkin force-pushed the nginx-temp1 branch 5 times, most recently from 8b03dda to bfe61e1 Compare February 25, 2019 10:36
@Izorkin
Copy link
Contributor Author

Izorkin commented Feb 25, 2019

сс @infinisil cc @Mic92

@Izorkin Izorkin force-pushed the nginx-temp1 branch 2 times, most recently from cc4163e to 2e4ff94 Compare March 4, 2019 17:09
@Izorkin Izorkin force-pushed the nginx-temp1 branch 2 times, most recently from 6a2910a to 03f6607 Compare March 4, 2019 18:07
@Izorkin Izorkin force-pushed the nginx-temp1 branch 2 times, most recently from 532a80b to 7d910ea Compare March 9, 2019 18:24
Copy link
Contributor

@asymmetric asymmetric left a comment

Choose a reason for hiding this comment

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

I think we shouldn't add the RLIMIT options.

nixos/modules/services/web-servers/nginx/default.nix Outdated Show resolved Hide resolved
nixos/modules/services/web-servers/nginx/default.nix Outdated Show resolved Hide resolved
@Izorkin Izorkin requested review from dasJ and Mic92 December 14, 2019 19:26
@Izorkin
Copy link
Contributor Author

Izorkin commented Dec 15, 2019

Returned AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" "CAP_SYS_RESOURCE" ];

@flokli
Copy link
Contributor

flokli commented Dec 17, 2019

@Izorkin: Does nginx still have permission to access letsencrypt certificates if we use services.nginx.virtualHosts.<name>.enableACME?

I didn't check yet, just asking.

Also, it seems the ACME test currently is broken on master so I can't easily check it in the test

cc @NinjaTrappeur @arianvp

@Izorkin
Copy link
Contributor Author

Izorkin commented Dec 17, 2019

@flokli yes, correct work:
ls -lah /var/lib/acme

итого 16K
drwxr-xr-x  4 root  root  4,0K дек 17 20:07 .
drwxr-xr-x 26 root  root  4,0K дек 17 20:10 ..
drwxr-xr-x  3 root  root  4,0K дек 17 20:07 acme-challenge
drwxr-xr-x  2 nginx nginx 4,0K дек 17 20:07 test1.example-stie

ls -lah /var/lib/acme/test1.example-stie

итого 32K
drwxr-xr-x 2 nginx nginx 4,0K дек 17 20:07 .
drwxr-xr-x 4 root  root  4,0K дек 17 20:07 ..
-rw-r--r-- 1 nginx nginx 3,1K дек 17 20:07 account_key.json
-rw-r--r-- 1 nginx nginx  912 дек 17 20:07 account_reg.json
-rwx------ 1 nginx nginx 3,9K дек 17 20:07 fullchain.pem
-rwx------ 1 nginx nginx 7,1K дек 17 20:07 full.pem
-rwx------ 1 nginx nginx 3,2K дек 17 20:07 key.pem

@flokli flokli merged commit 0a41dae into NixOS:master Dec 20, 2019
@flokli
Copy link
Contributor

flokli commented Dec 20, 2019

Acme tests still pass after merging this in, so should be good to go. Thanks!

@flokli
Copy link
Contributor

flokli commented Dec 22, 2019

@tbenst mentioned this broke nginx, as it's not able to open the log file:

Dec 22 03:54:01 hydra-server jdf8k5jc38ny3zfshcnxxiw52l9h8x4b-unit-script-nginx-pre-start[18157]: 2019/12/22 03:54:01 [emerg] 18158#18158: open() "/var/spool/nginx/logs/access.log" failed (13:>

When checking on a NixOS 19.09 machine however, I couldn't reproduce log files being owned by root. @NinjaTrappeur , @asymmetric, any thoughts?

@Izorkin
Copy link
Contributor Author

Izorkin commented Dec 22, 2019

Before update -

sudo ls -lah /var/spool/nginx/logs
итого 20K
drwxr-x--- 2 nginx nginx 4,0K дек 22 15:53 .
drwxr-x--- 8 nginx nginx 4,0K дек 22 15:53 ..
-rw-r--r-- 1 root  root  1,4K дек 22 15:53 access.log
-rw-r--r-- 1 root  root   134 дек 22 15:53 error.log
-rw-r--r-- 1 root  root     5 дек 22 15:53 nginx.pid

After this PR -

итого 16K
drwxr-x--- 2 nginx nginx 4,0K дек 22 18:08 .
drwxr-x--- 8 nginx nginx 4,0K дек 22 18:08 ..
-rw-r--r-- 1 nginx nginx 1,4K дек 22 18:08 access.log
-rw-r--r-- 1 nginx nginx  132 дек 22 18:08 error.log

Need remove log files or change owner to nginx

@aanderse
Copy link
Member

This should do the trick:

systemd.tmpfiles.rules = [
  "Z '${cfg.stateDir}/logs' 0750 ${cfg.user} ${cfg.group} - -"
];

@flokli
Copy link
Contributor

flokli commented Dec 22, 2019 via email

@dhess
Copy link
Contributor

dhess commented Dec 24, 2019

This commit breaks services.nginx.virtualHosts.<vhost>.useACMEHost, even with security.acme.certs.<vhost>.allowKeysForGroup and group nginx. I haven't figured out why, yet.

It's because the permissions on the pem files that acme writes are -rwx------ and ownership is root:nginx

edit: I believe this is because I didn't originally have allowKeysForGroup set. It was working anyway because nginx was reading certs as root. Now that it's not, I noticed that allowKeysForGroup was not set. I've enabled it, but it appears that the acme service only sets permissions to 0750 if allowKeysForGroup is set when it renews certs, which mine hasn't done.

tldr; I think this is a configuration issue on my end and it shouldn't affect other users who've set it up properly. I'll confirm later when I've had a chance to check this.

edit2: yes, it's as I explained. This was just a configuration error on my end that manifested once the change to the nginx module was made. Sorry for the false alarm.

@nh2
Copy link
Contributor

nh2 commented Apr 2, 2020

I have the suspicion that this file broke running nginx as root:

When you manually configure services.nginx.user = "root";, file uploads fail like this:

Apr 02 18:24:33 myhostname nginx[11878]: 2020/04/02 18:24:33 [crit] 11885#11885: *71 open() "/var/spool/nginx/client_body_temp/0000000012" failed (13: Permission denied)

Here, the nginx master process 11878 runs as root (as configured) and the worker process 11885 runs as nobody.

The directory permissions are:

# ls -lah /var/spool/nginx/
total 32K
drwxr-x--- 8 root   root 4.0K Apr  2 18:59 .
drwxr-xr-x 3 root   root 4.0K Apr  2 18:04 ..
drwx------ 2 nobody root 4.0K Apr  2 18:22 client_body_temp
drwx------ 2 nobody root 4.0K Apr  2 18:22 fastcgi_temp
drwxr-x--- 2 root   root 4.0K Apr  2 18:22 logs
drwx------ 2 nobody root 4.0K Apr  2 18:22 proxy_temp
drwx------ 2 nobody root 4.0K Apr  2 18:22 scgi_temp
drwx------ 2 nobody root 4.0K Apr  2 18:22 uwsgi_temp

Because /var/spool/nginx/ is rwxr-x--- (lacks x for non-root user/group), the nobody user cannot traverse and thus write into the subdirectory it owns (client_body_temp).

In other words, it seems like the lines

2a413da#diff-795fa65a7c41a479084de826e4e2e65cR672

    systemd.tmpfiles.rules = [
      "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -"

do not have the desired effect: Yes, they change the parent directory, but if nginx then drops privileges as it did before, child dirs cannot be written to with the dropped perms.

@danbst
Copy link
Contributor

danbst commented Apr 3, 2020

@nh2 which also implied, nginx won't be able to write to logs directory, as it is not nobody writeable...

Looks like root requires exceptional handling here.

@sumnerevans
Copy link
Member

sumnerevans commented Apr 4, 2020

I'm having an issue very similar to this, but with services.ngnix.user set to the default. The issue is that the nginx user cannot write to client_body_temp or proxy_temp (or any of the other directories with group of nobody. This causes issues for Airsonic (when I download files) and Marix (when I send messages) because Nginx aggressively buffers large downloads and uploads using files in client_body_temp and proxy_temp.

My workaround for now has been to just SSH to my server and chown -R nginx:nginx /var/spool/nginx, but this is not sustainable. Should the Nginx module also have rules for:

      "d '${cfg.stateDir}/client_body_temp' 0750 ${cfg.user} ${cfg.group} - -"
      "d '${cfg.stateDir}/fastcgi_temp' 0750 ${cfg.user} ${cfg.group} - -"
      "d '${cfg.stateDir}/proxy_temp' 0750 ${cfg.user} ${cfg.group} - -"
      "d '${cfg.stateDir}/scgi_temp' 0750 ${cfg.user} ${cfg.group} - -"
      "d '${cfg.stateDir}/uwsgi_temp' 0750 ${cfg.user} ${cfg.group} - -"

(which are the directories that nginx appears to create) in addition to the already existing:

      "d '${cfg.stateDir}/logs' 0750 ${cfg.user} ${cfg.group} - -"

?

I'm very new to this whole NixOS thing, so maybe there's a better way of achieving what I'm trying to accomplish.

@flokli
Copy link
Contributor

flokli commented Apr 4, 2020

@nh2 @sumnerevans since 50d6e93, there should be a Z line in tmpfiles that should chown /var/spool/nginx recursively to cfg.user / cfg.group - shouldn't nginx be able to create and update files in there with that?

@nh2
Copy link
Contributor

nh2 commented Apr 4, 2020

@flokli I suspect that should help with @sumnerevans issue, but it seems that it wouldn't help with mine, since as described above, nobody is relevant for that.

@sumnerevans
Copy link
Member

I misspoke in my last comment. The user is nobody, the group was nginx (totally forgot which way ls output worked 🤦‍♂️

@flokli
Copy link
Contributor

flokli commented Apr 5, 2020

Sorry, I'm now confused. Specifying root as a user likely requires special handling. Could both of you open issues with example configurations?

@nh2
Copy link
Contributor

nh2 commented Apr 5, 2020

Specifying root as a user likely requires special handling.

That is what was there before:

  • Before, the systemd service ran as root, so the nginx master process ran as root, and then the worker processes ran as an unprivileged user (user nginx nginx here, or nobody by default if thta line is not given).
  • Now the systemd service runs as nginx, including the master process.

Could both of you open issues with example configurations?

Yes. Done in #84391.

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

Successfully merging this pull request may close these issues.

None yet