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

Run as non-root #14

Open
geofft opened this issue Mar 15, 2021 · 13 comments · May be fixed by #110
Open

Run as non-root #14

geofft opened this issue Mar 15, 2021 · 13 comments · May be fixed by #110

Comments

@geofft
Copy link
Collaborator

geofft commented Mar 15, 2021

It occurs to me there's no particular reason to keep running as root (at least on most systems, though for certain nss_ldap configurations, you've got a password that's readable only as root). We should support dropping privileges.

I think best practice is to run as your own system account instead of nobody because that quickly turns nobody into a fairly juicy target of its own, so probably this wants to be an argument to drop privileges to a specific user + some packaging config to create a system user.

@catern
Copy link

catern commented May 17, 2021

Isn't this trivially supported by using systemd socket activation? If nsncd uses systemd socket activation then it can just run with User=nobody or User=nsncd, it never needs root.

@leifwalsh
Copy link
Collaborator

Yeah but #9

@catern
Copy link

catern commented May 21, 2021

How about having systemd pass the socket down, but not socket activating it? i.e. nscd started up immediately rather than only on connection to the socket, but the socket is still passed down. I don't recall exactly how to configure that in systemd but it should be possible.

@geofft
Copy link
Collaborator Author

geofft commented May 21, 2021

I think it's roughly equally as easy to just call setresuid (and setgroups(0, NULL)?) ourselves. We'd still probably use systemd-sysusers to create the user (assuming it does actually work properly on Debian, which I think it does).

I continue to worry about cases where systemd has the nscd socket open and receiving connectons, indicating to libc that nscd is worth trying, but nothing is actually accepting connections from the socket.

@catern
Copy link

catern commented May 21, 2021 via email

@geofft
Copy link
Collaborator Author

geofft commented May 21, 2021

What happens if systemd opens the socket immediately before starting nsncd, attempts to look up the non-root user to drop privileges to, and then deadlocks on itself?

That's very close to what happened in #9. ((I think systemd has some sort of explicit workaround for this scenario, but given the discussions in the two linked threads and the claims made about NSS and early boot, I wouldn't trust it.)

@catern
Copy link

catern commented May 21, 2021

In that scenario the fact that glibc stores whether nscd is usable after the first try saves us.

@geofft
Copy link
Collaborator Author

geofft commented May 21, 2021

It stores it per process (in a global), and presumably systemd forks before attempting to drop privileges (lest it drop privileges of pid 1), so I don't think we can count on that. And if it does the lookup from pid 1, then pid 1 (which is single-threaded) stalls for five seconds, which isn't great.

Basically, assuming that this will work is a sizable production risk, closely related to risk that we've previously gotten burned by, for no obvious benefit (yes, in theory, you can inspect what the systemd unit file does, but in practice, having tried to read that code, you can't... and if you do want to inspect what nsncd does, the code for that is right there).

@flokli
Copy link
Contributor

flokli commented Oct 14, 2022

On NixOS, I successfully run nsncd as a non-root user, with effectively the following directives in [Service]:

[Service]
ExecStart=/path/to/bin/nsncd
User=nscd
Group=nscd
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=read-only
ProtectSystem=strict
RemoveIPC=true
Restart=always
RestrictSUIDSGID=true
RuntimeDirectory=nscd
Type=notify # needs #35

The nscd user is defined in /etc/fstab.

This works fairly well, and doesn't rely on any socket activation.

The RuntimeDirectory=nscd directive causes systemd to create/chown /run/nscd to be write-able by the User specified, and as /var/run is a symlink to /run (at least in our case), nsncd has enough permissions to create /var/run/nsncd/socket.

@geofft
Copy link
Collaborator Author

geofft commented Oct 14, 2022

Oh, yes, I think that making /run/nscd owned by the non-root user should work, good point!

@leifwalsh
Copy link
Collaborator

are we done here?

@flokli
Copy link
Contributor

flokli commented Apr 10, 2024

We can probably update the unit file in the repo and/or add some docs about rootless operation.

flokli added a commit to flokli/nsncd that referenced this issue Apr 23, 2024
This updates the nsncd.service systemd unit file to run nsncd as a
`nscd` user and group, and enables sandboxing.

Fixes twosigma#14.
@flokli flokli linked a pull request Apr 23, 2024 that will close this issue
@flokli
Copy link
Contributor

flokli commented Apr 23, 2024

I ported the unit file changes over in #110, though the Debian packaging bits need some more work probably.

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 a pull request may close this issue.

4 participants