Skip to content

Commit 16f204c

Browse files
HuijingHeiopenshift-cherrypick-robot
authored andcommitted
tests: add fips.enable.tls
To verify that using TLS works in FIPS mode by having Ignition fetch a remote resource over HTTPS with FIPS compatible algorithms. tests/containers: build the container based on `nginx-126:10.1`. See Timothee's comment coreos#4477 (comment) Fixes https://issues.redhat.com/browse/COS-3487
1 parent 180f569 commit 16f204c

File tree

4 files changed

+218
-0
lines changed

4 files changed

+218
-0
lines changed

mantle/kola/tests/fips/fips.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,70 @@ func init() {
129129
}
130130
}`),
131131
})
132+
// Test that using TLS works in FIPS mode by having Ignition fetch
133+
// a remote resource over HTTPS with FIPS compatible algorithms.
134+
// See https://issues.redhat.com/browse/COS-3487
135+
// Note that 34.172.244.189, running RHCOS 9.6 (build 20260312-0) on
136+
// Google Cloud Platform, provides HTTPS services using nginx-126:10.1.
137+
register.RegisterTest(&register.Test{
138+
Run: fipsEnableTestTLS,
139+
ClusterSize: 1,
140+
Name: `fips.enable.tls`,
141+
Description: "Verify that fips enabled works if fetching a remote resource over HTTPS with FIPS compatible algorithms.",
142+
Flags: []register.Flag{},
143+
Tags: []string{kola.NeedsInternetTag},
144+
Distros: []string{"rhcos"},
145+
Platforms: []string{"qemu"},
146+
ExcludeArchitectures: []string{"s390x", "ppc64le", "aarch64"}, // only test on x86_64
147+
UserData: conf.Ignition(`{
148+
"ignition": {
149+
"config": {
150+
"replace": {
151+
"source": null,
152+
"verification": {}
153+
}
154+
},
155+
"security": {
156+
"tls": {
157+
"certificateAuthorities": [
158+
{
159+
"compression": "gzip",
160+
"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="
161+
}
162+
]
163+
}
164+
},
165+
"timeouts": {},
166+
"version": "3.4.0"
167+
},
168+
"passwd": {},
169+
"storage": {
170+
"files": [
171+
{
172+
"group": {
173+
"name": "root"
174+
},
175+
"overwrite": true,
176+
"path": "/etc/ignition-machine-config-encapsulated.json",
177+
"user": {
178+
"name": "root"
179+
},
180+
"contents": {
181+
"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",
182+
"verification": {}
183+
},
184+
"mode": 420
185+
},
186+
{
187+
"path": "/var/resource/https-fips",
188+
"contents": {
189+
"source": "https://34.172.244.189:8443/index.html"
190+
}
191+
}
192+
]
193+
}
194+
}`),
195+
})
132196
}
133197

134198
// Test: Run basic FIPS test
@@ -137,3 +201,9 @@ func fipsEnableTest(c cluster.TestCluster) {
137201
c.AssertCmdOutputContains(m, `cat /proc/sys/crypto/fips_enabled`, "1")
138202
c.AssertCmdOutputContains(m, `update-crypto-policies --show`, "FIPS")
139203
}
204+
205+
func fipsEnableTestTLS(c cluster.TestCluster) {
206+
fipsEnableTest(c)
207+
m := c.Machines()[0]
208+
c.AssertCmdOutputContains(m, `cat /var/resource/https-fips`, "This file was served from an RHCOS FIPS-hardened server.")
209+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM registry.redhat.io/rhel10/nginx-126:10.1
2+
3+
ADD nginx.conf "${NGINX_CONF_PATH}"
4+
5+
COPY index.html /usr/share/nginx/html/index.html
6+
7+
# TLS material
8+
USER 0
9+
COPY tls/ /etc/nginx/tls/
10+
RUN chown -R 1001:0 /etc/nginx/tls
11+
USER 1001
12+
13+
CMD ["nginx", "-g", "daemon off;"]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# fips-nginx Container
2+
3+
This is used by the `fips.enable.https` test to verify that using
4+
TLS works in FIPS mode by having Ignition fetch a remote resource
5+
over HTTPS with FIPS compatible algorithms.
6+
7+
See https://catalog.redhat.com/en/software/containers/rhel10/nginx-126/677d3718e58b5a1ae5598058#overview
8+
9+
To build the container using command:
10+
`./build.sh <IP>`
11+
12+
To run the container image using command:
13+
`podman run -d -p 8443:8443 --name fips-nginx fips-nginx`
14+
15+
Remember to create firewall-rules to allow port 8443:
16+
```
17+
gcloud compute firewall-rules create allow-nginx-fips-8443 \
18+
--action ALLOW \
19+
--direction INGRESS \
20+
--rules tcp:8443 \
21+
--source-ranges 0.0.0.0/0 \
22+
--target-tags nginx-fips-server \
23+
--description "Allow FIPS test access to nginx on port 8443"
24+
25+
gcloud compute instances add-tags rhcos-fips-test \
26+
--zone us-central1-a \
27+
--tags nginx-fips-server
28+
```
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env bash
2+
3+
# Run the image using command:
4+
# podman run -d --name fips-nginx -p 8443:8443 fips-nginx
5+
set -euo pipefail
6+
7+
# Check if argument is provided
8+
if [ $# -eq 0 ]; then
9+
echo "Error: Missing IP address argument"
10+
echo "Usage: $0 <ip-address>"
11+
exit 1
12+
fi
13+
14+
ip="$1"
15+
16+
tmpdir="$(mktemp -d)"
17+
cp Containerfile ${tmpdir}
18+
cd ${tmpdir}
19+
20+
# Prepare index.html
21+
cat <<EOF > index.html
22+
This file was served from an RHCOS FIPS-hardened server.
23+
EOF
24+
25+
# Prepare nginx.conf
26+
cat <<EOF > nginx.conf
27+
events {}
28+
29+
http {
30+
server {
31+
listen 8443 ssl;
32+
server_name _;
33+
34+
# ---- FIPS-only TLS ----
35+
ssl_protocols TLSv1.2;
36+
ssl_prefer_server_ciphers on;
37+
38+
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;
39+
40+
ssl_certificate /etc/nginx/tls/fips-server.crt;
41+
ssl_certificate_key /etc/nginx/tls/fips-server.key;
42+
43+
location / {
44+
root /usr/share/nginx/html;
45+
index index.html;
46+
}
47+
}
48+
}
49+
EOF
50+
51+
mkdir -p tls
52+
pushd tls/
53+
# Prepare openssl.cnf
54+
# The IP must point to an nginx server configured with FIPS-compliant ciphers
55+
cat <<SSLEOF > openssl.cnf
56+
[ req ]
57+
default_bits = 3072
58+
distinguished_name = dn
59+
prompt = no
60+
string_mask = utf8only
61+
req_extensions = req_ext
62+
63+
[ dn ]
64+
CN = FIPS TLS Test Server
65+
66+
[ req_ext ]
67+
keyUsage = critical, digitalSignature, keyEncipherment
68+
extendedKeyUsage = critical, serverAuth
69+
subjectAltName = @alt_names
70+
71+
[ alt_names ]
72+
IP.1 = ${ip}
73+
SSLEOF
74+
75+
# Prepare key and crt
76+
## Generate the private key (FIPS-approved)
77+
openssl genpkey \
78+
-algorithm RSA \
79+
-pkeyopt rsa_keygen_bits:3072 \
80+
-out fips-server.key
81+
82+
## Generate CSR (still FIPS-only)
83+
openssl req -new -key fips-server.key -out fips-server.csr -config openssl.cnf
84+
85+
## Self-sign the certificate (TLS-compatible + FIPS)
86+
openssl x509 -req \
87+
-in fips-server.csr \
88+
-signkey fips-server.key \
89+
-out fips-server.crt \
90+
-days 3650 \
91+
-sha256 \
92+
-extfile openssl.cnf \
93+
-extensions req_ext
94+
95+
# Verify SAN present
96+
openssl x509 -in fips-server.crt -noout -text | grep -A2 "Subject Alternative Name"
97+
98+
openssl verify \
99+
-provider fips \
100+
-CAfile fips-server.crt \
101+
fips-server.crt
102+
103+
rm fips-server.csr openssl.cnf
104+
105+
popd
106+
107+
podman build -t fips-nginx .

0 commit comments

Comments
 (0)