Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: OpenSSH: Dev

Authenticating users from proprietary user databases

 

 

OpenSSH dev RSS feed   Index | Next | Previous | View Threaded


yaniv at aknin

Oct 5, 2009, 11:27 AM

Post #1 of 10 (1419 views)
Permalink
Authenticating users from proprietary user databases

Hi,

I work for a company which develops a rather complicated Linux-based
grid-technology appliance. The appliance is made of several Linux hosts,
exposing its functionality over a proprietary CLI-like protocol. This
protocol currently works by running a proprietary client executable on a
host, sending the command via TCP/IP to one of the appliance's hosts and
receiving the response. The client handles authentication, compression, etc.
In addition, it is possible to access the various hosts of the clustered
appliance as a regular Linux host using plain SSH for technician maintenance
(not exposed to customers).

I'm a big proponent of exposing our CLI over SSH as well and doing away with
the proprietary "cli executable". Already the CLI executable can run inside
the appliance itself, and I'd very much like it to be possible to run a
single CLI command by running:
$ ssh user [at] applianc command parameter=value
...and also to make it possible to run a readline based appliance-CLI
interactive "shell" (we already have something like that) by running:
$ ssh user [at] applianc

We can easily separate (at least, at the transport layer) between the
"maintenance" SSH shell and the "CLI" SSH shell by running two sshd
instances and binding them to different ports (or addresses). I'm thinking
that the CLI-SSH instance have a sshd_config global ForceCommand that will
read SSH_ORIGINAL_COMMAND and run the CLI command or the 'CLI interactive
shell' accordingly. Also, I think I realize the security implications
insofar as our CLI executable is concerned, as well as the importance of
sanitizing the SSH connection (no sftp, no forwarding, etc). I'd much rather
not direct the discussion in that direction, unless you think this is
totally imperative and I missed something gargantuan. I know exploiting our
CLI can easily mean exploiting our box and I'll take that into account as
best I can (I'm not sure the current implementation is any better, either).

The issue I'm not sure how to tackle is how to make SSH 'natively'
authenticate the appliance's built-in users. Our appliance has its own user
directory with credentials, unrelated to the passwd/shadow directory of
nsswitch. The 'obvious' solution is to write an nsswitch module which will
fake all users from the appliance's proprietary directory as passwd:shadow
entries (we store the passwords in a way that is shadow compatible), and
give all users a uniform passwd entry with only the username/shadow hash
changing. This entry will have a fixed UID, GID, shell and homedir, and this
fixed homedir will contain an authorized_keys file that will dynamically
contain keys as set for our appliance's users (I'll add the CLI command
"user_add_ssh_key" or something).

While the above solution is, like I said, obvious, it has a very severe
drawback I'm not sure how to tackle, and that's the fact that nsswitch
modules are system global. I don't want our hosts' Linux users (root,
nobody, daemon, etc) to collide with the appliance's users and vice versa,
and I'd definitely not want to jeopardize the stability of core Linux
services in any way by adding something as complex as looking up our
clustered database for users from within all processes in the system.

I'm not sure how to further handle this. Should I patch OpenSSH itself (oh
god, please, no...)? Should I use some dynamic LD_PRELOAD concoction to
'rewrite' nsswitch.conf only for this sshd instance? Should I give up on
OpenSSH entirely and use an SSH implementation which is less focused on
letting system-users run shell-commands (like twisted.conch, or maybe
others)? All these options are... well, doable, but all seem like a lot of
(fragile) work. I'd appreciate comments and ideas.

Sincerely,
- Yaniv
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


dtucker at zip

Oct 5, 2009, 12:23 PM

Post #2 of 10 (1367 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Yaniv Aknin wrote:
[...]
> I'm not sure how to further handle this. Should I patch OpenSSH itself (oh
> god, please, no...)? Should I use some dynamic LD_PRELOAD concoction to
> 'rewrite' nsswitch.conf only for this sshd instance?

You could write those replacement functions for getpwnam() and friends
and just statically link them into application sshd. This is what we
already do with libopenbsd-compat when there's a broken native function
for which we have compat code (eg snprintf).

As long as the replacement functions provide the system-level accounts
that sshd expects (all I can think of is root and the privsep user) then
it should work, and should not require any patching (just feed configure
"--with-ldflags=-lyourlib").

--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


yaniv at aknin

Oct 5, 2009, 12:35 PM

Post #3 of 10 (1354 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Hrmf, how simple, I didn't think about patching getpwnam() et al themselves,
I was somehow locked on patching the nsswitch circuitry.
But in this case, why not use LD_PRELOAD and avoid the need to build my own
OpenSSH and have two different OpenSSH builds?
Thanks,
- Yaniv

On Mon, Oct 5, 2009 at 9:23 PM, Darren Tucker <dtucker [at] zip> wrote:

> Yaniv Aknin wrote:
> [...]
>
>> I'm not sure how to further handle this. Should I patch OpenSSH itself (oh
>> god, please, no...)? Should I use some dynamic LD_PRELOAD concoction to
>> 'rewrite' nsswitch.conf only for this sshd instance?
>>
>
> You could write those replacement functions for getpwnam() and friends and
> just statically link them into application sshd. This is what we already do
> with libopenbsd-compat when there's a broken native function for which we
> have compat code (eg snprintf).
>
> As long as the replacement functions provide the system-level accounts that
> sshd expects (all I can think of is root and the privsep user) then it
> should work, and should not require any patching (just feed configure
> "--with-ldflags=-lyourlib").
>
> --
> Darren Tucker (dtucker at zip.com.au)
> GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
> Good judgement comes with experience. Unfortunately, the experience
> usually comes from bad judgement.
>
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


chrivers at iversen-net

Oct 5, 2009, 1:31 PM

Post #4 of 10 (1352 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

On 2009-10-05 20:27, Yaniv Aknin wrote:
> Hi,
>
> I work for a company which develops a rather complicated Linux-based
> grid-technology appliance. The appliance is made of several Linux hosts,
> exposing its functionality over a proprietary CLI-like protocol. This
> protocol currently works by running a proprietary client executable on a
> host, sending the command via TCP/IP to one of the appliance's hosts and
> receiving the response. The client handles authentication, compression, etc.
> In addition, it is possible to access the various hosts of the clustered
> appliance as a regular Linux host using plain SSH for technician maintenance
> (not exposed to customers).
>
> I'm a big proponent of exposing our CLI over SSH as well and doing away with
> the proprietary "cli executable". Already the CLI executable can run inside
> the appliance itself, and I'd very much like it to be possible to run a
> single CLI command by running:
> $ ssh user [at] applianc command parameter=value
> ...and also to make it possible to run a readline based appliance-CLI
> interactive "shell" (we already have something like that) by running:
> $ ssh user [at] applianc
>
> We can easily separate (at least, at the transport layer) between the
> "maintenance" SSH shell and the "CLI" SSH shell by running two sshd
> instances and binding them to different ports (or addresses).

Does this mean that you want every user to be able to log on in either
"CLI" or "maintenance" mode? Otherwise, just set the shell of the
specific users to the right shell.

> The issue I'm not sure how to tackle is how to make SSH 'natively'
> authenticate the appliance's built-in users. Our appliance has its own user
> directory with credentials, unrelated to the passwd/shadow directory of
> nsswitch. The 'obvious' solution is to write an nsswitch module which will
> fake all users from the appliance's proprietary directory as passwd:shadow
> entries (we store the passwords in a way that is shadow compatible), and
> give all users a uniform passwd entry with only the username/shadow hash
> changing. This entry will have a fixed UID, GID, shell and homedir, and this
> fixed homedir will contain an authorized_keys file that will dynamically
> contain keys as set for our appliance's users (I'll add the CLI command
> "user_add_ssh_key" or something).
>
> While the above solution is, like I said, obvious, it has a very severe
> drawback I'm not sure how to tackle, and that's the fact that nsswitch
> modules are system global. I don't want our hosts' Linux users (root,
> nobody, daemon, etc) to collide with the appliance's users and vice versa,
> and I'd definitely not want to jeopardize the stability of core Linux
> services in any way by adding something as complex as looking up our
> clustered database for users from within all processes in the system.
>
> I'm not sure how to further handle this. Should I patch OpenSSH itself (oh
> god, please, no...)? Should I use some dynamic LD_PRELOAD concoction to
> 'rewrite' nsswitch.conf only for this sshd instance? Should I give up on
> OpenSSH entirely and use an SSH implementation which is less focused on
> letting system-users run shell-commands (like twisted.conch, or maybe
> others)? All these options are... well, doable, but all seem like a lot of
> (fragile) work. I'd appreciate comments and ideas.

I have worked with authentication solutions before (specifically with
NSS), and as far as I can see, you have a few options. I'll let you
decide which one suit your needs better, if any:

1a) Make an NSS plugin

(as you suggested)

1b) Make an NSS plugin with virtual usernames

As 1a, but prefix all usernames with a common prefix, such as "cli_"

That way, the names cannot clash.

2) Actually export CLI users into system users in passwd and shadow

Doesn't seem very nice, but it could work

3) Use libnss-extrausers

This existing plugin allows you to have an entirely seperate set of
passwd/group/shadow files, that are not related to the usual ones in
/etc. This way, you can safely make an export of all your users into the
files in /var/lib/extrausers, without risking anything. Worst case, only
your CLI users are affected by any problems.

4) Use a common database for all users

If you can export your current users (and change your existing
tools) to use something like PostgreSQL or LDAP for storing users, you'd
be able to use existing NSS plugins to connect to them.

Out of these options, I'd recommend that you look at number 3, since
it's so dead simple to use, while still (I believe) solving your problem.

--
Med venlig hilsen
Christian Iversen
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


dtucker at zip

Oct 5, 2009, 3:33 PM

Post #5 of 10 (1354 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Yaniv Aknin wrote:
> Hrmf, how simple, I didn't think about patching getpwnam() et al
> themselves, I was somehow locked on patching the nsswitch circuitry.
> But in this case, why not use LD_PRELOAD and avoid the need to build my
> own OpenSSH and have two different OpenSSH builds?

Yeah that should work too.

Personally I prefer that daemons don't change their behaviour if you
happen to restart them without some environment variable, but it sounds
like it would be fine for your appliance environment.

--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


yaniv at aknin

Oct 5, 2009, 9:05 PM

Post #6 of 10 (1344 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Thank you very much for your prompt and interesting replies.

To make sure I'm perfectly clear, I'd like complete separation between the
"CLI" users and "maintenance" users. Not every CLI user is a maintenance
user, nor is every maintenance user a CLI user. Maintenance users are
regular Linux users (/etc/passwd) and CLI users are defined by the users of
the appliance, who should be 100% abstracted from the fact this is actually
a bunch of Linux boxes. I'd like the separation to be complete enough that
it would be possible to create a user in the CLI called, say, "root", and
have that user be completely unrelated to Linuxes /etc/passwd UID-0 user
root we all know.

Christian, from your suggestions, I'm indeed most interested in (3) and
maybe (1b), but the issue which still remains is how to make the NSS plugin
I'll use specific to the OpenSSH process (and its only child, the CLI
executable), so that not all processes in my system would be affected by
this change. From my cursory look at nss-extrausers, I can't see a way to
limit it to a specific process, but please enlighten me if I'm wrong.

I'm willing to go with "override getpwnam()" method suggested by Darren
(either statically as Darren stated or indeed with LD_PRELOAD), but I'd be
happy to hear another suggestion, if you have any.

Thanks again,
- Yaniv

On Mon, Oct 5, 2009 at 10:31 PM, Christian Iversen
<chrivers [at] iversen-net>wrote:

> On 2009-10-05 20:27, Yaniv Aknin wrote:
>
>> Hi,
>>
>> I work for a company which develops a rather complicated Linux-based
>> grid-technology appliance. The appliance is made of several Linux hosts,
>> exposing its functionality over a proprietary CLI-like protocol. This
>> protocol currently works by running a proprietary client executable on a
>> host, sending the command via TCP/IP to one of the appliance's hosts and
>> receiving the response. The client handles authentication, compression,
>> etc.
>> In addition, it is possible to access the various hosts of the clustered
>> appliance as a regular Linux host using plain SSH for technician
>> maintenance
>> (not exposed to customers).
>>
>> I'm a big proponent of exposing our CLI over SSH as well and doing away
>> with
>> the proprietary "cli executable". Already the CLI executable can run
>> inside
>> the appliance itself, and I'd very much like it to be possible to run a
>> single CLI command by running:
>> $ ssh user [at] applianc command parameter=value
>> ...and also to make it possible to run a readline based appliance-CLI
>> interactive "shell" (we already have something like that) by running:
>> $ ssh user [at] applianc
>>
>> We can easily separate (at least, at the transport layer) between the
>> "maintenance" SSH shell and the "CLI" SSH shell by running two sshd
>> instances and binding them to different ports (or addresses).
>>
>
> Does this mean that you want every user to be able to log on in either
> "CLI" or "maintenance" mode? Otherwise, just set the shell of the specific
> users to the right shell.
>
>
> The issue I'm not sure how to tackle is how to make SSH 'natively'
>> authenticate the appliance's built-in users. Our appliance has its own
>> user
>> directory with credentials, unrelated to the passwd/shadow directory of
>> nsswitch. The 'obvious' solution is to write an nsswitch module which will
>> fake all users from the appliance's proprietary directory as passwd:shadow
>> entries (we store the passwords in a way that is shadow compatible), and
>> give all users a uniform passwd entry with only the username/shadow hash
>> changing. This entry will have a fixed UID, GID, shell and homedir, and
>> this
>> fixed homedir will contain an authorized_keys file that will dynamically
>> contain keys as set for our appliance's users (I'll add the CLI command
>> "user_add_ssh_key" or something).
>>
>> While the above solution is, like I said, obvious, it has a very severe
>> drawback I'm not sure how to tackle, and that's the fact that nsswitch
>> modules are system global. I don't want our hosts' Linux users (root,
>> nobody, daemon, etc) to collide with the appliance's users and vice versa,
>> and I'd definitely not want to jeopardize the stability of core Linux
>> services in any way by adding something as complex as looking up our
>> clustered database for users from within all processes in the system.
>>
>> I'm not sure how to further handle this. Should I patch OpenSSH itself (oh
>> god, please, no...)? Should I use some dynamic LD_PRELOAD concoction to
>> 'rewrite' nsswitch.conf only for this sshd instance? Should I give up on
>> OpenSSH entirely and use an SSH implementation which is less focused on
>> letting system-users run shell-commands (like twisted.conch, or maybe
>> others)? All these options are... well, doable, but all seem like a lot of
>> (fragile) work. I'd appreciate comments and ideas.
>>
>
> I have worked with authentication solutions before (specifically with NSS),
> and as far as I can see, you have a few options. I'll let you decide which
> one suit your needs better, if any:
>
> 1a) Make an NSS plugin
>
> (as you suggested)
>
> 1b) Make an NSS plugin with virtual usernames
>
> As 1a, but prefix all usernames with a common prefix, such as "cli_"
>
> That way, the names cannot clash.
>
> 2) Actually export CLI users into system users in passwd and shadow
>
> Doesn't seem very nice, but it could work
>
> 3) Use libnss-extrausers
>
> This existing plugin allows you to have an entirely seperate set of
> passwd/group/shadow files, that are not related to the usual ones in /etc.
> This way, you can safely make an export of all your users into the files in
> /var/lib/extrausers, without risking anything. Worst case, only your CLI
> users are affected by any problems.
>
> 4) Use a common database for all users
>
> If you can export your current users (and change your existing tools) to
> use something like PostgreSQL or LDAP for storing users, you'd be able to
> use existing NSS plugins to connect to them.
>
> Out of these options, I'd recommend that you look at number 3, since it's
> so dead simple to use, while still (I believe) solving your problem.
>
> --
> Med venlig hilsen
> Christian Iversen
>
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


peter at stuge

Oct 5, 2009, 10:36 PM

Post #7 of 10 (1352 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Yaniv Aknin wrote:
> I'd like the separation to be complete enough that it would be
> possible to create a user in the CLI called, say, "root", and have
> that user be completely unrelated to Linuxes /etc/passwd UID-0 user
> root we all know.

You want a new namespace so you can not use nss. And you will need
one sshd for each namespace.


> I'm willing to go with "override getpwnam()" method suggested by
> Darren

I think it's the easiest way.


//Peter
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


christian.pfaffel-janser at siemens

Oct 6, 2009, 5:10 AM

Post #8 of 10 (1348 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Yaniv Aknin wrote:

> Thank you very much for your prompt and interesting replies.
>
> To make sure I'm perfectly clear, I'd like complete separation between the
> "CLI" users and "maintenance" users. Not every CLI user is a maintenance
> user, nor is every maintenance user a CLI user. Maintenance users are
> regular Linux users (/etc/passwd) and CLI users are defined by the users of
> the appliance, who should be 100% abstracted from the fact this is actually
> a bunch of Linux boxes. I'd like the separation to be complete enough that
> it would be possible to create a user in the CLI called, say, "root", and
> have that user be completely unrelated to Linuxes /etc/passwd UID-0 user
> root we all know.
>
> Christian, from your suggestions, I'm indeed most interested in (3) and
> maybe (1b), but the issue which still remains is how to make the NSS plugin
> I'll use specific to the OpenSSH process (and its only child, the CLI
> executable), so that not all processes in my system would be affected by
> this change. From my cursory look at nss-extrausers, I can't see a way to
> limit it to a specific process, but please enlighten me if I'm wrong.
>
> I'm willing to go with "override getpwnam()" method suggested by Darren
> (either statically as Darren stated or indeed with LD_PRELOAD), but I'd be
> happy to hear another suggestion, if you have any.
>

Hi Yaniv,

how about using the PAM stack to do the work for You? You get all the
flexibility You need.

Regards,
Christian

--
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


yaniv at aknin

Oct 6, 2009, 5:16 AM

Post #9 of 10 (1350 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Uhm, I'm not sure how that would work. I think because my users don't
"exist" in the sense the getpwnam et al won't work on them, I must either
override getpwnam or write an NSS module. Otherwise, how would sshd know
(for example) what's the UID of user foo when foo tries to log in? (same
goes for homedir, gid, etc).

Anyway, I'm already doing pretty well with LD_PRELOAD, I think I'll have a
working solution rather soon, and it wasn't even half as hard as I feared,
too.

- Yaniv

On Tue, Oct 6, 2009 at 2:10 PM, Christian Pfaffel-Janser <
christian.pfaffel-janser [at] siemens> wrote:

> Yaniv Aknin wrote:
>
> > Thank you very much for your prompt and interesting replies.
> >
> > To make sure I'm perfectly clear, I'd like complete separation between
> the
> > "CLI" users and "maintenance" users. Not every CLI user is a maintenance
> > user, nor is every maintenance user a CLI user. Maintenance users are
> > regular Linux users (/etc/passwd) and CLI users are defined by the users
> of
> > the appliance, who should be 100% abstracted from the fact this is
> actually
> > a bunch of Linux boxes. I'd like the separation to be complete enough
> that
> > it would be possible to create a user in the CLI called, say, "root", and
> > have that user be completely unrelated to Linuxes /etc/passwd UID-0 user
> > root we all know.
> >
> > Christian, from your suggestions, I'm indeed most interested in (3) and
> > maybe (1b), but the issue which still remains is how to make the NSS
> plugin
> > I'll use specific to the OpenSSH process (and its only child, the CLI
> > executable), so that not all processes in my system would be affected by
> > this change. From my cursory look at nss-extrausers, I can't see a way to
> > limit it to a specific process, but please enlighten me if I'm wrong.
> >
> > I'm willing to go with "override getpwnam()" method suggested by Darren
> > (either statically as Darren stated or indeed with LD_PRELOAD), but I'd
> be
> > happy to hear another suggestion, if you have any.
> >
>
> Hi Yaniv,
>
> how about using the PAM stack to do the work for You? You get all the
> flexibility You need.
>
> Regards,
> Christian
>
> --
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev [at] mindrot
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
>
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev


bitpoet at linux-config

Oct 16, 2009, 11:50 PM

Post #10 of 10 (1194 views)
Permalink
Re: Authenticating users from proprietary user databases [In reply to]

Yaniv Aknin wrote:
[using pam to authenticate 'virtual' users]
> Uhm, I'm not sure how that would work. I think because my users don't
> "exist" in the sense the getpwnam et al won't work on them, I must either
> override getpwnam or write an NSS module. Otherwise, how would sshd know
> (for example) what's the UID of user foo when foo tries to log in? (same
> goes for homedir, gid, etc).
>
> Anyway, I'm already doing pretty well with LD_PRELOAD, I think I'll have a
> working solution rather soon, and it wasn't even half as hard as I feared,
> too.
>
I just want to point out that something similar to your problem
has already been approached using pam and its possiblity to
override PAM_USER and map it to another built-in account, so maybe
you can find something helpful there:
https://bugzilla.mindrot.org/show_bug.cgi?id=1215

-Chris
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev [at] mindrot
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

OpenSSH dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.