Deploy Keylime server components

Establish the server-side infrastructure for continuous remote system integrity monitoring by deploying the Keylime verifier and registrar.

Deploy Keylime verifier from a package

Deploy the Keylime verifier from a package to establish the core integrity monitoring component. The verifier acts as the verification authority for target systems - agents.

Before you begin

  • You have root permissions and network connection to the system or systems on which you want to install Keylime components.
  • You have valid keys and certificates from your certificate authority.
  • If you use pull model attestation:
    • The verifier’s host has outbound access to all monitored agents on port 9002.
    • The verifier’s host is reachable on port 8881 by the tenant.
    • The verifier has both server and client certificates for mTLS.
  • If you use push model attestation:
    • The verifier’s host is reachable on port 8881 by all monitored agents and the tenant.
    • The verifier has a server certificate to prove its own identity to agents.
  • Optional: You have access to the databases where Keylime saves data from the verifier. You can use any of the following database management systems:
    • SQLite (default)
    • PostgreSQL
    • MySQL
    • MariaDB

About this task

The verifier is the most critical component in Keylime. It performs initial and periodic checks of system integrity to ensure that monitored agents remain in a trusted state. In the pull model, the verifier also supports bootstrapping cryptographic keys and secure payloads with the agent.

The behavior of the Keylime verifier depends on the selected attestation model:

Pull model
The verifier actively polls the agent. It initiates an outbound connection and waits for a response before evaluating the measurements.
Push model
The verifier acts as a listener for inbound connections from agents. It accepts the incoming data, acknowledges it immediately, and evaluates the measurements independently. This decoupled approach allows the verifier to handle a significantly higher volume of requests without keeping connections open while processing the data.
Important

To maintain the chain of trust, keep the system that runs the verifier secure and under your control.

You can install the verifier on a separate system or on the same system as the Keylime registrar, depending on your requirements. Running the verifier and registrar on separate systems provides better performance.

Note

To keep the configuration files organized within the drop-in directories, use file names with a two-digit number prefix, for example /etc/keylime/verifier.conf.d/00-verifier-ip.conf. The configuration processing reads the files inside the drop-in directory in lexicographic order and sets each option to the last value it reads.

Procedure

  1. Install the Keylime verifier:
    # dnf install keylime-verifier
  2. Define the IP address and port of verifier by creating a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-verifier-ip.conf, with the following content:
    [verifier]
    ip = <verifier_IP_address>
    • Replace <verifier_IP_address> with the verifier’s IP address. Alternatively, use ip = * or ip = 0.0.0.0 to bind the verifier to all available IP addresses.
    • Optionally, you can also change the verifier’s port from the default value 8881 by using the port option.
  3. Optional: Configure the verifier’s database. The default configuration uses an SQLite database in the verifier’s /var/lib/keylime/cv_data.sqlite/ directory. You can define a different database by creating a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-db-url.conf, with the following content:
    [verifier]
    database_url = <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties>

    Replace <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties> with the URL of the database, for example, postgresql://verifier:UQ?nRNY9g7GZzN7@198.51.100.1/verifierdb.

    Ensure that the credentials you use provide the permissions for Keylime to create the database structure.

  4. Add certificates and keys to the verifier. You can either let Keylime generate them, or use existing keys and certificates:
    • With the default tls_dir = generate option, Keylime generates new certificates for the verifier, registrar, and tenant in the /var/lib/keylime/cv_ca/ directory.
    • To load existing keys and certificates in the configuration, define their location in the verifier configuration. The certificates must be accessible by the keylime user, under which the Keylime services are running.

      Create a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-keys-and-certs.conf, with the following content:

      [verifier]
      tls_dir = /var/lib/keylime/cv_ca
      server_key = </path/to/server_key>
      server_key_password = <passphrase1>
      server_cert = </path/to/server_cert>
      trusted_client_ca = ['</path/to/ca/cert1>', '</path/to/ca/cert2>']
      client_key = </path/to/client_key>
      client_key_password = <passphrase2>
      client_cert = </path/to/client_cert>
      trusted_server_ca = ['</path/to/ca/cert3>', '</path/to/ca/cert4>']
      Note

      Use absolute paths to define key and certificate locations. Alternatively, relative paths are resolved from the directory defined in the tls_dir option.

  5. For push model only: Configure the verifier for the push model attestation.
    Note

    The mode setting affects all agents on the verifier. A verifier in push mode expects agents to submit attestation data, it does not poll agents. A single verifier cannot operate in both modes simultaneously.

    You can either use a drop-in configuration file, set the mode in the verifier’s configuration file, or use an environment variable:

    • Set the verifier’s mode option by creating a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-push-mode.conf, with the following content:
      [verifier]
      mode = push
    • Set the verifier’s mode option to push in the ./etc/keylime/verifier.conf file:
      [verifier]
      mode = push
    • To configure the verifier by using environment variable, inject the variable directly into the systemd service environment.

      Open the systemd configuration editor for the verifier service:

      # systemctl edit keylime_verifier

      Add the variable to the Service environment:

      [Service]
      Environment="KEYLIME_VERIFIER_MODE=push"

      After you save the changes, the systemd service automatically updates and reloads the modified verifier service profile.

  6. Open the port in firewall:
    # firewall-cmd --add-port 8881/tcp
    # firewall-cmd --runtime-to-permanent

    If you use a different port, replace 8881 with the port number defined in the .conf file.

  7. Start the verifier service:
    # systemctl enable --now keylime_verifier
    Note

    In the default configuration, start the keylime_verifier before starting the keylime_registrar service because the verifier creates the CA and certificates for the other Keylime components. This order is not necessary when you use custom certificates.

Results

  1. Check that the keylime_verifier service is active and running:
    # systemctl status keylime_verifier
    keylime_verifier.service - The Keylime verifier
         Loaded: loaded (/usr/lib/systemd/system/keylime_verifier.service; disabled; vendor preset: disabled)
         Active: active (running) since Wed 2022-11-09 10:10:08 EST; 1min 45s ago
  2. For push model only: Check that the verifier is configured for push model attestation:
    # journalctl -u keylime_verifier -b
    ...
    keylime.verifier - INFO - Starting Keylime verifier in PUSH mode...
    ...

What to do next

Deploy Keylime verifier as a container

Configure the Keylime verifier as a container instead of the RPM method, without any binaries or packages on the host. The container deployment provides better isolation, modularity, and reproducibility of Keylime components.

Before you begin

  • The podman package and its dependencies are installed on the system.
  • The user that executes podman commands has read access to the local configuration files and certificates that will be mounted into the container.
  • If you use pull model attestation:
    • The verifier’s host has outbound access to all monitored agents on port 9002.
    • The verifier’s host is reachable on port 8881 by the tenant.
    • The verifier has both server and client certificates for mTLS.
  • If you use push model attestation:
    • The verifier’s host is reachable on port 8881 by all monitored agents and the tenant.
    • The verifier has a server certificate to prove its own identity to agents.
  • Optional: You have access to a database where Keylime saves data from the verifier. You can use any of the following database management systems:
    • SQLite (default)
    • PostgreSQL
    • MySQL
    • MariaDB
  • You have valid keys and certificates from your certificate authority.

About this task

The Keylime verifier performs initial and periodic checks of system integrity to ensure monitored agents remain in a trusted state. In the pull model, the verifier also supports bootstrapping cryptographic keys and delivering secure payloads to the agent.

The behavior of the Keylime verifier depends on the selected attestation model:

The pull model
The verifier actively polls the agent. It initiates an outbound connection and waits for a response before evaluating the measurements.
The push model
The verifier acts as a listener for inbound connections from agents. It accepts the incoming data, acknowledges it immediately, and evaluates the measurements independently. This decoupled approach allows the verifier to handle a significantly higher volume of requests without keeping connections open while processing the data.

After you start the container, the Keylime verifier is deployed with default configuration files. You can customize the configuration by using one or more of following methods:

  • Mounting the host’s directories that contain the configuration files to the container.
  • Modifying the environment variables directly on the container. Modifying the environment variables overrides the values from the configuration files.

Procedure

  1. Optional: Install the keylime-verifier package to access the configuration files. You can configure the container without this package, but it might be easier to modify the configuration files provided with the package.
    # dnf install keylime-verifier
  2. Bind the verifier to all available IP addresses by creating a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-verifier-ip.conf, with the following content:
    [verifier]
    ip = *
    • Optionally, you can also change the verifier’s port from the default value 8881 by using the port option.
  3. Optional: Configure the verifier’s database. The default configuration uses an SQLite database in the verifier’s /var/lib/keylime/cv_data.sqlite/ directory. You can define a different database by creating a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-db-url.conf, with the following content:
    [verifier]
    database_url = <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties>

    Replace <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties> with the URL of the database, for example, postgresql://verifier:UQ?nRNY9g7GZzN7@198.51.100.1/verifierdb.

    Ensure that the credentials you use have the permissions for Keylime to create the database structure.

  4. Add certificates and keys to the verifier. You can either let Keylime generate them, or use existing keys and certificates:
    • With the default tls_dir = generate option, Keylime generates new certificates for the verifier, registrar, and tenant in the /var/lib/keylime/cv_ca/ directory.
    • To load existing keys and certificates in the configuration, define their location in the verifier configuration. The certificates must be accessible by the keylime user, under which the Keylime processes are running.

      Create a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-keys-and-certs.conf, with the following content:

      [verifier]
      tls_dir = /var/lib/keylime/cv_ca
      server_key = </path/to/server_key>
      server_cert = </path/to/server_cert>
      trusted_client_ca = ['</path/to/ca/cert1>', '</path/to/ca/cert2>']
      client_key = </path/to/client_key>
      client_cert = </path/to/client_cert>
      trusted_server_ca = ['</path/to/ca/cert3>', '</path/to/ca/cert4>']
      Note

      Use absolute paths to define key and certificate locations. Alternatively, relative paths are resolved from the directory defined in the tls_dir option.

  5. For the push model only: Configure the verifier for the push model attestation.
    Note

    The mode setting affects all agents on the verifier. A verifier in push mode expects agents to submit attestation data, it does not poll agents. A single verifier cannot operate in both modes simultaneously.

    You can either use a drop-in configuration file, or set the mode in the verifier’s configuration file:

    • Set the verifier’s mode option by creating a new .conf file in the /etc/keylime/verifier.conf.d/ directory, for example, /etc/keylime/verifier.conf.d/00-push-mode.conf, with the following content:
      [verifier]
      mode = push
    • Set the verifier’s mode option to push in the ./etc/keylime/verifier.conf file:
      [verifier]
      mode = push
  6. Open the port in firewall:
    # firewall-cmd --add-port 8881/tcp
    # firewall-cmd --runtime-to-permanent

    If you use a different port, replace 8881 with the port number defined in the .conf file.

    For the push model, the port must be open to the network segments where the agents are located.

  7. Run the container:
    • In the push model:
      $ podman run --name keylime-verifier \
        -p 8881:8881 \
        -v /etc/keylime/verifier.conf.d:/etc/keylime/verifier.conf.d:Z \
        -v /var/lib/keylime/cv_ca:/var/lib/keylime/cv_ca:Z \
        -d \
        -e KEYLIME_VERIFIER_MODE=push \
        registry.redhat.io/rhel10/keylime-verifier
      • The -p option opens the default port 8881 on the host and on the container.
      • The -v option creates a bind mount for the directory to the container.
        • With the Z option, Podman marks the content with a private unshared label. This means only the current container can use the private volume.
      • The -d option runs the container detached and in the background.
      • You can override configuration options with environment variables by using the option -e KEYLIME_VERIFIER_<ENVIRONMENT_VARIABLE>=<value>. To modify additional options, insert the -e option separately for each environment variable. For a complete list of environment variables and their default values, see Keylime configuration.
    • In the pull model:
      $ podman run --name keylime-verifier \
        -p 8881:8881 \
        -v /etc/keylime/verifier.conf.d:/etc/keylime/verifier.conf.d:Z \
        -v /var/lib/keylime/cv_ca:/var/lib/keylime/cv_ca:Z \
        -d \
        -e KEYLIME_VERIFIER_SERVER_KEY_PASSWORD=<passphrase1> \
        -e KEYLIME_VERIFIER_CLIENT_KEY_PASSWORD=<passphrase2> \
        registry.redhat.io/rhel10/keylime-verifier
      • The -p option opens the default port 8881 on the host and on the container.
      • The -v option creates a bind mount for the directory to the container.
        • With the Z option, Podman marks the content with a private unshared label. This means only the current container can use the private volume.
      • The -d option runs the container detached and in the background.
      • The option -e KEYLIME_VERIFIER_SERVER_KEY_PASSWORD=<passphrase1> defines the server key passphrase.
      • The option -e KEYLIME_VERIFIER_CLIENT_KEY_PASSWORD=<passphrase2> defines the client key passphrase.
      • You can override configuration options with environment variables by using the option -e KEYLIME_VERIFIER_<ENVIRONMENT_VARIABLE>=<value>. To modify additional options, insert the -e option separately for each environment variable. For a complete list of environment variables and their default values, see Keylime configuration.

Results

  • Check that the container is running:
    $ podman ps -a
    CONTAINER ID  IMAGE                                                     COMMAND           CREATED         STATUS         PORTS                   NAMES
    80b6b9dbf57c  registry.redhat.io/rhel10/keylime-verifier:latest  keylime_verifier  14 seconds ago  Up 14 seconds  0.0.0.0:8881->8881/tcp  keylime-verifier
  • For the push model only: Check that the verifier is configured for the push model attestation:
    # podman logs keylime-verifier | grep -i "push mode"
    ...
    keylime.verifier - INFO - Starting Keylime verifier in PUSH mode...
    ...

What to do next

Deploy Keylime registrar from a package

Deploy the Keylime registrar from a package to securely store and manage identity and key information about agents. Keeping the registrar secure helps maintain the chain of trust.

Before you begin

  • You have network access to the systems where the Keylime verifier is installed and running. For more information, see

Deploy Keylime verifier from a package.

  • You have root permissions and network connection to the system or systems on which you want to install Keylime components.
  • You have access to the database where Keylime saves data from the registrar. You can use any of the following database management systems:
    • SQLite (default)
    • PostgreSQL
    • MySQL
    • MariaDB
  • You have valid keys and certificates from your certificate authority.

About this task

The registrar is the Keylime component that contains a database of all agents, and it hosts the public keys of the TPM vendors. After the registrar’s HTTPS service accepts trusted platform module (TPM) public keys, it presents an interface to obtain these public keys for checking quotes.

Important

To maintain the chain of trust, keep the system that runs the registrar secure and under your control.

You can install the registrar on a separate system or on the same system as the Keylime verifier, depending on your requirements. Running the verifier and registrar on separate systems provides better performance.

Note

To keep the configuration files organized within the drop-in directories, use file names with a two-digit number prefix, for example /etc/keylime/registrar.conf.d/00-registrar-ip.conf. The configuration processing reads the files inside the drop-in directory in lexicographic order and sets each option to the last value it reads.

Procedure

  1. Install the Keylime registrar:
    # dnf install keylime-registrar
  2. Define the IP address and port of the registrar by creating a new .conf file in the /etc/keylime/registrar.conf.d/ directory, for example, /etc/keylime/registrar.conf.d/00-registrar-ip.conf, with the following content:
    [registrar]
    ip = <registrar_IP_address>
    • Replace <registrar_IP_address> with the registrar’s IP address. Alternatively, use ip = * or ip = 0.0.0.0 to bind the registrar to all available IP addresses.
    • Optionally, change the port to which the Keylime agents connect by using the port option. The default value is 8890.
    • Optionally, change the TLS port to which the Keylime verifier and tenant connect by using the tls_port option. The default value is 8891.
  3. Optional: Configure the registrar’s database for the list of agents. The default configuration uses an SQLite database in the registrar’s /var/lib/keylime/reg_data.sqlite directory. You can create a new .conf file in the /etc/keylime/registrar.conf.d/ directory, for example, /etc/keylime/registrar.conf.d/00-db-url.conf, with the following content:
    [registrar]
    database_url = <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties>

    Replace <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties> with the URL of the database, for example, postgresql://registrar:EKYYX-bqY2?#raXm@198.51.100.1/registrardb.

    Ensure that the credentials you use have the permissions for Keylime to create the database structure.

  4. Add certificates and keys to the registrar:
    • You can use the default configuration and load the keys and certificates to the /var/lib/keylime/reg_ca/ directory.
    • Alternatively, you can define the location of the keys and certificates in the configuration. Create a new .conf file in the /etc/keylime/registrar.conf.d/ directory, for example, /etc/keylime/registrar.conf.d/00-keys-and-certs.conf, with the following content:
      [registrar]
      tls_dir = /var/lib/keylime/reg_ca
      server_key = </path/to/server_key>
      server_key_password = <passphrase1>
      server_cert = </path/to/server_cert>
      trusted_client_ca = ['</path/to/ca/cert1>', '</path/to/ca/cert2>']
      Note

      Use absolute paths to define key and certificate locations. Alternatively, you can define a directory in the tls_dir option and use paths relative to that directory.

  5. Open the ports in firewall:
    # firewall-cmd --add-port 8890/tcp --add-port 8891/tcp
    # firewall-cmd --runtime-to-permanent

    If you use a different port, replace 8890 or 8891 with the port number defined in the .conf file.

  6. Start the keylime_registrar service:
    # systemctl enable --now keylime_registrar
    Note

    In the default configuration, start the keylime_verifier before starting the keylime_registrar service because the verifier creates the CA and certificates for the other Keylime components. This order is not necessary when you use custom certificates.

Results

  • Check that the keylime_registrar service is active and running:
    # systemctl status keylime_registrar
    ● keylime_registrar.service - The Keylime registrar service
         Loaded: loaded (/usr/lib/systemd/system/keylime_registrar.service; disabled; vendor preset: disabled)
         Active: active (running) since Wed 2022-11-09 10:10:17 EST; 1min 42s ago
    ...

What to do next

Deploy Keylime registrar as a container

Configure the Keylime registrar as a container instead of the RPM method, without any binaries or packages on the host. The container deployment provides better isolation, modularity, and reproducibility of Keylime components.

Before you begin

  • The podman package and its dependencies are installed on the system.
  • Optional: You have access to a database where Keylime saves data from the registrar. You can use any of the following database management systems:
    • SQLite (default)
    • PostgreSQL
    • MySQL
    • MariaDB
  • You have valid keys and certificates from your certificate authority.

About this task

The registrar is the Keylime component that contains a database of all agents, and it hosts the public keys of the trusted platform module (TPM) vendors. After the registrar’s HTTPS service accepts TPM public keys, it presents an interface to obtain these public keys for checking quotes.

After you start the container, the Keylime registrar is deployed with default configuration files. You can customize the configuration by using one or more of following methods:

  • Mounting the host’s directories that contain the configuration files to the container. This is available in all versions of RHEL 9.
  • Modifying the environment variables directly on the container. This is available in RHEL 9.3 and later versions. Modifying the environment variables overrides the values from the configuration files.

Procedure

  1. Optional: Install the keylime-registrar package to access the configuration files. You can configure the container without this package, but it might be easier to modify the configuration files provided with the package.
    # dnf install keylime-registrar
  2. Bind the registrar to all available IP addresses by creating a new .conf file in the /etc/keylime/registrar.conf.d/ directory, for example, /etc/keylime/registrar.conf.d/00-registrar-ip.conf, with the following content:
    [registrar]
    ip = *
    • Optionally, change the port to which the Keylime agents connect by using the port option. The default value is 8890.
    • Optionally, change the TLS port to which the Keylime tenant connects by using the tls_port option. The default value is 8891.
  3. Optional: Configure the registrar’s database for the list of agents. The default configuration uses an SQLite database in the registrar’s /var/lib/keylime/reg_data.sqlite directory. You can create a new .conf file in the /etc/keylime/registrar.conf.d/ directory, for example, /etc/keylime/registrar.conf.d/00-db-url.conf, with the following content:
    [registrar]
    database_url = <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties>

    Replace <protocol>://<name>:<password>@<ip_address_or_hostname>/<properties> with the URL of the database, for example, postgresql://registrar:EKYYX-bqY2?#raXm@198.51.100.1/registrardb.

    Ensure that the credentials you use have the permissions for Keylime to create the database structure.

  4. Add certificates and keys to the registrar:
    • You can use the default configuration and load the keys and certificates to the /var/lib/keylime/reg_ca/ directory.
    • Alternatively, you can define the location of the keys and certificates in the configuration. Create a new .conf file in the /etc/keylime/registrar.conf.d/ directory, for example, /etc/keylime/registrar.conf.d/00-keys-and-certs.conf, with the following content:
      [registrar]
      tls_dir = /var/lib/keylime/reg_ca
      server_key = </path/to/server_key>
      server_cert = </path/to/server_cert>
      trusted_client_ca = ['</path/to/ca/cert1>', '</path/to/ca/cert2>']
      Note

      Use absolute paths to define key and certificate locations. Alternatively, you can define a directory in the tls_dir option and use paths relative to that directory.

  5. Open the ports in firewall:
    # firewall-cmd --add-port 8890/tcp --add-port 8891/tcp
    # firewall-cmd --runtime-to-permanent

    If you use a different port, replace 8890 or 8891 with the port number defined in the .conf file.

  6. Run the container:
    $ podman run --name keylime-registrar \
      -p 8890:8890 \
      -p 8891:8891 \
      -v /etc/keylime/registrar.conf.d:/etc/keylime/registrar.conf.d:Z \
      -v /var/lib/keylime/reg_ca:/var/lib/keylime/reg_ca:Z \
      -d \
      -e KEYLIME_REGISTRAR_SERVER_KEY_PASSWORD=<passphrase1> \
      registry.access.redhat.com/rhel9/keylime-registrar
    • The -p option opens the default ports 8890 and 8881 on the host and on the container.
    • The -v option creates a bind mount for the directory to the container.
      • With the Z option, Podman marks the content with a private unshared label. This means only the current container can use the private volume.
    • The -d option runs the container detached and in the background.
    • The option -e KEYLIME_VERIFIER_SERVER_KEY_PASSWORD=<passphrase1> defines the server key passphrase.
    • You can override configuration options with environment variables by using the option -e KEYLIME_REGISTRAR__<ENVIRONMENT_VARIABLE>=<value>. To modify additional options, insert the -e option separately for each environment variable. For a complete list of environment variables and their default values, see Keylime configuration.

Results

  • Check that the container is running:
    $ podman ps -a
    CONTAINER ID  IMAGE                               COMMAND            CREATED             STATUS             PORTS                                           NAMES
    07d4b4bff1b6  localhost/keylime-registrar:latest  keylime_registrar  12 seconds ago      Up 12 seconds      0.0.0.0:8881->8881/tcp, 0.0.0.0:8891->8891/tcp  keylime-registrar

What to do next