Add sshd options for alternative `~/.ssh/environment` and `~/.ssh/rc` files
Continuing on from a previous attempt on the mailing list at proposing a mechanism for specifying alternative paths for the environment and rc files used by sshd, I figured it would be worth simply working on it there and then and submitting it as a PR.
The rationale for this comes from the prior mailing list discussion near the start of the month regarding the possibility of built-in fallback paths which would follow the XDG Base Directory Specification, and my own attempt following it at implementing it myself. As it turns out, it was not very feasible to implement full compliance, as some of the files within the ~/.ssh directory — namely, authorized_keys, environment and rc — were not read by the client program, but the server daemon running as a different privileged user. In attempting to implement any solution that required the use of environment variables to define alternative locations, I was not able to find an easy way — if such even exists — of having the sshd user read the authenticated user's existing environment.
Therefore, it would instead make sense to leverage the existing configuration and program invocation options such as ssh -F [config] for a user to enforce compliance as they wish. However, while it is possible to specify alternative paths for sshd to use for authorised key files, ~/.ssh/environment and ~/.ssh/rc remained hard-coded with no option to specify alternative paths. This PR implements this option for both of these files via the UserEnvironmentFile and UserRCFile options respectively for sshd_config, completely eliminating the need for the ~/.ssh directory should the user choose to not use it.
If there are any problems with the PR as it stands, please let me know and I'll be happy to address them.
Great. Another thing everyone has to scan for. Not a fan.
I don't see the problem. By default, none of these are overridden and work the same as they always have. If people are already scanning for alternate authorized_keys files then why couldn't they do so for environment and rc too?
still not a fan.
I don't see the problem. By default, none of these are overridden and work the same as they always have. If people are already scanning for alternate
authorized_keysfiles then why couldn't they do so forenvironmentandrctoo?
I will give you a reason. Now I have one cool place to set alias with no UID traceability. environment is an open book. And people who can't afford to buy commercial scanners have yet another setting they have to watch out for in ssh_conf. All this PR does is make CrowdStrike money.
Not. A. Fan.
I don't think i follow what are you trying to say here. Can you elaborate what exactly is bothering you and what CrowdStrike (whatever that is) has anything in common with the PR? Thanks! :)
@62832 i eyeballed your commit. Did you make sure that the environment file specified in the option is locked down to the root user as owner and locked down with chattr +i ? If not... please for the love of God, add it.
@62832 i eyeballed your commit. Did you make sure that the environment file specified in the option is locked down to the root user as owner and locked down with
chattr +i? If not... please for the love of God, add it.
OpenSSH doesn't even do this with the existing ~/.ssh/environment file prior to this PR. Why is this a requirement all of a sudden and why can this not be addressed in a separate PR if need be?
@62832 i eyeballed your commit. Did you make sure that the environment file specified in the option is locked down to the root user as owner and locked down with
chattr +i? If not... please for the love of God, add it.OpenSSH doesn't even do this with the existing
~/.ssh/environmentfile prior to this PR. Why is this a requirement all of a sudden?
sshd enforces flags on the key files in the user folder. Now you want to take the environment file, managed by OS security in the user folder, and put that anywhere.... and if you're determined to centralize the environment file you already have ln sitting on your machine right now for what arguably is just an edge case.
At least refuse to use the file if the underlying fs has no ro flag capability (and abort/ignore if it doesn't), and require ro be set on the file before sucking it up.
sshdenforces flags on the key files in the user folder.
If that is indeed the case, I'm happy to take another look and address this. I concede that I might have glossed over something important, but I would have better appreciated if this was clarified with less hostility.
and if you're determined to centralize the environment file you already have
lnsitting on your machine right now for what arguably is just an edge case.
Symlinks are not the answer. If I want to comply by specifications such as XDGBDS then I want there to be NO ~/.ssh directory, symlinked or not. Otherwise, why even provide the options to move different files and use those to begin with?
At least refuse to use the file if the underlying fs has no ro capability (and abort/ignore if it doesn't), and require ro be set on the file before sucking it up.
As mentioned in the first point, that can be arranged.
At least refuse to use the file if the underlying fs has ro capability (and abort/ignore if it doesn't), and require ro be set on the file before sucking it up.
As mentioned in the first point, that can be arranged.
Thank you... updated out my typo above but you got what I meant. The ro check would give a lot of assurance that whatever option value is set, it's going to get some basket of controls that /etc gets, at least, since the file will be put anywhere by the user and they will be inclined to strip perms and chmod a+rw it.
Thought about this some more...
You have to resolve down the path and examine if the user setting keeps the file in the own user's home folder, because you're assuming this is just going to be set for XDG but user can set it anywhere. If it stays in the user's home folder but no longer on the 0700 .ssh folder, you have to perm check the file to make sure the user did not put on global write/execute on it.
If it's outside the user home folder, then what I said above... file has to be owned by root and +i must be on the file because it's going to be global readable (then it's the user's problem if sensitive stuff is in it)... that would be ok.
I think that gets you in a better position because right now ssh is not checking flags there and the 0700 on .ssh is what's protecting it.
Sounds good. In that case, I'm thinking that the steps to take would be the following:
- Check if the (env/rc) file has permissions other than
go-rwxand if it does, ignore it - Further check if the file resides somewhere in the user's home directory
- If it does not reside in home, check if the file is owned by
rootand has the immutable attribute and if not, ignore it.
Is this what you had in mind?
Sounds good. In that case, I'm thinking that the steps to take would be the following:
- Check if the (env/rc) file has permissions other than
go-rwxand if it does, ignore it
0700 anywhere in the $HOME folder, outside the $HOME folder 0755
+i check if it's OUTSIDE the $HOME folder, no check needed if it's inside.
- If it does not reside in home, check if the file is owned by
rootand has the immutable attribute and if not, ignore it.Is this what you had in mind?
Yes if it resolves down to outside the $HOME folder, +i needs to be on it root chown also must be on it and if the underlying fs does not have the ability to do the +i flag, ignore the setting.
That would keep the existing functionality the same when the option has been set, but then if an absolute path or path to somewhere else on the filesystem that makes the file shared needs good write protection.
I'm guessing manpages update needed and/or printf because it's unexpected behavior to set an absolute path for the user folder and the client just ignores it with no information, so the user would need to be told (same way ssh client tells you that perms are wrong on the keys and authorized_keys)
@christoofar I've so far manage to implement the checks for user ownership and outside permissions within $HOME, and root ownership outside of $HOME.
Unfortunately, I'm at a loss as to how to put together the immutability check considering that file flags work very differently between Linux and *BSD. chattr +i is very much Linux-specific (e2fsprogs) and in order to check for it as such it would rely on the Linux-specific fs.h, whereas on OpenBSD, say, flags set via chflags would be retrieved via OpenBSD's stat struct.
Since I don't know of a particularly easy portable way to check for this, I'd be eager to hear any potential alternatives that might be worth considering instead.
Further consideration: it probably doesn't make sense to enforce root ownership on an env/rc file outside of $HOME if it happens to reside in a directory that's still owned by the user. Would it be fine in that case to just check the owner of the parent directory and see if it matches with the owner of the file?
Further consideration: it probably doesn't make sense to enforce
rootownership on an env/rc file outside of$HOMEif it happens to reside in a directory that's still owned by the user. Would it be fine in that case to just check the owner of the parent directory and see if it matches with the owner of the file?
Well, ignoring the xz backdoor situation, it's still not a good idea. The keys files are supposed to be just data in the eyes of the user, with no surprises. Although we've learned that instructions can be injected into SSH certificate presentations and the fields can then deposit script. sshd runs as root everywhere someone also wants to login and claim root from their shell.
The environment and rc files are obvious injector points. If you take them out of where the user expects them to be (in the XDG reason you gave, it's still going to live under $HOME), then in my eyes it's not a shared object if 0700 is on the files.
But you take it anywhere outside that expectation, root ownership matters. It matters on the file. A shared environment file is what you're going to have happen by default so you should be throwing on as much security gates as you can.
I think it's way better to take the more user-annoying option and enforce to the file and not allow a root->lazyadmin ownership if the file leaves the users area.
They will ask around why it's like that and on a machine that's set up with lots of group ownerships it will stop some priv escalation attacks.