Skip to content

Commit

Permalink
Adding system test for provision using Provisioner.NET (#748)
Browse files Browse the repository at this point in the history
* Adding run script, Dockerfile, and container setup script for provisioning with TPM Simulator and Provisioner.Net

* Replacing Docker container setup script with Docker Compose .yml file with respective configurations in related files

* Adding system_test.yml for GitHub actions to run system tests upon V3 branch pushes. Modifying related files accordingly

* Replacing V2 ACA with V3 ACA built from Rocky 9
  • Loading branch information
iadgovuser62 authored May 1, 2024
1 parent e8924dc commit 144160d
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 119 deletions.
2 changes: 1 addition & 1 deletion .ci/docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ IMA_ENABLED=false
HIRS_ACA_PORTAL_IP=172.19.0.2
HIRS_ACA_PORTAL_PORT=8443
HIRS_BROKER_PORT=61616
HIRS_ACA_PORTAL_CONTAINER_PORT=80
HIRS_ACA_PORTAL_CONTAINER_PORT=8443

HIRS_ACA_HOSTNAME=hirsaca

Expand Down
100 changes: 100 additions & 0 deletions .ci/docker/Dockerfile.tpm2provisioner_dotnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
FROM rockylinux:9
LABEL org.opencontainers.image.vendor NSA Laboratory for Advanced Cybersecurity Research
LABEL org.opencontainers.image.source https://github.com/nsacyber/hirs
LABEL org.opencontainers.image.description Tools for testing the build and deployment of HIRS projects.

# Purpose: This image is designed for HIRS Provisioner.Net testing on Rocky 9.
# Date Modified: 4/15/24
# Notes: The image to be built should be named "tpm2provisioner-dotnet-ci:latest".
# For local build, use this command from the /HIRS/ directory to build the image:
# $ docker build -f ./.ci/docker/Dockerfile.tpm2provisioner_dotnet -t tpm2provisioner-dotnet-ci:latest .

# REF can be specified as a docker run environment variable to select the HIRS branch to work with
ENV REF=main
# BUILD, is an environment variable that if not empty, will attempt to run gradle bootWar on the cloned branch
ENV BUILD=

SHELL ["/bin/bash", "-c"]

# Rocky 9 has a different channel for some apps
RUN dnf install -y 'dnf-command(config-manager)' && dnf config-manager --set-enabled crb

# Update and install OS-dependencies
RUN dnf update -y
# Dependencies were selected for these reasons:
# OS setup/Unknown direct impact for HIRS
ENV HIRS_DNF_OS_SETUP="initscripts firewalld policycoreutils policycoreutils-python-utils net-tools"
# OS tools
ENV HIRS_DNF_OS_TOOLS="git sudo vim wget"
# ACA compile
ENV HIRS_DNF_ACA_COMPILE="java-17-openjdk-devel"
# ACA run
ENV HIRS_DNF_ACA_RUN="mariadb-server"
# IBM TPM simulator compile
ENV HIRS_DNF_TPM_COMPILE="tpm2-tools gcc cmake openssl-devel"
# IBM TSS compile
ENV HIRS_DNF_TSS_COMPILE="autoconf automake libtool"
# .NET SDK
ENV HIRS_DNF_DOTNET_SDK="dotnet-sdk-6.0"
# Download and install all dependencies at one time
RUN dnf -y install $(echo "$HIRS_DNF_OS_SETUP") $(echo "$HIRS_DNF_OS_TOOLS") $(echo "$HIRS_DNF_ACA_COMPILE") $(echo "$HIRS_DNF_ACA_RUN") $(echo "$HIRS_DNF_TPM_COMPILE") $(echo "$HIRS_DNF_TSS_COMPILE") $(echo "$HIRS_DNF_DOTNET_SDK")

# Build IBM TPM Simulator
RUN git clone https://github.com/kgoldman/ibmswtpm2 /ibmswtpm2
WORKDIR /ibmswtpm2/src
RUN make

# Build IBM TPM tools
RUN git clone https://github.com/kgoldman/ibmtss /ibmtss
WORKDIR /ibmtss/utils
RUN make -f makefiletpmc

# The following script tests that the SW TPM and TSS were compiled in the docker image. And documents how to start the SW TPM after container launch using both IBM's tss and TPM2-TOOLS.
RUN echo "#!/bin/bash" > /tmp/tpm_config && \
echo "/ibmswtpm2/src/tpm_server &" >> /tmp/tpm_config && \
echo "sleep 5" >> /tmp/tpm_config && \
echo "/ibmtss/utils/startup -c" >> /tmp/tpm_config && \
echo "tpm2_shutdown" >> /tmp/tpm_config && \
echo "tpm2_startup -c" >> /tmp/tpm_config && \
echo "/ibmtss/utils/shutdown -c" >> /tmp/tpm_config && \
bash /tmp/tpm_config && \
rm -rf /tmp/tpm_config

# Checkout HIRS
RUN git clone -b main https://github.com/nsacyber/HIRS.git /hirs

# Run bootwar to cache build artifacts
WORKDIR /hirs
RUN ./gradlew bootWar

# Install dotnet tools
RUN dotnet tool install --global dotnet-deb
RUN dotnet tool install --global dotnet-rpm
RUN dotnet tool install --global dotnet-zip
# Add dotnet PATHs
ENV PATH="/root/.dotnet:/root/.dotnet/tools:$PATH"
# Build .NET
WORKDIR /hirs/HIRS_Provisioner.NET
RUN dotnet restore
WORKDIR /hirs/HIRS_Provisioner.NET/hirs
RUN dotnet test
RUN dotnet deb -r linux-x64 -c Release
RUN dotnet rpm -r linux-x64 -c Release

# The following script will clone and copy the referenced branch of HIRS off GitHub
# If configured, run bootwar to cache build artifacts
RUN echo "#!/bin/bash" > /tmp/auto_clone_branch && \
echo "cd /hirs" >> /tmp/auto_clone_branch && \
echo "git fetch origin && git pull origin main && git reset --hard" >> /tmp/auto_clone_branch && \
echo 'git checkout $1 && git reset --hard' >> /tmp/auto_clone_branch && \
echo 'if [ -n "${2}" ]; then ./gradlew bootWar; fi' >> /tmp/auto_clone_branch && \
echo "cd HIRS_Provisioner.NET/hirs" >> /tmp/auto_clone_branch && \
echo 'if [ -n "${2}" ]; then dotnet deb -r linux-x64 -c Release && dotnet rpm -r linux-x64 -c Release; fi' >> /tmp/auto_clone_branch && \
chmod 755 /tmp/auto_clone_branch

# Reset working directory
WORKDIR /hirs

# Copy script for running TPM Simulator
COPY ./.ci/setup/container/setup_tpm2provisioner_dotnet.sh /.ci/setup/container/
RUN chmod 755 /.ci/setup/container/setup_tpm2provisioner_dotnet.sh
30 changes: 5 additions & 25 deletions .ci/docker/docker-compose-system-test.yml
Original file line number Diff line number Diff line change
@@ -1,54 +1,34 @@
version: "3.1"

services:
aca:
image: ghcr.io/nsacyber/hirs/aca-ci:latest
image: ghcr.io/nsacyber/hirs/aca-rocky:5445278
container_name: hirs-aca1
volumes:
- ../../:/HIRS
ports:
- "${HIRS_ACA_PORTAL_PORT}:${HIRS_ACA_PORTAL_CONTAINER_PORT}"
entrypoint: /bin/bash -c
command: [tail -f /dev/null;]
hostname: ${HIRS_ACA_HOSTNAME}
networks:
hirs_aca_system_tests:
ipv4_address: ${HIRS_ACA_PORTAL_IP}
aliases:
- ${HIRS_ACA_HOSTNAME}
- ${HIRS_ACA_HOSTNAME}

tpmprovisioner:
image: ghcr.io/nsacyber/hirs/tpm2provisioner-ci:latest
image: ghcr.io/nsacyber/hirs/tpm2provisioner-dotnet-ci:latest
container_name: hirs-provisioner1-tpm2
depends_on:
- aca
volumes:
- ../../:/HIRS
- ../system-tests/profiles/laptop/dmi:/sys/class/dmi:ro
entrypoint: /bin/bash -c
command: [tail -f /dev/null;]
devices:
- "/dev/mem:/dev/mem"
cap_add:
- sys_rawio
command: ["bash", "-c", "tail -f /dev/null;"]
networks:
hirs_aca_system_tests:
ipv4_address: ${HIRS_ACA_PROVISIONER_TPM2_IP}
environment:
- HIRS_ACA_PROVISIONER_TPM2_IP=${HIRS_ACA_PROVISIONER_TPM2_IP}
- TPM_ENABLED=${TPM_ENABLED}
- IMA_ENABLED=${IMA_ENABLED}
- HIRS_ACA_PORTAL_IP=${HIRS_ACA_PORTAL_IP}
- HIRS_ACA_PORTAL_PORT=${HIRS_ACA_PORTAL_PORT}
- HIRS_BROKER_PORT=${HIRS_BROKER_PORT}
- HIRS_ACA_PORTAL_CONTAINER_PORT=${HIRS_ACA_PORTAL_CONTAINER_PORT}
- HIRS_ACA_HOSTNAME=${HIRS_ACA_HOSTNAME}
- HIRS_SUBNET=${HIRS_SUBNET}

networks:
hirs_aca_system_tests:
driver: bridge
ipam:
driver: default
config:
- subnet: ${HIRS_SUBNET}
- subnet: ${HIRS_SUBNET}
83 changes: 83 additions & 0 deletions .ci/setup/container/setup_tpm2provisioner_dotnet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/bin/bash
#########################################################################################
# Script to setup the TPM Provisioner.NET for System Tests
#########################################################################################

# Setting configurations
. ./.ci/docker/.env

set -a

set -e
echo "*** Setting up TPM emulator for the TPM2 Provisioner *** "

# Wait for ACA to boot
echo "*** Waiting for ACA to spin up at address ${HIRS_ACA_PORTAL_IP} on port ${HIRS_ACA_PORTAL_PORT} ..."
until [ "`curl --silent -I -k https://${HIRS_ACA_PORTAL_IP}:${HIRS_ACA_PORTAL_PORT}/HIRS_AttestationCAPortal | grep 'HTTP/1.1 200'`" != "" ]; do
sleep 1;
done
echo "*** ACA is up!"

# Un-package Provisioner.NET RPM
cd /
yes | dnf install /hirs/HIRS_Provisioner.NET/hirs/bin/Release/net6.0/linux-x64/HIRS_Provisioner.NET.2.2.0.linux-x64.rpm 1> /dev/null

# Start TPM simulator server
./ibmswtpm2/src/tpm_server 1> /dev/null &
echo "*** TPM Simulator Server has started"

# Create EK Certificate
cd /ibmtss/utils || exit
./startup 1> /dev/null
./createekcert -rsa 2048 -cakey cakey.pem -capwd rrrr -v 1> /dev/null
cd / || exit
echo "*** EK certificate has been created using IBMTSS CA Key"

# Writing to Provisioner.Net configurations file for modified aca port and efi prefix
cat <<APPSETTINGS_FILE > /usr/share/hirs/appsettings.json
{
"auto_detect_tpm": "TRUE",
"aca_address_port": "https://${HIRS_ACA_PORTAL_IP}:${HIRS_ACA_PORTAL_PORT}",
"efi_prefix": "/boot/efi",
"paccor_output_file": "",
"event_log_file": "",
"hardware_manifest_collectors": "paccor_scripts",
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Message}{NewLine}",
"theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Grayscale, Serilog.Sinks.Console",
"restrictedToMinimumLevel": "Information"
}
},
{
"Name": "File",
"Args": {
"path": "hirs.log",
"rollingInterval": "Day",
"retainedFileCountLimit": 5
}
}
]
}
}
APPSETTINGS_FILE

# Uploading CA Certificate to HIRS ACA Portal
curl -k -s -F "file=@/ibmtss/utils/certificates/cacert.pem" https://${HIRS_ACA_PORTAL_IP}:${HIRS_ACA_PORTAL_PORT}/HIRS_AttestationCAPortal/portal/certificate-request/trust-chain/upload
echo "*** CA Certificate has been uploaded to HIRS ACA Portal"

# Starting Provisioning
./usr/share/hirs/tpm_aca_provision --tcp --ip 127.0.0.1:2321 --sim
87 changes: 25 additions & 62 deletions .ci/system-tests/run_system_tests.sh
Original file line number Diff line number Diff line change
@@ -1,84 +1,47 @@
#!/bin/bash
#########################################################################################
# Script to run the System Tests for HIRS TPM 2.0 Provisoner
#
# Notes for running manually/locally (not from GitHub Actions)
# 1. Uncomment the "cd ../.." line below to make working directory = /HIRS/
# 2. Run with the desired HIRS branch as an argument (i.e. $./run_system_tests.sh main)
#########################################################################################
# cd ../..

# Setting variables
aca_container=hirs-aca1
tpm2_container=hirs-provisioner1-tpm2
testResult="passed";
issuerCert=../setup/certs/ca.crt
hirs_aca_log=/var/log/tomcat/HIRS_AttestationCA.log

# Source files for Docker Variables and helper scripts
. ./.ci/docker/.env

set -a

echo "******** Setting up for HIRS System Tests for TPM 2.0 ******** "

# Expand linux dmi files to mount to the provisioner container to simulate device component
unzip -q .ci/system-tests/profiles/laptop/laptop_dmi.zip -d .ci/system-tests/profiles/laptop/
# Start System Testing Docker Environment
pushd .ci/docker > /dev/null

docker-compose -f docker-compose-system-test.yml up -d

popd > /dev/null
pushd .ci/system-tests > /dev/null
source sys_test_common.sh

# Build, Package, and Install HIRS ACA (2+ minutes) then wait for systems tests...
docker exec $aca_container sh -c "/HIRS/.ci/setup/container/setup_aca.sh"
echo "ACA Loaded!"
echo "ACA Container info: $(checkContainerStatus $aca_container)";

# Install HIRS provioner and setup tpm2 emulator
docker exec $tpm2_container /HIRS/.ci/setup/container/setup_tpm2provisioner.sh
echo "TPM2 Provisioner Container info: $(checkContainerStatus $tpm2_container)";
echo "******** Setting up for HIRS System Tests for TPM 2.0 ******** "
docker compose -f ./.ci/docker/docker-compose-system-test.yml up -d

# ********* Execute system tests here, add tests as needed *************
echo "******** Setup Complete Begin HIRS System Tests ******** "
# Switching to current/desired branch
docker exec $tpm2_container sh -c "cd / && ./tmp/auto_clone_branch $1 1> /dev/null && cd hirs"

source tests/aca_policy_tests.sh
source tests/platform_cert_tests.sh
source tests/rim_system_tests.sh
# Install HIRS Provisioner.Net and setup tpm2 simulator.
# In doing so, tests a single provision between Provisioner.Net and ACA.
docker exec $tpm2_container /.ci/setup/container/setup_tpm2provisioner_dotnet.sh

# HERE is where other system tests will be called, including:
# aca_policy_tests.sh, platform_cert_tests.sh, rim_system_tests.sh
echo "******** HIRS System Tests Complete ******** "

# collecting ACA logs for archiving
echo "Collecting ACA logs ....."
docker exec $aca_container mkdir -p /HIRS/logs/aca/;
docker exec $aca_container cp -a /var/log/tomcat/. /HIRS/logs/aca/;
docker exec $aca_container chmod -R 777 /HIRS/logs/;
echo "Collecting provisioner logs"
docker exec $tpm2_container mkdir -p /HIRS/logs/provisioner/;
docker exec $tpm2_container cp -a /var/log/hirs/provisioner/. /HIRS/logs/provisioner/;
docker exec $tpm2_container chmod -R 777 /HIRS/logs/;

echo ""
echo "===========HIRS Tests and Log collection complete ==========="
# Collecting ACA and Provisioner.Net logs for workflow artifact
echo "*** Extracting ACA and Provisioner.Net logs ..."
docker exec $aca_container sh -c "cd .. && mkdir -p /HIRS/logs/aca/ && cp -arp /var/log/hirs/* /HIRS/logs/aca/"
docker exec $tpm2_container sh -c "cd .. && mkdir -p /HIRS/logs/provisioner/ && cp -ap hirs*.log /HIRS/logs/provisioner/ && chmod -R 777 /HIRS/logs"

echo ""
echo "End of System Tests for TPM 2.0, cleaning up..."
echo ""
# Clean up services and network
popd > /dev/null
pushd .ci/docker > /dev/null
docker-compose -f docker-compose-system-test.yml down -v
popd > /dev/null
# Clean up dangling containers
echo "Cleaning up dangling containers..."
echo ""
docker container prune --force
echo ""
echo "New value of test status is ${TEST_STATUS}"
echo "*** Exiting and removing Docker containers and network ..."
docker compose -f ./.ci/docker/docker-compose-system-test.yml down -v

# Return container exit code
if [[ ${TEST_STATUS} == "0" ]]; then
echo "SUCCESS: System Tests for TPM 2.0 passed"
echo "******** SUCCESS: System Tests for TPM 2.0 passed ********"
echo "TEST_STATUS=0" >> $GITHUB_ENV
exit 0;
else
echo "FAILURE: System Tests for TPM 2.0 failed"
echo "******** FAILURE: System Tests for TPM 2.0 failed ********"
echo "TEST_STATUS=1" >> $GITHUB_ENV
exit 1
exit 1
fi
Loading

0 comments on commit 144160d

Please sign in to comment.