OpenBMC community telecon - 11/27 Agenda

Brad Bishop bradleyb at fuzziesquirrel.com
Thu Dec 21 07:29:32 AEDT 2017


Hi Michael

Thanks for the info!


> On Dec 20, 2017, at 3:26 PM, <Michael.E.Brown at dell.com> <Michael.E.Brown at dell.com> wrote:
> 
> I fully support using PAM for user and password management. This is the method we use in our product and it has been fairly successful.
> 
> However, the one thing I would like to point out is that you want to keep your "Linux users" separate from your IPMI/Web/etc users, and you want to keep your Linux groups separate from the IPMI/web/etc groups.

Can you elaborate on why and/or call out any specific issues
you’ve had with this approach?

> You configure PAM specifically to have separate PAM configurations for IPMI/web/etc that is different, for example pam_listfile for ipmi and pam_unix for logins.
> 
> This works well except for the following:
> 1) PAM api is synchronous. You have to do some lifting to ensure everything works well for async event loop programs or for multi-threaded programs.
> 2) For allowing actual Linux shell logins using IPMI/web usernames.
> 	This intersection point becomes a problem. What we do in our product may or may not be a satisfactory solution. What we do in our product is have a single Linux user "racuser" and an NSS library. All SSH or local logins map the actual username back to this racuser user. PAM is used to check the actual user password. The PAM module then sets an environment variable with the user details and correct permissions the user has. The reason this works is that we have a restricted shell where the user is not allowed to reset environment variables. All of the command line utilities check the permissions when deciding if the logged in user should be able to perform an action, and log with the user details given in the environment. This is unlikely to be a satisfactory answer for openbmc where the user can get full shell access. However, using linux containers, we may be able to use a user container to do this same mapping.
> 
> Other notes:
> 	Once you use PAM, you can then configure AD/LDAP and other by simply changing the PAM configuration. We use a custom PAM module that handles AD and LDAP, however I believe the existing open source PAM modules for AD/LDAP would work well here. Once you support AD and/or LDAP, you have to have a method of mapping directory groups to specific permissions on the local BMC, and that can be challenging. The most straightforward method is to statically configure group names, however it is also the least flexible from a large organization perspective. This is something that could be discussed/designed after base PAM support is all enabled, though.
> 
> --
> Michael
> 
> 
> -----Original Message-----
> From: openbmc [mailto:openbmc-bounces+michael.e.brown=dell.com at lists.ozlabs.org] On Behalf Of Brad Bishop
> Sent: Monday, December 18, 2017 6:32 PM
> To: Vernon Mauery <vernon.mauery at linux.intel.com>
> Cc: OpenBMC <openbmc at lists.ozlabs.org>; Richard Marian Thomaiyar <richard.marian.thomaiyar at linux.intel.com>
> Subject: Re: OpenBMC community telecon - 11/27 Agenda
> 
> 
>> On Dec 18, 2017, at 5:39 PM, Vernon Mauery <vernon.mauery at linux.intel.com> wrote:
>> 
>> On 18-Dec-2017 01:07 PM, Brad Bishop wrote:
>>> On Mon, 2017-12-04 at 17:02 -0800, Vernon Mauery wrote:
>>> 
>>> Hi Vernon
>>> 
>>> Really appreciate you putting this together - thanks.  I do have a 
>>> couple comments/questions.
>>> 
>>>> 
>>>> For the discussion on user management.
>>>> 
>>>> Overview:
>>>> 1. User management is done via PAM.
>>> 
>>> Are there any aspects of user management that are done outside of PAM?
>> 
>> Yes. It turns out that IPMI management with multiple LAN channels throws a wrench in things, so it may be that IPMI need to do some of its user management separately (like determining what privileges a user gets on a particular channel).
> 
> Could creating a group per channel on the BMC at runtime make this simpler?
> 
>> There may be other stuff like this, so it might be helpful to define a 'hook' or something that says if a user is a member of group X, you must notify group X when you want to change stuff.
>> 
>>> I only ask this because your writeup feels like a good start on a 
>>> README somewhere.  To that end, would it make sense to frame this 
>>> from the perspective of different actors attempting to add function?  
>>> For
>>> example:
>>> 
>>> If you want to implement a service that authenticates a user:
>>> - do v
>>> - do w
>>> 
>>> If you want to implement a service that adds users to a user database:
>>> - do x
>>> 
>>> If you want to implement a service that adds users to a group:
>>> - do y
>>> 
>>> If you want to implement a service that authorizes a user:
>>> - do z
>>> 
>>> etc, and then the IPMI specifics would just be adhering to this 
>>> framework.
>>> 
>>> I could have these bullet points all wrong.  This was just meant as a 
>>> straw-man for a more general document that can guide people looking 
>>> to add this type of function later.
>> 
>> Yes, this sort of writeup as a README would be a good idea. Not just an API, but a practical usage guide.
>> 
>>>> 2. If IPMI is being used, PAM loads the pam_ipmi.so password module.
>>>>  a. pam_ipmi.so intercepts password changes and saves the password
>>>>     for IPMI-enabled users to a file that can be read at a later 
>>>> time
>>>>     to initiate an RMCP+ session. (encrypted or obfuscated with a
>>>>     per-BMC key so no passwords are written directly in flash.)
>>>>  b. pam_ipmi.so implements a method to decrypt passwords and 
>>>> provide
>>>>     them to host-ipmi (for test password command) and net-ipmi (for
>>>>     session initiation)
>>>> 3. If a user is not enabled for IPMI, their password will not be 
>>>> saved
>>>>  in the ipmi database, and thus must be reset if/when that user 
>>>> gains
>>>>  IPMI capability.
>>>> 4. If a user loses IPMI capability, their password is reset to force 
>>>> a
>>>>  password change so their password is secure again.
>>> 
>>> I'm not understanding why this is needed.  Couldn't we simply remove 
>>> the password entry from the IPMI backend when the group membership 
>>> changes?  Is this an artifact of how PAM works or do we think we need 
>>> it for a more fundamental reason?
>> 
>> If the password is ever saved in the IPMI password database, it is best to assume it is no longer a secret. If you really want your password secure, it should be changed.
> 
> ok.
> 
>> 
>>>> 5. Capabilities is done via unix groups
>>>>  a. Groups like ipmi, webserver, redfish, ssh, sol can provide 
>>>> login
>>>>     or 'channel' access.
>>> 
>>> I wonder if a per-channel (or service in PAM speak?) pam_listfile 
>>> account entry can get us here.
>> 
>> Sure, that could be a pattern we follow. I would have to dig deeper to see if it buys us anything that plain-old unix groups would not provide.
>> 
>>>>  b. Groups like user-manager, media, power, sensor, etc., can 
>>>> provide
>>>>     fine-grained access for various capabilities. Providers of
>>>>     capabilities should check to see that accessors (users) have 
>>>> the
>>>>     required permission.
>>> 
>>> pam_listfile might work here too, only this would global across all 
>>> PAM services?
>> 
>> Once again, I am not entirely sure what this would buy over just using unix groups. We need to walk through some more usage scenarios like you have above.
>> 
> 
> I wasn’t intending to propose something extra - this was just the result of my brief research on how to authorize users based on group membership with PAM.
> 
> I’ve never written any programs that use PAM so I could be way off in the weeds here.  I guess my question would be what other way can we do it?
> 
> 
>>>> 6. Admin-defined 'super-groups'
>>>>  a. Provide a set of pre-defined groups of capabilities that can be
>>>>     assigned to users: Admin, User, Operator or similar that each 
>>>> have
>>>>     groups associated with them.
>>> 
>>> Do we intend to also allow the contained subgroups to be 
>>> changed/configured for the on the BMC dynamically?  For example could 
>>> you remove the 'sensor' group from the Operator group (assuming that 
>>> by default sensor group is included in the Operator group).
>> 
>> Ideally, yes, a system admin could change what capabilities each group allowed (like removing sensor capabilities from the Operator group), but to start with, just having a way to define the defaults at built time would be a good target.
>> 
>>>>  b. Changes to groups via APIs can make sure that if a user is
>>>>     assigned to a 'super-group' will stay assigned to the sub- 
>>>> groups
>>>>  c. Changes made to users via manual commands may override API 
>>>> groups
>>> 
>>> This all seemed pretty straightforward until I got to #6.  It seems 
>>> like it is definitely required but I'm wondering if it could be 
>>> staged in later somehow?
>> 
>> Yes. Let's just start with defining a way to define defaults. This should be done using a yocto mechanism that allows developers of openbmc to override at build time (maybe on a platform basis?). This makes the original defaults less important (so not all of the contributors need to fully agree on what constitutes reasonable defaults).
> 
> Sounds good.  Lets say you have an operator group on platform X with sensors and an operator group on platform Y without sensors.  How would you authorize the user?
> 
>> 
>>>> 
>>>> 
>>>> Methods:
>>> 
>>> Do we need similar APIs for groups?
>> 
>> Likely. But to start with, maybe we can skip that part. To start with, the list of groups (and their associated capabilities) will be fixed at build time.
> 
> Sounds good.
> 
>> 
>>>>   1. CREATE_USER
>>>>       Privilege-required: USER-MANAGER
>>>>       Args:
>>>>           UserName - STRING (16 bytes only - else role change to 
>>>> IPMI can't be done)
>>>>           Password - Byte Array (Max of 20 bytes if IPMID is 
>>>> chosen. For
>>>>                      others can send more bytes, but change role to 
>>>> IPMI will
>>>>                      request password again under 20 bytes)
>>>>           Roles - STRING with comma separated
>>>>       Return:
>>>>           SUCCESS ERR_USERNAME_EXIST ERR_PASSWORD_FAILS 
>>>> ERR_ROLE_FAILS
>>>>           ERR_PASSWORD_ROLE_FAIL ERR_NO_RESOURCE ERR_UNKNOWN
>>>>           ERR_AUTHORIZATION_FAIL
>>>> 
>>>>   2. DELETE_USER
>>>>       Privilege-required: USER-MANAGER
>>>>       Args:
>>>>           UserName - STRING
>>>>       Return:
>>>>           SUCCESS ERR_USERNAME_NOT_EXIST ERR_UNKNOWN 
>>>> ERR_AUTHORIZATION_FAIL
>>> 
>>> Can we use the xyz.openbmc_project.Object.Delete interface for this?
>>> The thinking was that a common Delete interface might make DBus<->UI 
>>> implementations easier.  This is the same motivation behind asking 
>>> for the org.freedesktop interfaces below.
>> 
>> I am fine with using generic interfaces as long as they fit the bill. Deleting a user seems like it should be straight-forward enough that this would work well.
>> 
>>>> 
>>>>   3. CHANGE ROLE / CHANGE_PASSWORD (OTHERS)
>>>>       Privilege-required: USER-MANAGER
>>>>       Args:
>>>>           UserName - STRING
>>>>           New Password (if changed) - Byte Array
>>>>           New Role (if changed) - Array of STRING
>>>>       Return:
>>>>           SUCCESS ERR_USERNAME_NOT_EXIST ERR_UNKNOWN 
>>>> ERR_AUTHORIZATION_FAIL
>>>>           ERR_PASSWORD_FAILS ERR_PASSWORD_ROLE_FAIL ERR_NO_RESOURCE
>>>> 
>>> 
>>> I thought the intent was to strictly use PAM for this.  In what 
>>> scenario do we need a DBus API for this?
>> 
>> For managing groups, this will have to be done outside of PAM. PAM doesn't know how to change /etc/group. So we will have to provide some central mechanism (probably in the phosphor-user-manager) to host the group management API.
>> 
>>>>   4. CHANGE_PASSWORD (SELF)
>>>>       Privilege-required: Any Valid user
>>>>       Args:
>>>>           New Password - Byte Array
>>>>       Return:
>>>>           SUCCESS ERR_PASSWORD_FAILS ERR_PASSWORD_ROLE_FAIL 
>>>> ERR_UNKNOWN
>>> 
>>> Same question as #3.
>> 
>> You are right. Passwords should not go over DBus. Things that change passwords should use PAM directly.
>> 
>>>> 
>>>>   5. LIST_USER_DETAILS
>>>>       Privilege-required: USER-MANAGER
>>>>       Args:
>>>>           NULL
>>>>       Return:
>>>>           Array of:
>>>>               USER_NAME (String)
>>>>               ROLES (String)
>>> 
>>> Could we use org.freedesktop.DBus.ObjectManager.GetManagedObjects for 
>>> this?
>> 
>> Yes.
>> 
>>>> 
>>>> Signals:
>>>>   1. UPDATED_USER_SIGNAL
>>>>       Args:
>>>>           UserName of updated user
>>>>           UpdateType:
>>>>               Role changed / User Deleted / User created / Password
>>> 
>>> Could we use org.freedesktop.DBus.Properties.PropertiesChanged here?
>> 
>> Yes.
>> 
>> --Vernon


More information about the openbmc mailing list