Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve configuration and change format to TOML #449

Merged
merged 9 commits into from
Sep 21, 2022

Conversation

ansasaki
Copy link
Contributor

@ansasaki ansasaki commented Sep 19, 2022

This introduces several improvements to the agent configuration.

  • The file format is modified from INI style files to TOML formatted
    files.
  • The configuration options names were modified to follow the
    enhancement proposal:
  • The configuration is constructed using an hierarchical organization
    following the order:
    • The default hardcoded values are loaded
    • If a configuration file is found in /usr/etc/keylime/agent.conf, it
      is loaded and any option set overrides the default values
    • Load configuration snippets from /usr/etc/keylime/agent.conf.d/*,
      overriding the previous values
    • Load the configuration from /etc/keylime/agent.conf, overriding
      previous values
    • Load configuration snippets from /etc/keylime/agent.conf.d/*,
      overriding previous values
    • Finally any configuration option can be overriden via environment
      variable, by using the 'KEYLIME_AGENT_' prefix. For example,
      KEYLIME_AGENT_PORT=9003 will override the 'port' option from the
      'agent' section with the value '9003'.

It is possible to override all file sources with a single file by setting the KEYLIME_AGENT_CONFIG environment variable. If it is set, the configuration files and snippets are ignored and all options are loaded from the file pointed by KEYLIME_AGENT_CONFIG. The environment variable overrides still apply, meaning it is still possible to override the options from the file pointed by KEYLIME_AGENT_CONFIG using the environment variables with the KEYLIME_AGENT_ prefix.

This was implemented using new dependency crates: config and glob.

Other changes:

  • Added support to using existing key (optionally protected by a password) and certificate
  • Add the EK public key hash to the stored TPM data (AK) to allow verifying if the TPM where the data is being loaded is the same that generated the data (this is to avoid errors as it is not possible to load the data generated by a TPM using another TPM)

Follow the naming specified in the configuration enhancement:

https://github.com/keylime/enhancements/blob/master/72_config_and_simplify_tls.md

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
Keep only the data path as part of the configuration structure. Then
open and load the data when needed.

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
Separate the key and certificate from the Agent Data and store in
separate files.

Add the configuration options 'server_key' and 'server_cert' to allow
the user to use existing key and certificate.

If the files set to 'server_key' or 'server_cert' don't exist, new files
are created to store the generated key or certificate.  Otherwise the
existing files will not be overwritten.

This also unify the handling of file paths in the configuration file
for the files stored in the 'keylime_dir' by introducing the
config_get_file_path() function with the following behavior:

- If the option is set as "default" or left empty, the default value is
  used
- If the option is not an absolute path, it is treated as relative from
  the directory set in the 'keylime_dir' configuration option
- If the option is set with an absolute path, it is used without change

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
Include as part of the stored Agent Data the hash of the public EK of
the TPM that generated the AK.

Before loading the AK, check if the current TPM is the same TPM that
generated the information to avoid loading errors.

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
@ueno
Copy link
Contributor

ueno commented Sep 19, 2022

If a configuration file is found in /usr/etc/keylime-agent.conf, it
is loaded and any option set overrides the default values

Perhaps I should have mentioned it earlier but I wonder if /usr/etc is a standard place to install such configuration. FHS doesn't specify it and on my systems: /usr/etc is only owned by npm on Fedora, and it does not exist on Debian.

Add the configuration option server_key_password to allow setting a
password to be used to encrypt the generated key when writing to a file
and to decrypt the key when loading from a file.

If the server_key_password is set as empty, the key is assumed to be
unencrypted.

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
@ansasaki
Copy link
Contributor Author

If a configuration file is found in /usr/etc/keylime-agent.conf, it
is loaded and any option set overrides the default values

Perhaps I should have mentioned it earlier but I wonder if /usr/etc is a standard place to install such configuration. FHS doesn't specify it and on my systems: /usr/etc is only owned by npm on Fedora, and it does not exist on Debian.

I can drop this. I just added this path to make it similar to the python configuration.

@ueno
Copy link
Contributor

ueno commented Sep 19, 2022

If a configuration file is found in /usr/etc/keylime-agent.conf, it
is loaded and any option set overrides the default values

Perhaps I should have mentioned it earlier but I wonder if /usr/etc is a standard place to install such configuration. FHS doesn't specify it and on my systems: /usr/etc is only owned by npm on Fedora, and it does not exist on Debian.

I can drop this. I just added this path to make it similar to the python configuration.

Was there any discussion on this on the Python side? If not and it's not too late, maybe good to revisit; I would suggest /usr/share instead. See also: https://docs.fedoraproject.org/en-US/packaging-guidelines/#_filesystem_layout

@ansasaki
Copy link
Contributor Author

ansasaki commented Sep 19, 2022

If a configuration file is found in /usr/etc/keylime-agent.conf, it
is loaded and any option set overrides the default values

Perhaps I should have mentioned it earlier but I wonder if /usr/etc is a standard place to install such configuration. FHS doesn't specify it and on my systems: /usr/etc is only owned by npm on Fedora, and it does not exist on Debian.

I can drop this. I just added this path to make it similar to the python configuration.

Was there any discussion on this on the Python side? If not and it's not too late, maybe good to revisit; I would suggest /usr/share instead. See also: https://docs.fedoraproject.org/en-US/packaging-guidelines/#_filesystem_layout

I think the main supporter of using the /usr/etc/ was @aplanas who can give the reasoning for it.

@ansasaki ansasaki force-pushed the toml branch 2 times, most recently from fcbd834 to b544401 Compare September 19, 2022 23:41
@aplanas
Copy link
Contributor

aplanas commented Sep 20, 2022

FHS doesn't specify it and on my systems

Depends on the source. There is a tendency of using it, that is also referenced here:

https://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/usr.html

I think the main supporter of using the /usr/etc/ was @aplanas who can give the reasoning for it.

I hope that I am not alone here!

/usr/etc it is used to store sane defaults configuration for services. This is provided by the distributor and are not mean to be changed by the user nor the admin, for that it is /etc.

Ideally the service will know how to merge the snipped in /etc together with the version stored in /usr/etc, merging both versions (with priority on the one provided by the admin in /etc). The benefits are:

  • Once a package gets updated, the new /usr/etc will be updated too (no rpmsave, rpmnew). So if there is a new option or an old one with a safest value, it will be updated with the package
  • If the user removes the version in /etc, the service will take the default values

A longer explanation, with more examples can be found here: https://kubic.opensuse.org/blog/2019-12-05-usr-etc/

For doing the merge in services that do not support it by default, we are using libeconf, and doing upstream commits to support it.

@ansasaki
Copy link
Contributor Author

/packit test

pub static DEFAULT_KEYLIME_DIR: &str = "/var/lib/keylime";
pub static DEFAULT_SERVER_KEY: &str = "server-private.pem";
pub static DEFAULT_SERVER_CERT: &str = "server-cert.crt";
pub static DEFAULT_SERVER_KEY_PASSWORD: &str = "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be None ...?

enc_keyname: DEFAULT_ENC_KEYNAME.to_string(),
extract_payload_zip: DEFAULT_EXTRACT_PAYLOAD_ZIP,
server_key: Some("default".to_string()),
server_key_password: Some(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... because this put Some("") (there is a password, that is the empty string), that is different from None (no password was provided)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ansasaki
Copy link
Contributor Author

/packit retest-failed

@ansasaki
Copy link
Contributor Author

/packit test

This introduces several improvements to the agent configuration.

- The file format is modified from INI style files to TOML formatted
  files.
- The configuration is constructed using an hierarchical organization
  following the order:
  - The default hardcoded values are loaded
  - If a configuration file is found in /usr/etc/keylime-agent.conf, it
    is loaded and any option set overrides the default values
  - Load configuration snippets from /usr/etc/keylime-agent.conf.d/*,
    overriding the previous values
  - Load the configuration from /etc/keylime-agent.conf, overriding
    previous values
  - Load configuration snippets from /etc/keylime-agent.conf.d/*,
    overriding previous values
  - Finally any configuration option can be overriden via environment
    variable, by using the 'KEYLIME_AGENT_' prefix. For example,
    KEYLIME_AGENT_PORT=9003 will override the 'port' option from the
    'agent' section with the value '9003'.

This was introduced by using an added dependency, the 'config' crate
using the 'toml' feature for the toml file format.

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
Add back the support for overriding the 'keylime_dir' option by setting
the 'KEYLIME_DIR' environment variable.

Note that it is also possible to override the 'keylime_dir' option by
setting the 'KEYLIME_AGENT_KEYLIME_DIR' environment variable, although
'KEYLIME_DIR' has priority.

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
This is not currently used, but will be important in future to check
configuration file compatibility and upgrades.

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
@ansasaki
Copy link
Contributor Author

@lkatalin @ueno @aplanas I think the only pending decision here is about using /usr/etc or not.

Please let me know if there are other points to be modified.

Before merging, we need to drop the last commit which temporarily changes the tests repository.

@ashcrow
Copy link
Contributor

ashcrow commented Sep 20, 2022

I think the only pending decision here is about using /usr/etc or not.

Quick reminder that /usr is read-only on CoreOS.

@lkatalin
Copy link
Contributor

I did a first pass and it seemed good to me, I can do another one shortly.

@aplanas
Copy link
Contributor

aplanas commented Sep 20, 2022

the only pending decision here is about using /usr/etc or not

My vote is for /usr/etc. We can add /usr/lib (like systemd) or /usr/share as new search paths later if there are other standards.

Quick reminder that /usr is read-only on CoreOS.

Exactly. /usr/etc will be deployed with the image, never edited by the user (that should edit /etc)

The python components expect the configuration files to be in
/etc/keylime/*.conf and the configuration snippets to be in
/etc/keylime/*.conf.d

This patch modifies the paths where the configuration files are searched
to align with the python components. In the case, the agent
configuration will be installed in /etc/keylime/agent.conf and the
snippets are searched in /etc/keylime/agent.conf.d/

Signed-off-by: Anderson Toshiyuki Sasaki <[email protected]>
@ansasaki
Copy link
Contributor Author

/packit test

1 similar comment
@ansasaki
Copy link
Contributor Author

/packit test

@ansasaki
Copy link
Contributor Author

/packit retest-failed

Copy link
Contributor

@lkatalin lkatalin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM and I appreciate that the config locations will match the Python version. Hopefully this will help with the CI.

@ueno
Copy link
Contributor

ueno commented Sep 21, 2022

@aplanas thanks for the detailed explanation!

A longer explanation, with more examples can be found here: https://kubic.opensuse.org/blog/2019-12-05-usr-etc/

For doing the merge in services that do not support it by default, we are using libeconf, and doing upstream commits to support it.

I wasn't aware of the UsrEtc effort. It makes sense from the package update point of view, though other distributions currently don't seem to catch up; as mentioned in the link to the Fedora packaging guideline:

Fedora follows the Filesystem Hierarchy Standard with regards to filesystem layout, with exceptions noted below. The FHS defines where files should be placed on the system.
[...]
Fedora does not allow new directories directly under / or /usr without FPC approval.

That said, I guess it shouldn't be a problem as long as the Fedora package doesn't ship any files under /usr/etc.

@ansasaki
Copy link
Contributor Author

Fedora follows the Filesystem Hierarchy Standard with regards to filesystem layout, with exceptions noted below. The FHS defines where files should be placed on the system.
[...]
Fedora does not allow new directories directly under / or /usr without FPC approval.

That said, I guess it shouldn't be a problem as long as the Fedora package doesn't ship any files under /usr/etc.

I'll make sure the Fedora package doesn't ship any files there.

@ansasaki ansasaki merged commit 9dfb597 into keylime:master Sep 21, 2022
@kkaarreell
Copy link
Contributor

Maybe the location could be configurable at build time, so that config templates could be shipped also to a different location (and used from there).

@aplanas
Copy link
Contributor

aplanas commented Sep 21, 2022

Maybe the location could be configurable at build time

That is a good idea

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants