mbox series

[bug#55034,0/1] Let openssh trust /gnu/store

Message ID 20220420084724.3514-1-levenson@mmer.org
Headers show
Series Let openssh trust /gnu/store | expand

Message

Alexey Abramov April 20, 2022, 8:47 a.m. UTC
This patch allows users to use /gnu/store objects for AuthorizedKeysCommand
and similar options. According to the sshd_config(5):

> The program must be owned by root, not writable by group or others, and
> specified by an absolute path.

However, this is not the case for Guix, even though it is RO. OpenSSH doesn't
check if the location mounted or ended up on the RO mount point.

I think implementing a check for RO location is much harder here, rather
than to trust /gnu/store path. The same way OpenSSH does with users' home
directory.

Let me know what you think.

Alexey Abramov (1):
  gnu: openssh: Trust /gnu/store directory

 gnu/local.mk                                  |  1 +
 .../openssh-trust-gnu-store-directory.patch   | 35 +++++++++++++++++++
 gnu/packages/ssh.scm                          |  3 +-
 3 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/openssh-trust-gnu-store-directory.patch

Comments

Ludovic Courtès April 20, 2022, 9:56 a.m. UTC | #1
Hi,

Alexey Abramov <levenson@mmer.org> skribis:

> This patch allows users to use /gnu/store objects for AuthorizedKeysCommand
> and similar options. According to the sshd_config(5):
>
>> The program must be owned by root, not writable by group or others, and
>> specified by an absolute path.

That’s the case with programs in /gnu/store.  Why isn’t it working?

> However, this is not the case for Guix, even though it is RO. OpenSSH doesn't
> check if the location mounted or ended up on the RO mount point.
>
> I think implementing a check for RO location is much harder here, rather
> than to trust /gnu/store path. The same way OpenSSH does with users' home
> directory.

(RO = read-only, right?)

I’m not sure why checking whether a file is read-only is much harder.
Am I overlooking something?

Thanks,
Ludo’.
Tobias Geerinckx-Rice April 20, 2022, 10:17 a.m. UTC | #2
On 20 April 2022 08:47:24 UTC, Alexey Abramov via Guix-patches via <guix-patches@gnu.org> wrote:
>This patch allows users to use /gnu/store objects for AuthorizedKeysCommand
>and similar options. According to the sshd_config(5):
>
>> The program must be owned by root, not writable by group or others, and
>> specified by an absolute path.
>
>However, this is not the case for Guix, even though it is RO. OpenSSH doesn't
>check if the location mounted or ended up on the RO mount point.

The RO bind mount is not a hard guarantee, and a footgun protector against accidental writes, not primarily a security feature (IMO).

By design, *anyone* can write *anything* to the store by talking to the daemon.  They just can't choose the file name.  A much weaker guarantee than OpenSSH assumes, at the very least.

With that in mind, could this highly intrusive patch be used to compromise a system?  It seems so very likely.  If it is, Guix will be rightly derided for what amounts to ifdeffing out the securities, even if OpenBSD's can be frustratingly theatrical at times.

>I think implementing a check for RO location is much harder here

Why is 'RO location' relevant here?

If the snippet you quote above is complete, which requirement does the un-bind-mounted store not meet?  I can't think of one off the top o' me head?

> , rather
>than to trust /gnu/store path.

That's a lot of trust.  Tens of gigabytes on average.

We explicitly rejected that idea in IceCat for example, instead whitelisting only specific store subdirectories.  Why is OpenSSH different?

> The same way OpenSSH does with users' home
>directory.
>
>Let me know what you think.

The rationale and its assumptions (also) belong in the patch itself, not just a separate mail.

Hi Alexey,

Thanks for the patch suggestion!

Kind regards,

T G-R

Sent on the go.  Excuse or enjoy my brevity.
Tobias Geerinckx-Rice April 20, 2022, 10:20 a.m. UTC | #3
> $EVERYTHING
>
>Hi Alexey,
>
>Thanks for the patch suggestion!
>
>Kind regards,
>
>T G-R

is a very annoying thing my MUA does.  Apologies.


Kind regards,

T G-R

Sent on the go.  Excuse or enjoy my brevity.
Alexey Abramov April 22, 2022, 6:44 a.m. UTC | #4
Hi Ludo,

Ludovic Courtès <ludo@gnu.org> writes:

> Hi,
>
> Alexey Abramov <levenson@mmer.org> skribis:
>
>> This patch allows users to use /gnu/store objects for AuthorizedKeysCommand
>> and similar options. According to the sshd_config(5):
>>
>>> The program must be owned by root, not writable by group or others, and
>>> specified by an absolute path.
>
> That’s the case with programs in /gnu/store.  Why isn’t it working?

The reason is that safe_path in openssh takes a full path of the file
and checks every directory one by one. The constrain fails on /gnu/store
directory due to write permissions for group.

openssh reports the following message:

Unsafe AuthorizedKeysCommand "/gnu/store/xxxx-echo-sshkey.sh": bad
ownership or modes for directory /gnu/store.

>> However, this is not the case for Guix, even though it is RO. OpenSSH doesn't
>> check if the location mounted or ended up on the RO mount point.
>>
>> I think implementing a check for RO location is much harder here, rather
>> than to trust /gnu/store path. The same way OpenSSH does with users' home
>> directory.
>
> (RO = read-only, right?)

Yes. 

> I’m not sure why checking whether a file is read-only is much harder.
> Am I overlooking something?

As I mentioned before, the check not just checking the file path itself,
but also follows down to the root and check every single directory for
the constrain. Me dunno, was thinking about an extra check against mount
locations, and in case it has read-only mount options along the way, I
could trust the executable. It also implies cross-compilation...

May be I overthink the thing? Maybe it is me who overlooking something?
Alexey Abramov April 22, 2022, 7:33 a.m. UTC | #5
Hi Tobias,

Thanks for the review.

Tobias Geerinckx-Rice <me@tobias.gr> writes:

[...]

> The RO bind mount is not a hard guarantee, and a footgun protector
> against accidental writes, not primarily a security feature (IMO).
>
> By design, *anyone* can write *anything* to the store by talking to
> the daemon.  They just can't choose the file name.  A much weaker
> guarantee than OpenSSH assumes, at the very least.

Even though I knew how the daemon works, I find your explanation very
nice and clear. Thank you.


[...]

>
> Why is 'RO location' relevant here?
>
> If the snippet you quote above is complete, which requirement does the
> un-bind-mounted store not meet?  I can't think of one off the top o'
> me head?

Here is a comment from safe_path function

--8<---------------cut here---------------start------------->8---
/*
 * Check a given path for security. This is defined as all components of
 * the path to the file must be owned by either the owner of of the file
 * or root and no directories must be group or world writable.
 *
 * XXX Should any specific check be done for sym links ?
 *
 * Takes a file name, its stat information (preferably from fstat() to
 * avoid races), the uid of the expected owner, their home directory and
 * an error buffer plus max size as arguments.
 *
 * Returns 0 on success and -1 on failure /
--8<---------------cut here---------------end--------------->8---

I probably had to post it first, to avoid
misunderstanding. sshd_config(5) is not that clear unfortunately. Due to
group write permissions on the /gnu/store directory, safe_path doesn't
allow openssh execute it. 

Couple of months ago I posted this problem on IRC, and you mentioned the
read-only mount thingy. So I was trying to take advantage of that.

What other options do I have?

> That's a lot of trust.  Tens of gigabytes on average.

=)

> We explicitly rejected that idea in IceCat for example, instead
> whitelisting only specific store subdirectories.  Why is OpenSSH
> different?

I didn't know that. I don't treat OpenSSH any different than other
software either. Whitelist some specific directory is a really good
option here, even though It introduces some secret knowledge.

> The rationale and its assumptions (also) belong in the patch itself,
> not just a separate mail.

True. Let me put some more context on what I am trying to do. We have
LDAP server which also holds users' ssh keys. I package a simple wrapper
for LDAP search which returns them. I would like to use it with OpenSSH,
however due to the way it checks executable in the configuration, I
don't see the way to use it.

I assume it is possible to copy that store object somewhere, but it
doesn't look right to me.
Ludovic Courtès April 27, 2022, 9:54 p.m. UTC | #6
Hi,

Alexey Abramov <levenson@mmer.org> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:
>
>> Hi,
>>
>> Alexey Abramov <levenson@mmer.org> skribis:
>>
>>> This patch allows users to use /gnu/store objects for AuthorizedKeysCommand
>>> and similar options. According to the sshd_config(5):
>>>
>>>> The program must be owned by root, not writable by group or others, and
>>>> specified by an absolute path.
>>
>> That’s the case with programs in /gnu/store.  Why isn’t it working?
>
> The reason is that safe_path in openssh takes a full path of the file
> and checks every directory one by one. The constrain fails on /gnu/store
> directory due to write permissions for group.

Oh I see, makes sense.

[...]

>> Also note that the strcmp above is incorrect: it would accept
>> /gnu/storesomethinglese.  You probably need to add a trailing slash to
>> be sure.
>
> Let me correct myself. In the previous email I wrote that the safe_path
> goes from top to bottom, but actually it walking upwards. This is an
> actual loop

[...]

> As you can see, buffer is holding the result of dirname already, hence
> I used "/gnu/store".

Sounds good then!

Thanks for explaining,
Ludo’.