diff --git a/conf/waivers/10-unknown b/conf/waivers/10-unknown index c90160f..8b49637 100644 --- a/conf/waivers/10-unknown +++ b/conf/waivers/10-unknown @@ -23,7 +23,8 @@ /hardening(/host-os)?/ansible/.+/audit_rules_usergroup_modification True # RHEL-9 only -/hardening/ansible/with-gui/.+/network_nmcli_permissions +# (possibly because of missing Ansible remediation?) +/hardening/ansible/.+/network_nmcli_permissions rhel == 9 # RHEL-8 or 9 /hardening(/host-os)?/ansible/.+/audit_rules_unsuccessful_file_modification @@ -105,10 +106,10 @@ # Image Builder # # TODO: file issues ? -/hardening/image-builder/anssi_[^/]+/mount_option_tmp_noexec -/hardening/image-builder/anssi_[^/]+/sebool_polyinstantiation_enabled +/hardening/image-builder(/.+)?/anssi_[^/]+/mount_option_tmp_noexec +/hardening/image-builder(/.+)?/anssi_[^/]+/sebool_polyinstantiation_enabled True -/hardening/image-builder/hipaa/sebool_selinuxuser_execmod +/hardening/image-builder(/.+)?/hipaa/sebool_selinuxuser_execmod rhel == 9 # vim: syntax=python diff --git a/conf/waivers/20-long-term b/conf/waivers/20-long-term index af8fe6d..94afc00 100644 --- a/conf/waivers/20-long-term +++ b/conf/waivers/20-long-term @@ -12,7 +12,7 @@ # - possibly unrelated https://github.com/ComplianceAsCode/content/issues/12276 /hardening/kickstart(/with-gui)?/[^/]+/firewalld_sshd_port_enabled # https://github.com/ComplianceAsCode/content/issues/11625 -/hardening/image-builder/[^/]+/firewalld_sshd_port_enabled +/hardening/image-builder/.+/firewalld_sshd_port_enabled True # rule ordering issue - accounts_password_pam_retry is checked first and passes, @@ -88,7 +88,7 @@ # https://github.com/ComplianceAsCode/content/issues/11565 /hardening/image-builder/.*/audit_rules_privileged_commands # https://github.com/ComplianceAsCode/content/issues/11566 -/hardening/image-builder/[^/]+/sebool_selinuxuser_execstack +/hardening/image-builder/.+/sebool_selinuxuser_execstack # https://github.com/ComplianceAsCode/content/issues/11567 /hardening/image-builder/.*/enable_dracut_fips_module /hardening/image-builder/.*/enable_fips_mode @@ -134,4 +134,13 @@ /static-checks/rule-identifiers/ism_o/.* rhel == 8 or rhel == 9 or rhel == 10 +# UEFI/SecureBoot +# +# https://github.com/ComplianceAsCode/content/issues/12508 +/hardening/ansible/uefi/anssi_bp28_(enhanced|high) + status == 'error' +# https://github.com/ComplianceAsCode/content/issues/12510 +/hardening/image-builder/uefi/.+/mount_option_boot_efi_nosuid + True + # vim: syntax=python diff --git a/hardening/ansible/test.py b/hardening/ansible/test.py index 76e4477..2294e73 100755 --- a/hardening/ansible/test.py +++ b/hardening/ansible/test.py @@ -13,6 +13,8 @@ if variant == 'with-gui': g = virt.Guest('gui_with_oscap') +elif variant == 'uefi': + g = virt.Guest('uefi_with_oscap') else: g = virt.Guest('minimal_with_oscap') @@ -20,7 +22,7 @@ ks = virt.Kickstart(partitions=partitions.partitions) if variant == 'with-gui': ks.packages.append('@Server with GUI') - g.install(kickstart=ks) + g.install(kickstart=ks, secure_boot=(variant == 'uefi')) g.prepare_for_snapshot() # the VM guest ssh code doesn't use $HOME/.known_hosts, so Ansible blocks diff --git a/hardening/ansible/uefi.fmf b/hardening/ansible/uefi.fmf new file mode 100644 index 0000000..3ac9eba --- /dev/null +++ b/hardening/ansible/uefi.fmf @@ -0,0 +1,77 @@ +tag+: + - broken + +/anssi_bp28_high: + +/anssi_bp28_enhanced: + tag+: + - subset-profile + +/anssi_bp28_intermediary: + tag+: + - subset-profile + +/anssi_bp28_minimal: + tag+: + - subset-profile + +/cis: + +/cis_server_l1: + tag+: + - subset-profile + +/cis_workstation_l2: + +/cis_workstation_l1: + tag+: + - subset-profile + +/cui: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no CUI profile on RHEL-10+ + +/e8: + +/hipaa: + +/ism_o: + +/ospp: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no OSPP profile on RHEL-10+ + +/pci-dss: + +/stig: + +/stig_gui: + adjust+: + - enabled: false + because: not supported without GUI, use stig instead + +/ccn_advanced: + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_intermediate: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_basic: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 diff --git a/hardening/image-builder/test.py b/hardening/image-builder/test.py index e71e7bf..889780a 100755 --- a/hardening/image-builder/test.py +++ b/hardening/image-builder/test.py @@ -25,7 +25,7 @@ _, lines = util.subprocess_stream(cmd, check=True) blueprint = osbuild.translate_oscap_blueprint(lines, '/root/remediation-ds.xml') -g.create(blueprint=blueprint, rpmpack=rpmpack) +g.create(blueprint=blueprint, rpmpack=rpmpack, secure_boot=(variant == 'uefi')) with g.booted(): # copy the original DS to the guest diff --git a/hardening/image-builder/uefi.fmf b/hardening/image-builder/uefi.fmf new file mode 100644 index 0000000..3ac9eba --- /dev/null +++ b/hardening/image-builder/uefi.fmf @@ -0,0 +1,77 @@ +tag+: + - broken + +/anssi_bp28_high: + +/anssi_bp28_enhanced: + tag+: + - subset-profile + +/anssi_bp28_intermediary: + tag+: + - subset-profile + +/anssi_bp28_minimal: + tag+: + - subset-profile + +/cis: + +/cis_server_l1: + tag+: + - subset-profile + +/cis_workstation_l2: + +/cis_workstation_l1: + tag+: + - subset-profile + +/cui: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no CUI profile on RHEL-10+ + +/e8: + +/hipaa: + +/ism_o: + +/ospp: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no OSPP profile on RHEL-10+ + +/pci-dss: + +/stig: + +/stig_gui: + adjust+: + - enabled: false + because: not supported without GUI, use stig instead + +/ccn_advanced: + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_intermediate: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_basic: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 diff --git a/hardening/kickstart/test.py b/hardening/kickstart/test.py index db0ba4b..c733d3e 100755 --- a/hardening/kickstart/test.py +++ b/hardening/kickstart/test.py @@ -30,7 +30,7 @@ if variant == 'with-gui': ks.packages.append('@Server with GUI') -g.install(kickstart=ks, rpmpack=rpmpack) +g.install(kickstart=ks, rpmpack=rpmpack, secure_boot=(variant == 'uefi')) with g.booted(): # copy the original DS to the guest diff --git a/hardening/kickstart/uefi.fmf b/hardening/kickstart/uefi.fmf new file mode 100644 index 0000000..1a10115 --- /dev/null +++ b/hardening/kickstart/uefi.fmf @@ -0,0 +1,77 @@ +tag+: + - broken + +/anssi_bp28_high: + +/anssi_bp28_enhanced: + tag+: + - subset-profile + +/anssi_bp28_intermediary: + tag+: + - subset-profile + +/anssi_bp28_minimal: + tag+: + - subset-profile + +/cis: + +/cis_server_l1: + tag+: + - subset-profile + +/cis_workstation_l2: + +/cis_workstation_l1: + tag+: + - subset-profile + +/cui: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no CUI profile on RHEL-10+ + +/e8: + +/hipaa: + +/ism_o: + +/ospp: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no OSPP profile on RHEL-10+ + +/pci-dss: + +/stig: + +/stig_gui: + adjust+: + - enabled: false + because: CCN profiles are not present on RHEL-8 + +/ccn_advanced: + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_intermediate: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_basic: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 diff --git a/hardening/oscap/test.py b/hardening/oscap/test.py index 1fe7691..a7add00 100755 --- a/hardening/oscap/test.py +++ b/hardening/oscap/test.py @@ -12,6 +12,8 @@ if variant == 'with-gui': g = virt.Guest('gui_with_oscap') +elif variant == 'uefi': + g = virt.Guest('uefi_with_oscap') else: g = virt.Guest('minimal_with_oscap') @@ -19,7 +21,7 @@ ks = virt.Kickstart(partitions=partitions.partitions) if variant == 'with-gui': ks.packages.append('@Server with GUI') - g.install(kickstart=ks) + g.install(kickstart=ks, secure_boot=(variant == 'uefi')) g.prepare_for_snapshot() with g.snapshotted(): diff --git a/hardening/oscap/uefi.fmf b/hardening/oscap/uefi.fmf new file mode 100644 index 0000000..3ac9eba --- /dev/null +++ b/hardening/oscap/uefi.fmf @@ -0,0 +1,77 @@ +tag+: + - broken + +/anssi_bp28_high: + +/anssi_bp28_enhanced: + tag+: + - subset-profile + +/anssi_bp28_intermediary: + tag+: + - subset-profile + +/anssi_bp28_minimal: + tag+: + - subset-profile + +/cis: + +/cis_server_l1: + tag+: + - subset-profile + +/cis_workstation_l2: + +/cis_workstation_l1: + tag+: + - subset-profile + +/cui: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no CUI profile on RHEL-10+ + +/e8: + +/hipaa: + +/ism_o: + +/ospp: + adjust+: + - when: distro >= rhel-10 + enabled: false + because: there is no OSPP profile on RHEL-10+ + +/pci-dss: + +/stig: + +/stig_gui: + adjust+: + - enabled: false + because: not supported without GUI, use stig instead + +/ccn_advanced: + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_intermediate: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 + +/ccn_basic: + tag+: + - subset-profile + adjust+: + - when: distro == rhel-8 or distro == rhel-10 + enabled: false + because: CCN profiles are not present on RHEL-8 and on RHEL-10 diff --git a/lib/osbuild.py b/lib/osbuild.py index 9cb8b7d..8773945 100644 --- a/lib/osbuild.py +++ b/lib/osbuild.py @@ -247,7 +247,7 @@ def wipe(self): def install(*args, **kwargs): raise NotImplementedError("install() is not supported, use create()") - def create(self, *, blueprint=None, bp_verbatim=None, rpmpack=None): + def create(self, *, blueprint=None, bp_verbatim=None, rpmpack=None, secure_boot=False): """ Create a guest disk image via osbuild, and import it as a new guest domain into libvirt. @@ -357,6 +357,8 @@ def create(self, *, blueprint=None, bp_verbatim=None, rpmpack=None): '--os-variant', 'rhel8-unknown', '--noreboot', '--import', ] + if secure_boot: + virt_install += ['--boot', 'firmware=efi,loader_secure=yes'] executable = util.libdir / 'pseudotty' util.subprocess_run(virt_install, executable=executable) diff --git a/lib/virt.py b/lib/virt.py index 6c03164..84e6e98 100644 --- a/lib/virt.py +++ b/lib/virt.py @@ -380,7 +380,10 @@ def __init__(self, tag=None, *, name=GUEST_NAME): # if exists, all snapshot preparation processes were successful self.snapshot_ready_path = Path(f'{GUEST_IMG_DIR}/{name}.snapshot_ready') - def install(self, location=None, kickstart=None, rpmpack=None, disk_format='raw'): + def install( + self, location=None, kickstart=None, rpmpack=None, secure_boot=False, + disk_format='raw', + ): """ Install a new guest, to a shut down state. @@ -459,6 +462,8 @@ def install(self, location=None, kickstart=None, rpmpack=None, disk_format='raw' ), '--noreboot', ] + if secure_boot: + virt_install += ['--boot', 'firmware=efi,loader_secure=yes'] util.log(f"calling {virt_install}") executable = util.libdir / 'pseudotty'