-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add /hardening/container/anaconda-ostree
Signed-off-by: Jiri Jaburek <comps@nomail.dom>
- Loading branch information
Showing
2 changed files
with
192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
summary: Creates an OS using Anaconda's ostreecontainer and scans it | ||
test: python3 -m lib.runtest ./test.py | ||
result: custom | ||
environment+: | ||
PYTHONPATH: ../../.. | ||
duration: 1h | ||
require+: | ||
# virt library dependencies | ||
- libvirt-daemon | ||
- libvirt-daemon-driver-qemu | ||
- libvirt-daemon-driver-storage-core | ||
- libvirt-daemon-driver-network | ||
- firewalld | ||
- qemu-kvm | ||
- libvirt-client | ||
- virt-install | ||
- rpm-build | ||
- createrepo | ||
# podman library dependencies | ||
- podman | ||
extra-hardware: | | ||
keyvalue = HVM=1 | ||
hostrequire = memory>=3720 | ||
adjust: | ||
- when: arch != x86_64 | ||
enabled: false | ||
because: we want to run virtualization on x86_64 only | ||
- when: distro < rhel-9.6 | ||
enabled: false | ||
because: Image Mode not supported for older RHELs | ||
- when: distro == rhel | ||
enabled: false | ||
because: TODO - no freely accessible RHEL bootc image, CentOS Stream only | ||
tag+: | ||
# TODO: this test is currently broken by / blocked on Anaconda | ||
# having broken ostreecontainer kickstart functionality, | ||
# https://issues.redhat.com/browse/RHEL-66155 | ||
- 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#!/usr/bin/python3 | ||
|
||
from lib import results, oscap, versions, virt, podman, util | ||
from conf import remediation | ||
|
||
|
||
virt.Host.setup() | ||
|
||
_, variant, profile = util.get_test_name().rsplit('/', 2) | ||
|
||
oscap.unselect_rules(util.get_datastream(), 'remediation-ds.xml', remediation.excludes()) | ||
|
||
# note that the .wipe() is necessary here, as we are not calling any .install() | ||
# function that would normally perform it | ||
guest = virt.Guest() | ||
guest.wipe() | ||
guest.generate_ssh_keypair() | ||
|
||
# CentOS Stream image only, for now | ||
src_image = f'quay.io/centos-bootc/centos-bootc:stream{versions.rhel.major}' | ||
|
||
# RHEL-9 and older use 'maint-1.3' openscap git repo branch, newer use 'main' | ||
if versions.rhel <= 9: | ||
copr = 'packit/OpenSCAP-openscap-maint-1.3' | ||
else: | ||
copr = 'packit/OpenSCAP-openscap-main' | ||
|
||
# prepare a Container file for making a hardened image | ||
cfile = podman.Containerfile() | ||
cfile += util.dedent(fr''' | ||
FROM {src_image} | ||
RUN dnf -y install dnf-plugins-core | ||
RUN dnf -y copr enable {copr} centos-stream-{versions.rhel.major}-x86_64 | ||
RUN dnf -y install openscap-utils | ||
COPY remediation-ds.xml /root/. | ||
RUN oscap-bootc --profile '{profile}' /root/remediation-ds.xml | ||
# hack sshd cmdline to allow root login | ||
RUN echo "OPTIONS=-oPermitRootLogin=yes" >> /etc/sysconfig/sshd | ||
''') | ||
cfile.add_ssh_pubkey(guest.ssh_pubkey) | ||
cfile.write_to('Containerfile') | ||
|
||
podman.podman('image', 'build', '--tag', 'contest-hardened', '.') | ||
|
||
ks = virt.Kickstart() | ||
|
||
# install the VM, using a locally-hosted podman registry serving | ||
# the hardened image for Anaconda's ostreecontainer | ||
with podman.Registry(host_addr=virt.NETWORK_HOST) as registry: | ||
image_url = registry.push('contest-hardened') | ||
ks.append(f'ostreecontainer --url {image_url}') | ||
# Anaconda doesn't expose ostree --insecure-skip-tls-verification, | ||
# work around it using registries.conf | ||
raddr, rport = registry.get_listen_addr() | ||
ks.add_pre( | ||
fr'''echo -e '[[registry]]\nlocation = "{raddr}:{rport}"\n''' | ||
r'''insecure = true\n' >> /etc/containers/registries.conf''' | ||
) | ||
guest.install_basic(kickstart=ks) | ||
|
||
# boot up and scan the VM | ||
with guest.booted(): | ||
# copy the original DS to the guest | ||
guest.copy_to(util.get_datastream(), 'scan-ds.xml') | ||
# scan the remediated system | ||
proc, lines = guest.ssh_stream( | ||
f'oscap xccdf eval --profile {profile} --progress --report report.html' | ||
f' --results-arf results-arf.xml scan-ds.xml' | ||
) | ||
oscap.report_from_verbose(lines) | ||
if proc.returncode not in [0,2]: | ||
raise RuntimeError("post-reboot oscap failed unexpectedly") | ||
|
||
guest.copy_from('report.html') | ||
guest.copy_from('results-arf.xml') | ||
|
||
util.subprocess_run(['gzip', '-9', 'results-arf.xml'], check=True) | ||
|
||
results.report_and_exit(logs=['report.html', 'results-arf.xml.gz']) |