Error uploading openscap scan to the foreman server with foreman_scap_client

Problem:
I’m trying to add an openscap scan/policy through puppet to the machine by using the module foreman_scap_client. When i assign this with a policy id that doesn’t exist in the foreman web interface it give me a 422 error.

Uploading results to https://openscapsmartproxy:8443/compliance/arf/1
Report not uploaded from proxy to Foreman server, cause: 422 "Unprocessable Entity"

This error is throw after manually executing
foreman_scap_client 1

The following lines are outputted in foreman production.log

2020-09-09T14:05:58 [I|app|] Started POST "/api/v2/compliance/arf_reports/openscapsmartproxy/1/1599653154" for "ip here" at 2020-09-09 14:05:58 +0200
2020-09-09T14:06:00 [I|app|4fdf7] Processing by Api::V2::Compliance::ArfReportsController#create as JSON
2020-09-09T14:06:00 [I|app|4fdf7]   Parameters: {"logs"=>"[FILTERED]", "digest"=>"1150d4fc2468ed374475b13851961aac3c86ed39b13b8d1a62bbebf71467cbdb", "metrics"=>{"passed"=>16, "failed"=>33, "othered"=>2}, "openscap_proxy_name"=>nil, "openscap_proxy_url"=>nil, "apiv"=>"v2", "cname"=>"openscapsmartproxy", "policy_id"=>"1", "date"=>"1599653154", "arf_report"=>{"logs"=>"[FILTERED]", "digest"=>"1150d4fc2468ed374475b13851961aac3c86ed39b13b8d1a62bbebf71467cbdb", "metrics"=>{"passed"=>16, "failed"=>33, "othered"=>2}, "openscap_proxy_name"=>nil, "openscap_proxy_url"=>nil}}
2020-09-09T14:06:01 [E|app|4fdf7] Policy with id 1 not found.
2020-09-09T14:06:01 [I|app|4fdf7] Filter chain halted as :find_resources_before_create rendered or redirected
2020-09-09T14:06:01 [I|app|4fdf7] Completed 422 Unprocessable Entity in 1544ms (Views: 0.3ms | ActiveRecord: 124.8ms)

Expected outcome:
For the scan to be either uploaded to the server without errors or that it would create the policy with that id in foreman
Foreman and Proxy versions:
foreman server

  - foreman:
      version: 1.20.3-1.el7
  - foreman-debug:
      version: 1.20.3-1.el7
  - foreman-ec2:
      version: 1.20.3-1.el7
  - foreman-openstack:
      version: 1.20.3-1.el7
  - foreman-postgresql:
      version: 1.20.3-1.el7
  - foreman-selinux:
      version: 1.20.3-1.el7
  - rubygem-foreman_scap_client:
      version: 0.4.0-1.el7
  - tfm-rubygem-foreman_openscap:
      version: 0.11.5-1.fm1_20.el7
  - tfm-rubygem-foreman_remote_execution:
      version: 1.6.7-1.fm1_20.el7
  - tfm-rubygem-foreman_remote_execution_core:
      version: 1.1.4-1.el7
  - tfm-rubygem-foreman-tasks:
      version: 0.14.1-1.fm1_20.el7
  - tfm-rubygem-foreman-tasks-core:
      version: 0.2.5-2.fm1_20.el7
  - openscap:
      version: 1.2.17-9.el7
  - openscap-scanner:
      version: 1.2.17-9.el7
  - tfm-rubygem-foreman_openscap:
      version: 0.11.5-1.fm1_20.el7

foreman smart proxy with openscap

  - foreman-debug:
      version: 1.20.3-1.el7
  - foreman-proxy:
      version: 1.20.3-1.el7
  - rubygem-foreman_scap_client:
      version: 0.4.0-1.el7
  - openscap:
      version: 1.2.17-9.el7
  - openscap-scanner:
      version: 1.2.17-9.el7
  - rubygem-openscap:
      version: 0.4.7-1.el7
  - rubygem-smart_proxy_openscap:
      version: 0.7.1-1.el7

Distribution and version:
CentOS Linux release 7.8.2003 (Core)
Other relevant data:

The puppet file used to set the scan up:

class profile_foreman::proxy::openscap::profile {
  class { foreman_scap_client:
    server           => 'openscapsmartproxy',
    port             => 8443,
    policies         => [{
      "id"                      => 1,
      "hour"                    => "*",
      "minute"                  => "0",
      "month"                   => "*",
      "monthday"                => "*",
      "weekday"                 => "*",
      "profile_id"              => 'xccdf_org.ssgproject.content_profile_standard',
      "content_path"            => '/var/lib/openscap/content/test.xml',
      "download_path"           => '/compliance/policies/1/content/test.xml',
      "tailoring_path"          => '',
      "tailoring_download_path" => ""
    }]
  }
}

I created this based on the example given here: https://github.com/theforeman/puppet-foreman_scap_client#sample-usage

When i add a policy through the foreman web interface it is able to install the scanning software and execute the scan and send the report back but i want to be able to set this up without manual intervention.
Also when i changed the id to “6” for example it does work as this policy exists in foreman. This policy was manually created but i want to try and avoid this.

Thanks in advance!

Thanks for the detailed report. Do I understand it correctly that you try to configure foreman_scap_client without creating the policy in Foreman first? If that’s the case, this won’t work. The puppet modules only makes it easy to configure foreman_scap_client, but the policy must be created in Foreman explicitly. That way we make sure the correct scap content file exists on the server and can be distributed. Note that the content_path says where the content should be downloaded from Foreman to. It may be interesting RFE to autocreate policy on first report, however there would be no way to ensure the same scap content is distributed to all hosts that are supposed to comply with this policy. Also, we couldn’t be sure the profile id is valid etc.

If you want to automate this, there’s a REST API to define the policy. Or you can use hammer CLI for that purpose. Last but not least, at least some parts of API should already be covered in Foreman ansible collection https://github.com/theforeman/foreman-ansible-modules.

1 Like