Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions mantle/kola/tests/fips/fips.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,70 @@
}
}`),
})
// Test that using TLS works in FIPS mode by having Ignition fetch
// a remote resource over HTTPS with FIPS compatible algorithms.
// See https://issues.redhat.com/browse/COS-3487
// Note that 34.172.244.189, running RHCOS 9.6 (build 20260312-0) on
// Google Cloud Platform, provides HTTPS services using nginx-126:10.1.
register.RegisterTest(&register.Test{
Run: fipsEnableTestTLS,
ClusterSize: 1,
Name: `fips.enable.tls`,
Description: "Verify that fips enabled works if fetching a remote resource over HTTPS with FIPS compatible algorithms.",
Flags: []register.Flag{},
Tags: []string{kola.NeedsInternetTag},

Check failure on line 143 in mantle/kola/tests/fips/fips.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: kola) (typecheck)

Check failure on line 143 in mantle/kola/tests/fips/fips.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: kola (typecheck)
Distros: []string{"rhcos"},
Platforms: []string{"qemu"},
ExcludeArchitectures: []string{"s390x", "ppc64le", "aarch64"}, // only test on x86_64
UserData: conf.Ignition(`{
"ignition": {
"config": {
"replace": {
"source": null,
"verification": {}
}
},
"security": {
"tls": {
"certificateAuthorities": [
{
"compression": "gzip",
"source": "data:;base64,H4sIAAAAAAAC/2SUTdN7yhbF5z7FnaduIUEY/AfdNFoQ2luYeUkkSLwk0fj0t57nnsk5Zw9/u2rV3lVrrf/+DEQGdv+jIhJiHasgRL+UcTBGVqOqoJdqQDEENY4q7G3jjqz64bkgmSjY2p8qKY3Gm0w1P7VOfYbvc+kCH9kM9AE1N1Q58G0APkKA0oi0nR+tMAp1p46NeKtUGGYXa59dMDXvpes0KXU2tHc0Z2PcBgjJD9x+4fYDf1kDbg7hqEFTLfZ9TYPECGIYYp04P+LZxeWw7nZM+cq68ueFHP/zPAh9oNW14QFNVUHaq3VtQHBWT5t93FhwWUnrFkyamb0KudwI1bgZ+jV86+TQaPrgrd/RvQRx+Xqx6lfffdnAi9FQTRw82PZ8HHM7Gt6IeaTV10vepwcr0iU/QLV250dMAquRsMi/rIJevXRV71auDPfnyVnHiD9UX4ukfUm5cGJkdr29FkGZ/DU58SQxrnjd9p/yAu+cgNL7JXq3j0oxd16NyiU3z+5bYyH5HK6NhTg5Y9J7labtJrhbee+zXBdD+7LGb42PLOOCbqoyfBp/93jvZBIBj6gGXwvCEsjE6q5o2iSGNe/EjLESWAdPw71i2EmRnCO22Y1k0i41HjGZaQLzaiM8r4kbDH3xewJdNBjhfh0ZGpTmt67ZfuLOYdjxwPJt4dh9RN/3Ba9LV78JzkjK0+rrV97xHamGieTUaRcqNVNxYdgPp5tRKtgt0PSg+wglmZ7obbN+cfNuR1JkJPLMJSx2tO1Pb+jtxnCJCpR3W8EOiGWaC8LlXZ9nT0nEJyeJm2iwTzRW/Km6Yrn189YdH5Y3Fy2K1OJT+VgDPoA939NEA2cG1m5s+jIENxlB4KgwB1SvUy0mXAd8k4WAUrVO8YmmEPqRCSiiGv3dEwhqysC+RHjcuDkE1f/FBKTXfpSRh97WU19wD/tV3W6NMRK2z0HSvf/mWOYnUX9ZFgI7MvEKKldoWtHGxSRxfLc9bbQrzSORUfLm2t2J3Bw42QVnTblbl4ww4DnmpaGN6OOuxKL79dTj7LqlPtcfH3vqK2XBC93VVzwavjTN+hnskvauGroj3Z4z442peDVjPXB4urDVFX8qsv924b7x7fuXaytdrbqyy53RL0r5my2udheyLWPJcHh6t5yZi5zjnEAxTRgeh+oRDpwkhnOunL/pQRjchO3LaPwaSuLkDs/HhqodOno6JA9BZsPYZ9BgdPPgKB9l1z/H9X3L8uU11Hv/6gSTZXpsGxm4Ts/24SbbT1pehxgCjh7XYY1Dc5KYqyh5tBYH/bk/vtbDHLgW/+yt83gTr1McTwczY08UWFIvfchVldSHYixka6XAN4lyEZinOkjjINfRNRpa3iuUs77t94NcgU8U7j6FtV0TCWTp7Qym5jn1jvupgkCKYuqEyhlhpig1gy0fs7mEuCi8ERNxt1R5+hHP5SZPX1AH1evyXCuzfZeP5uRVbNLbXbZ8UBvIw5tZtt1wqIKDRXA81H/+ML9ljVzt3wX+vwAAAP//bBEEnd0FAAA="
}
]
}
},
"timeouts": {},
"version": "3.4.0"
},
"passwd": {},
"storage": {
"files": [
{
"group": {
"name": "root"
},
"overwrite": true,
"path": "/etc/ignition-machine-config-encapsulated.json",
"user": {
"name": "root"
},
"contents": {
"source": "data:,%7B%22metadata%22%3A%7B%22name%22%3A%22rendered-worker-1cc576110e0cf8396831ce4016f63900%22%2C%22selfLink%22%3A%22%2Fapis%2Fmachineconfiguration.openshift.io%2Fv1%2Fmachineconfigs%2Frendered-worker-1cc576110e0cf8396831ce4016f63900%22%2C%22uid%22%3A%2248871c03-899d-4332-a5f5-bef94e54b23f%22%2C%22resourceVersion%22%3A%224168%22%2C%22generation%22%3A1%2C%22creationTimestamp%22%3A%222019-11-04T15%3A54%3A08Z%22%2C%22annotations%22%3A%7B%22machineconfiguration.openshift.io%2Fgenerated-by-controller-version%22%3A%22bd846958bc95d049547164046a962054fca093df%22%7D%2C%22ownerReferences%22%3A%5B%7B%22apiVersion%22%3A%22machineconfiguration.openshift.io%2Fv1%22%2C%22kind%22%3A%22MachineConfigPool%22%2C%22name%22%3A%22worker%22%2C%22uid%22%3A%223d0dee9e-c9d6-4656-a4a9-81785b9ab01a%22%2C%22controller%22%3Atrue%2C%22blockOwnerDeletion%22%3Atrue%7D%5D%7D%2C%22spec%22%3A%7B%22osImageURL%22%3A%22registry.svc.ci.openshift.org%2Focp%2F4.3-2019-11-04-125204%40sha256%3A8a344c5b157bd01c3ca1abfcef0004fc39f5d69cac1cdaad0fd8dd332ad8e272%22%2C%22config%22%3A%7B%22ignition%22%3A%7B%22config%22%3A%7B%7D%2C%22security%22%3A%7B%22tls%22%3A%7B%7D%7D%2C%22timeouts%22%3A%7B%7D%2C%22version%22%3A%223.0.0%22%7D%2C%22networkd%22%3A%7B%7D%2C%22passwd%22%3A%7B%7D%2C%22storage%22%3A%7B%7D%2C%22systemd%22%3A%7B%7D%7D%2C%22kernelArguments%22%3A%5B%5D%2C%22fips%22%3Atrue%7D%7D",
"verification": {}
},
"mode": 420
},
{
"path": "/var/resource/https-fips",
"contents": {
"source": "https://34.172.244.189:8443/index.html"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This test relies on a hardcoded IP address (34.172.244.189). This makes the test brittle and dependent on an external resource that may not be available or may change over time, leading to test flakiness and maintenance overhead. It would be more robust to have the test environment dynamically set up a local server for this purpose, or use a DNS name that can be pointed to a new server if needed. If a dynamic setup is not feasible, consider moving the IP address to a configuration variable to make it easier to update.

}
}
]
}
}`),
})
}

// Test: Run basic FIPS test
Expand All @@ -137,3 +201,9 @@
c.AssertCmdOutputContains(m, `cat /proc/sys/crypto/fips_enabled`, "1")
c.AssertCmdOutputContains(m, `update-crypto-policies --show`, "FIPS")
}

func fipsEnableTestTLS(c cluster.TestCluster) {
fipsEnableTest(c)
m := c.Machines()[0]
c.AssertCmdOutputContains(m, `cat /var/resource/https-fips`, "This file was served from an RHCOS FIPS-hardened server.")
}
13 changes: 13 additions & 0 deletions tests/containers/fips-nginx/Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM registry.redhat.io/rhel10/nginx-126:10.1

ADD nginx.conf "${NGINX_CONF_PATH}"

COPY index.html /usr/share/nginx/html/index.html

# TLS material
USER 0
COPY tls/ /etc/nginx/tls/
RUN chown -R 1001:0 /etc/nginx/tls
USER 1001

CMD ["nginx", "-g", "daemon off;"]
28 changes: 28 additions & 0 deletions tests/containers/fips-nginx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# fips-nginx Container

This is used by the `fips.enable.https` test to verify that using
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The README mentions the test name is fips.enable.https, but the actual test registered in mantle/kola/tests/fips/fips.go is named fips.enable.tls. To avoid confusion, please update the README to use the correct test name.

Suggested change
This is used by the `fips.enable.https` test to verify that using
This is used by the `fips.enable.tls` test to verify that using

TLS works in FIPS mode by having Ignition fetch a remote resource
over HTTPS with FIPS compatible algorithms.

See https://catalog.redhat.com/en/software/containers/rhel10/nginx-126/677d3718e58b5a1ae5598058#overview

To build the container using command:
`./build.sh <IP>`

To run the container image using command:
`podman run -d -p 8443:8443 --name fips-nginx fips-nginx`

Remember to create firewall-rules to allow port 8443:
```
gcloud compute firewall-rules create allow-nginx-fips-8443 \
--action ALLOW \
--direction INGRESS \
--rules tcp:8443 \
--source-ranges 0.0.0.0/0 \
--target-tags nginx-fips-server \
--description "Allow FIPS test access to nginx on port 8443"

gcloud compute instances add-tags rhcos-fips-test \
--zone us-central1-a \
--tags nginx-fips-server
```
107 changes: 107 additions & 0 deletions tests/containers/fips-nginx/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env bash

# Run the image using command:
# podman run -d --name fips-nginx -p 8443:8443 fips-nginx
set -euo pipefail

# Check if argument is provided
if [ $# -eq 0 ]; then
echo "Error: Missing IP address argument"
echo "Usage: $0 <ip-address>"
exit 1
fi

ip="$1"

tmpdir="$(mktemp -d)"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The script creates a temporary directory using mktemp -d but doesn't clean it up upon exit. This can lead to an accumulation of temporary files on the build machine. It's a good practice to use a trap to ensure the temporary directory is removed, even if the script fails.

Suggested change
tmpdir="$(mktemp -d)"
tmpdir="$(mktemp -d)"
trap 'rm -rf "${tmpdir}"' EXIT

cp Containerfile ${tmpdir}
cd ${tmpdir}

# Prepare index.html
cat <<EOF > index.html
This file was served from an RHCOS FIPS-hardened server.
EOF

# Prepare nginx.conf
cat <<EOF > nginx.conf
events {}

http {
server {
listen 8443 ssl;
server_name _;

# ---- FIPS-only TLS ----
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;

ssl_certificate /etc/nginx/tls/fips-server.crt;
ssl_certificate_key /etc/nginx/tls/fips-server.key;

location / {
root /usr/share/nginx/html;
index index.html;
}
}
}
EOF

mkdir -p tls
pushd tls/
# Prepare openssl.cnf
# The IP must point to an nginx server configured with FIPS-compliant ciphers
cat <<SSLEOF > openssl.cnf
[ req ]
default_bits = 3072
distinguished_name = dn
prompt = no
string_mask = utf8only
req_extensions = req_ext

[ dn ]
CN = FIPS TLS Test Server

[ req_ext ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = critical, serverAuth
subjectAltName = @alt_names

[ alt_names ]
IP.1 = ${ip}
SSLEOF

# Prepare key and crt
## Generate the private key (FIPS-approved)
openssl genpkey \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:3072 \
-out fips-server.key

## Generate CSR (still FIPS-only)
openssl req -new -key fips-server.key -out fips-server.csr -config openssl.cnf

## Self-sign the certificate (TLS-compatible + FIPS)
openssl x509 -req \
-in fips-server.csr \
-signkey fips-server.key \
-out fips-server.crt \
-days 3650 \
-sha256 \
-extfile openssl.cnf \
-extensions req_ext

# Verify SAN present
openssl x509 -in fips-server.crt -noout -text | grep -A2 "Subject Alternative Name"

openssl verify \
-provider fips \
-CAfile fips-server.crt \
fips-server.crt

rm fips-server.csr openssl.cnf

popd

podman build -t fips-nginx .
Loading