Skip to content

Commit

Permalink
add /hardening/container/anaconda-ostree
Browse files Browse the repository at this point in the history
Signed-off-by: Jiri Jaburek <comps@nomail.dom>
  • Loading branch information
comps committed Nov 15, 2024
1 parent 5a49232 commit f8e1533
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 0 deletions.
113 changes: 113 additions & 0 deletions hardening/container/anaconda-ostree/main.fmf
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
79 changes: 79 additions & 0 deletions hardening/container/anaconda-ostree/test.py
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'])

0 comments on commit f8e1533

Please sign in to comment.