chef / ohai

Ohai profiles your system and emits JSON
https://docs.chef.io/ohai.html
Apache License 2.0
681 stars 450 forks source link

fips plugin does not detect host fips mode properly #1745

Open jblaine opened 2 years ago

jblaine commented 2 years ago

Description

The "fips" plugin improperly detects whether the host is in FIPS mode or not. This is not a bug in the existing code per se but a larger flaw in the overall implementation of the goal.

Ohai Version

16.8.1

Platform Version

RHEL 7 (at least)

Ohai Output

Note below that a host with no fips mode enablement gets the same result as a host with fips mode turned on:

See https://github.com/chef/ohai/blob/main/lib/ohai/plugins/fips.rb#L33 where checking OpenSSL::OPENSSL_FIPS is used to set a true/false flag indicating, theoretically, that fips mode is on (true) or off (false).

[m26560@el7fips-on ~]$ fipscheck
fips mode is on
[m26560@el7fips-on ~]$ /opt/chef/embedded/bin/irb
irb(main):001:0> require "openssl"
=> true
irb(main):002:0> OpenSSL::OPENSSL_FIPS
=> true
irb(main):003:0>
[m26560@el7fips-off ~]$ fipscheck
fips mode is off
[m26560@el7fips-off ~]$ /opt/chef/embedded/bin/irb
irb(main):001:0> require "openssl"
=> true
irb(main):002:0> OpenSSL::OPENSSL_FIPS
=> true
irb(main):003:0>
stanhu commented 2 years ago

I think https://github.com/chef/ohai/pull/1754 may explain why FIPS detection isn't working properly.

rjhornsby commented 1 year ago

running Ohai version 18.1.4, Rocky (RHEL) 8.8

1754 does provide some historical background and moves things in the right direction, but AFAICT, hasn't solved the underlying problem. On both windows and Linux (RHEL/Rocky specifically here), with FIPS enabled and acknowledged as such by chef when a chef client (v18.2.7 here) run starts up it says OpenSSL FIPS 140 mode enabled

I know FIPS to be enabled on Windows because of the registry setting, and on RHEL because the kernel argument fips=1 is present in /proc/cmdline, and fips-mode-setup --check says FIPS mode is enabled. However, the Ohai attribute reports it is not enabled on both platforms when you examine fips["kernel"]["enabled"]

It's a bit confusing because while the attribute's name seems to indicate that Ohai is looking at the kernel configuration, the underlying implementation[1] is querying OpenSSL.

To be fair to Ohai, technically the implementation is just passing the answer it gets from the OpenSSL gem: false, but it's unclear why OpenSSL is saying this. This is despite the earlier message from the beginning of the client run to the contrary.

It's almost as if Ohai says it's looking at the kernel, but is really querying openssl while the startup message says it is asking OpenSSL but getting its answer from the kernel config?

To complicate things further I believe (please correct me here) because FIPS "mode" is multiple things, the Linux kernel and openssl could be different. That is, setting aside the RHEL-specific fips-mode-setup helper tools, you could set fips=1 as a kernel argument enabling it in the kernel (ie this is part of mainline kernel 5.4 and later IIRC) and not have the SSL module activated.

[1] https://github.com/chef/ohai/blob/main/lib/ohai/plugins/fips.rb#L34

stanhu commented 1 year ago

RIght, this gets at the question, "What does it mean to be in FIPS mode?" It depends on what level you mean:

  1. Kernel: The Linux kernel must be enabled in FIPS mode (cat /proc/sys/crypto/fips_enabled returns 1).
  2. Crypto libraries: OpenSSL or whatever SSL library used on the system has to be FIPS-validated. [OpenSSL < v3 has a fips_mode](https://wiki.openssl.org/index.php/FIPS_mode()), which Ohai uses at the moment. I think OpenSSL v3 has removed this.
  3. Application: The application has to link against FIPS-enabled crypto libraries and not use its own crypto implementations (e.g. SHA-1, SHA-256). Chef make uses of the OpenSSL's implementation in FIPS mode.
rjhornsby commented 1 year ago

Thanks. That insight helps confirm my understanding of the layers of "what is FIPS mode?"

fips-enabled vs fips-validated further muddies the waters. For example, OpenSSL 3.0.8 is FIPS-validated, but 3.0.9 is not.

You can easily compile the openssl FIPS module and get it running, but it seems as if unless you're doing it against the 3.0.8 source, you might have FIPS enabled and functioning perfectly well but are not in technical compliance.

I honestly don't know how this works for the kernel. FIPS is one of those standards for which the "validated" seal of approval is time consuming, expensive and sometimes only applies to one specific version of a product. From my reading of it, many projects (including OpenSSL and the kernel) have historically refused or later only reluctantly decided to deal with it.

I think the best Ohai can do is cover the enabled part. From there it's a question of communication. What information should Ohai provide and how to do so clearly. Maybe something along these lines:

"fips": {
   "components_enabled": {
      "chef": ?
      "kernel": <checks /proc/sys/crypto/fips_enabled>
      "ssl": <checks the system ssl libraries, with appropriate handling of openssl 3.x and pre-3.x>
      ...other/future components...
   }
   "enabled": <logical AND of all components_enabled>
}

I'm also starting to question the current implementation of the Ohai FIPS plugin wondering if it really is looking at the system openssl as we expect, or if it is looking at the ssl libraries bundled with the chef client package? Maybe this goes back to the earlier question of what is chef doing when it starts up to see that FIPS is enabled and how is it making this determination compared to how Ohai is doing it presently.