ibm-openbmc / dev

Product Development Project Mgmt and Tracking
16 stars 2 forks source link

Default to an expired password #947

Closed joseph-reynolds closed 1 year ago

joseph-reynolds commented 5 years ago

NOTE: This issue was originally titled "Move away from a default BMC password" as we were mulling over the various ways that could be accomplished. This issue is now limited in scope to the "expired password" design (details below). Although the original discussion is preserved here, this issue is specifically only for the "expired password" design.

The "expired password" design is intended to partially satisfy the requirements of CA Law SB-327 (referenced below), section 1798.91.04 (b) (2) which states, "The device contains a security feature that requires a user to generate a new means of authentication before access is granted to the device for the first time".

The original text is below.


If you have a project based on OpenBMC, you may want to provide reasonable security by ensuring that the BMC moves away from its default password.

You can not merely change the default password (such as provided by https://github.com/openbmc/openbmc/blob/master/meta-phosphor/conf/distro/include/phosphor-defaults.inc) to some other default password because that does not by itself provide a significant security benefit. For example, if a bad actor learns the default password from one device, that actor will likely know the password for many of them.

The idea is to create a single firmware image which uses the default password, then after you test each BMC, change its password to an unique value (such as from the pwgen command) and record that password with the BMC (such as by printing it on a sticker).

If you store the generated password, such as in a database mapping the BMC serial number to its shipped password, consider privacy laws. For example, the EU GDPR law https://en.wikipedia.org/wiki/General_Data_Protection_Regulation.

TODO: Determine what happens to the password if the BMC is factory reset.

An alternate approach to the one described here is: Keep the default password, but operate with limited function, such as by locking the device into Provisioning mode per https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/21195 until the password is changed.

Reference: Laws may require products to have reasonable security built into them, for example, by not having a default password. See, for example, CA Law SB-327 https://leginfo.legislature.ca.gov/faces/billTextClient.xhtml?bill_id=201720180SB327

joseph-reynolds commented 5 years ago

Asked a related questions in the OpenBMC open source email list: https://lists.ozlabs.org/pipermail/openbmc/2019-June/016703.html

joseph-reynolds commented 5 years ago

Here is an idea. Have a new distro feature to expire the password. The feature would be off by default, and security conscious use cases can opt-in. When the feature is used, the root and its default password are still used, but the password is expired. This expired password:

It seems like this would this comply with the law, specifically CA Law TITLE 1.81.26., Security of Connected Devices, 1798.91.04 b.2 (but I am software engineer, not a lawyer).

The work for OpenBMC would be:

The testing scenario would be:

  1. Flash (scratch install) the BMC. Ensure no BMC network-facing functions operate (ssh, https, ipmi) that is, they indicate a problem with the signon.
  2. Change the default password to a new password (mechanism TBD). Ensure it changes correctly and is no longer expired. Ensure the default password no longer works. Ensure network network-facing interfaces work correctly.
  3. Code update the BMC to a different compatible firmware level and ensure its network-facing interfaces continue to work. Ensure the default password does not work.
  4. Factory reset the BMC, and ensure its network-facing interfaces stop working and the default password works again.
amboar commented 5 years ago

Can be used to change the password (mechanism to be determined), perhaps via ssh into the system or ipmitool user set password 1 ${new_password}.

I hope that this would require authentication from that point forward?

joseph-reynolds commented 5 years ago

Changed the title to better reflect the purpose.

joseph-reynolds commented 5 years ago

Although having an unique password per BMC is a solution, I am not pursuing it at this time.

Note the default for the OpenBMC project will remain to have a default password. For now, these are opt-in solutions which require an explicit recipe change to use. I hope one of these solutions can become the project's default, and make the "insecure default password" an opt-in choice.

I am considering two alternatives:

  1. Expired password. Build the BMC firmware image with an expired password which cannot be used to operate the BMC, and can only be used to change the password. In this model, you power on the BMC and access it with default credentials [e.g., default password], then change those credentials to lock out everyone else while you provision the BMC.
  2. Initial provisioning mode. Build the BMC firmware image to start with a new systemd target=initial-provisioning-mode.target which cannot be used to operate the BMC, and can only be used to provision the BMC. In this model, you power on the BMC and access it with default credentials, then provision it, including altering credentials such as the password

Here are some thoughts for design requirements common to the designs above, with questions:

  1. Key point: The BMC must not be usable until the expired password or provisioning mode is cleared, for example, the BMC cannot boot the host, or perhaps something else less drastic. 1a. For example, if the BMC can be used to boot the host while the BMC is still in provisioning mode, that is a bad design because it leaves a long time window when the BMC has a default password. 1b. Provisioning mode should allow changing passwords, changing user accounts, setting up LDAP, certificates, enabling or disabling services. 1c. This idea doesn't work for use cases where the BMC admin accesses the BMC via its host (which requires the host be booted). In that case, perhaps there is something else the BMC can restrict to motivate the BMC admin to configure it. Or perhaps this situation is okay if there is no network access to the BMC.
  2. Key point: There must be some way to get out of provisioning mode which: 2a. Can be done with the expired password or when in provisioning mode, and 2b. Changes the default password effective for all interfaces which have default password.
  3. The design should consider SSH, IPMI, and REST, and Web interfaces... 3a. Some use cases may disable IPMI, or not have a Web interface, for example. 3b. Which interfaces will allow access with an expired password? As the primary interface, REST APIs should provide a way (perhaps a special URL) to provision the BMC and get out of provisioning mode (e.g., get to systemd target=multi-user).
joseph-reynolds commented 5 years ago

We will probably want the Web GUI phosphor-webui to detect the use of an expired password and have a screen which users can change the password. The flows between web app to BMC would be something like (my initial draft, please correct and improve):

  1. User supplies username and expired password to the web GUI, which forwards them to the BMC.
  2. The BMC http response returns the fact that the password is expired.
  3. The web app tells the user their password is expired and goes to a "change password" screen which lets the user enter a new password. The web app sends the password update request to the BMC.
  4. Etc.
joseph-reynolds commented 5 years ago

I am pursuing the "expired password" design for this, here: https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/23849

amboar commented 5 years ago

For a lab environment we wouldn't want it, but I would think for deployed systems we may want to require asserting physical presence as well. If we're not going to do that, we need to document when the BMC might fall into a vulnerable state (opening a race to set the password).

joseph-reynolds commented 4 years ago

Thanks, I've added a Warning to the design for the system integrator to ensure their solution doesn't have holes. It points to the "physical presence" alternate design that you mentioned. In this sense, the design 23849 is only a solution for one of many use cases.

joseph-reynolds commented 4 years ago

I've updated the design 23849 to incorporate all the comments. The design includes a starter kit for the WebGUI design. I believe 23849 is entirely approveable at this point.

I believe should pursue adding the password change facility to the dropbear SSH implementation.. Why? The right place to add this is to Yocto/OpenEmbedded, so I plan to add the new EXPIRED_PASSWORD image feature to the Yocto project, and they have agreed to a mechanism like this: https://lists.yoctoproject.org/pipermail/yocto-security/2019-July/000114.html I feel that Yocto uses ssh, and dropbear is one of the ssh servers, so if someone uses the EXPIRED_PASSWORD feature, they will need their dropbear ssh server to implement the expired password change mechanism. (A workaround is to use the OpenSSH SSH server.) Also, I feel that ssh access will continue to prevail in the OpenBMC project for quite a long time, so we should try to make it work with expired passwords. Note: There is a dropbear patch to enable changing expired password here: https://lists.ucc.gu.uwa.edu.au/pipermail/dropbear/2016q2/001895.html I have not followed up on the status of this old patch.

I've emailed the BMCWeb maintainer to get initial agreement that this can be implemented. See https://lists.ozlabs.org/pipermail/openbmc/2019-August/017577.html For what it's worth, I agree with Ed's assessment that adding PasswordChangeRequired=True to the authority model will be tricky. I plan to vet that part of the low level design via email.

joseph-reynolds commented 4 years ago

Development work items:

joseph-reynolds commented 4 years ago

There is a design change for an upgrade scenario. This scenario has a BMC with an older version installed (like OP930) and the user has not changed the password so the BMC still has the default password. When the new driver is installed, the BMC should NOT cause the password to be expired. The thinking is: its not a new install, so the default expired password should not apply.

joseph-reynolds commented 4 years ago

Some work related to this:

joseph-reynolds commented 4 years ago

Pushed user docs "expired password cheatsheet" for review here: https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/25706

joseph-reynolds commented 3 years ago

I've created https://github.com/openembedded/openembedded-core/pull/63 to merge this into openembeded-core. However, this is not currently needed. The alternate design was implemented here: https://github.com/ibm-openbmc/openbmc/blob/5434eaa5e4f53d9972c7bf3c4a90fd189f529547/meta-phosphor/recipes-phosphor/users/phosphor-user-manager/first-boot-expire-password.service

joseph-reynolds commented 1 year ago

Upstream oe-core has the expire-password support. IBM systems are using it. Closing.