On Mo, 12.11.18 14:49, David Parsley (parsley@xxxxxxxxxxxxx) wrote: > It's a fairly common practice to configure services and provide secrets > with environment variables. Passing secrets through env vars is marginally better than passing them in via cmdline params, but still bad, bad, bad practice. Seriously, don't do that. Env vars suck for this. They are generally not considered secret, and thus they leak everywhere, as programs generally don't assume them to be. As one example: "systemctl show -p Environment …" will show to unpriv users the env vars you pass to any service of your choice. Moreover, env vars are by default inherited down the process tree, and this means code that really shouldn't see them might end up seeing them. The lifecycle of secrets needs to be tightly controlled, and as limited as possible. Env vars are the opposite of that. They are propagated agressively by default, even across security boundaries (setuid/setgid!) and everything. Seriously, don't do it that way. If you do it like that, then you are building an insecure system. There are other options available. The optimal way would be to stick them in the kernel keyring. In the kernel keyring you get some guarantees about lifecycle, access control, even paging that you otherwise generally don't get. If the keyring doesn't work, then stick them in a regular file in your $RUNTIME_DIRECTORY and make sure that files has 0600 access mode or so. You can even set an env var to the path of such a file if you really want to use the env vars for something. But please, never stick passwords directly there. Another option is to allocate a pipe(), write the password in there, then pass over the reading side of the pipe to the process you fork. It's not ideal since the fd would theoretically be propagated further down the tree, but it does have nice properties in that you can read the pw off the pipe only once, and then it's gone. It also has the benefit over the file solution suggested above that it won't leave artifacts in the fs by design. > For instance, both Hubot (made by Github) and > Gopherbot (made by me) can get their Slack token from an environment > variable. In my case, github.com/lnxjedi/ansible-role-gopherbot stores the > Slack bot token with "Environtment=GOPHER_SLACK_TOKEN=xxx" in the systemd > unit file. I had hoped to keep this info to the robot user by marking the > unit file world-inaccessible. I was dismayed to see the log warning about > values being accessible via the API, though super glad that my unprivileged > user couldn't fetch it with a simple systemctl cat gopherbot. I know very > little about DBUS or any APIs for systemd, so wanted to ask - is there some > means by which a non-privileged user can access the values provided with > "Environment=..." lines? Can I disable this by disabling dbus-daemon on > server systems? Yes, the bus API is generally open for any clients. One way to access it is "systemctl show -p Environment …", another is directly with busctl. And no, you cannot reasonably disable this. It's the wrong place. It's a swiss cheese. Seriously, the right approach is not to pass these secrets in the env vars in the first place, not then to try to play hide and seek to make them hopefully not leak. Lennart -- Lennart Poettering, Red Hat _______________________________________________ systemd-devel mailing list systemd-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/systemd-devel