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.
Comment on lines +132 to +136
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.

critical

The test relies on a hardcoded IP address (34.172.244.189), which makes it dependent on an external service that is not managed by the test framework. This is a fragile approach and can lead to test failures if the server at this IP is down, changed, or decommissioned, making the test suite unreliable.

A better approach would be to have the test provision the required HTTPS server as part of its setup, for example by running the fips-nginx container (which is also added in this PR) on a machine within the test cluster or on a temporary VM. This would make the test self-contained and more robust.

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"
}
}
]
}
}`),
})
}

// 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

There's a small typo here. The test is named fips.enable.tls, not fips.enable.https. Please update the README to match the test name in mantle/kola/tests/fips/fips.go.

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 but doesn't clean it up on exit. This can lead to an accumulation of temporary directories in /tmp. It's a good practice to use trap to ensure cleanup, even if the script fails. For example, you could add trap 'rm -rf "${tmpdir}"' EXIT after this line.

cp Containerfile ${tmpdir}
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

This cp command assumes the script is run from the same directory as Containerfile. To make the script more robust and runnable from any location, you should reference Containerfile relative to the script's own location.

Suggested change
cp Containerfile ${tmpdir}
cp "$(dirname "$0")/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