Skip to content

Commit bedc706

Browse files
donoghucyaauie
andcommitted
Provision automatic test runs for ruby/java unit tests and integration tests with fips mode (#17029)
* Run ruby unit tests under FIPS mode This commit shows a proposed pattern for running automated tests for logstash in FIPS mode. It uses a new identifier in gradle for conditionally setting properties to configure fips mode. The tests are run in a container representative of the base image the final artifacts will be built from. * Move everything from qa/fips -> x-pack This commit moves test setup/config under x-pack dir. * Extend test pipelines for fips mode to java unit tests and integration * Add git to container for gradle * move fips-mode gradle hooks to x-pack * Skip license check for now --------- Co-authored-by: Ry Biesemeyer <[email protected]>
1 parent 18772dd commit bedc706

File tree

7 files changed

+313
-0
lines changed

7 files changed

+313
-0
lines changed

.buildkite/pull_request_pipeline.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ steps:
1818
export JRUBY_OPTS="-J-Xmx1g"
1919
export GRADLE_OPTS="-Xmx2g -Dorg.gradle.daemon=false -Dorg.gradle.logging.level=info"
2020
ci/license_check.sh -m 4G
21+
# SKIP LICENCE CHECK FOR NOW WHILE WE FIGURE OUT DEPENDENCY VENDORING/PACKAGING
22+
skip: "Skipping license check: TODO unskip once packaging is sorted out"
2123

2224
- label: ":rspec: Ruby unit tests"
2325
key: "ruby-unit-tests"
@@ -37,6 +39,26 @@ steps:
3739
artifact_paths:
3840
- "coverage/coverage.json"
3941

42+
- label: ":rspec: Ruby unit tests - FIPS mode"
43+
key: "ruby-unit-tests-fips"
44+
agents:
45+
provider: gcp
46+
imageProject: elastic-images-prod
47+
image: family/platform-ingest-logstash-ubuntu-2204
48+
machineType: "n2-standard-4"
49+
diskSizeGb: 64
50+
retry:
51+
automatic:
52+
# dont retry on failure while they are expected
53+
- limit: 0
54+
command: |
55+
set -euo pipefail
56+
57+
docker build -t test-runner-image -f x-pack/distributions/internal/observabilitySRE/docker/Dockerfile .
58+
docker run test-runner-image ./gradlew --info --stacktrace -PrunTestsInFIPSMode=true rubyTests
59+
artifact_paths:
60+
- "coverage/coverage.json"
61+
4062
- label: ":java: Java unit tests"
4163
key: "java-unit-tests"
4264
agents:
@@ -58,6 +80,30 @@ steps:
5880
- "**/jacocoTestReport.xml"
5981
- "**/build/classes/**/*.*"
6082

83+
- label: ":java: Java unit tests - FIPS mode"
84+
key: "java-unit-tests-fips"
85+
agents:
86+
provider: gcp
87+
imageProject: elastic-images-prod
88+
image: family/platform-ingest-logstash-ubuntu-2204
89+
machineType: "n2-standard-4"
90+
diskSizeGb: 64
91+
retry:
92+
automatic:
93+
# dont retry on failure while they are expected
94+
- limit: 0
95+
env:
96+
ENABLE_SONARQUBE: true
97+
command: |
98+
set -euo pipefail
99+
100+
docker build -t test-runner-image -f x-pack/distributions/internal/observabilitySRE/docker/Dockerfile .
101+
docker run test-runner-image ./gradlew --info --stacktrace -PrunTestsInFIPSMode=true javaTests
102+
artifact_paths:
103+
- "**/build/test-results/javaTests/TEST-*.xml"
104+
- "**/jacocoTestReport.xml"
105+
- "**/build/classes/**/*.*"
106+
61107
- label: ":sonarqube: Continuous Code Inspection"
62108
if: |
63109
build.pull_request.id != null ||
@@ -79,6 +125,24 @@ steps:
79125
manual:
80126
allowed: true
81127

128+
- label: ":lab_coat: Integration Tests - FIPS mode"
129+
key: "integration-tests-fips"
130+
agents:
131+
provider: gcp
132+
imageProject: elastic-images-prod
133+
image: family/platform-ingest-logstash-ubuntu-2204
134+
machineType: "n2-standard-4"
135+
diskSizeGb: 64
136+
retry:
137+
automatic:
138+
# dont retry on failure while they are expected
139+
- limit: 0
140+
command: |
141+
set -euo pipefail
142+
143+
docker build -t test-runner-image -f x-pack/distributions/internal/observabilitySRE/docker/Dockerfile .
144+
docker run test-runner-image ./gradlew --info --stacktrace -PrunTestsInFIPSMode=true runIntegrationTests
145+
82146
- label: ":lab_coat: Integration Tests / part 1"
83147
key: "integration-tests-part-1"
84148
agents:

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ plugins {
3939
id "com.dorongold.task-tree" version "2.1.0"
4040
}
4141

42+
apply from: "${projectDir}/x-pack/distributions/internal/observabilitySRE/build-ext.gradle"
43+
4244
apply plugin: 'de.undercouch.download'
4345
apply from: "rubyUtils.gradle"
4446

logstash-core/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ dependencies {
235235
runtimeOnly 'commons-logging:commons-logging:1.3.1'
236236
// also handle libraries relying on log4j 1.x to redirect their logs
237237
runtimeOnly "org.apache.logging.log4j:log4j-1.2-api:${log4jVersion}"
238+
// FIPS deps. TODO: figure out how to actually manage these
239+
runtimeOnly("org.bouncycastle:bc-fips:2.0.0")
240+
runtimeOnly("org.bouncycastle:bcpkix-fips:2.0.7")
241+
runtimeOnly("org.bouncycastle:bctls-fips:2.0.19")
242+
runtimeOnly("org.bouncycastle:bcutil-fips:2.0.3")
238243
implementation('org.reflections:reflections:0.10.2') {
239244
exclude group: 'com.google.guava', module: 'guava'
240245
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
ext {
2+
runTestsInFIPSMode = project.hasProperty('runTestsInFIPSMode') ? project.property('runTestsInFIPSMode').toBoolean() : false
3+
}
4+
5+
subprojects {
6+
ext {
7+
runTestsInFIPSMode = rootProject.runTestsInFIPSMode
8+
}
9+
}
10+
11+
allprojects {
12+
afterEvaluate {
13+
tasks.withType(Test) {
14+
if (runTestsInFIPSMode) {
15+
logger.debug("configuring ${it} to run in FIPSMode ")
16+
systemProperty "java.security.properties", System.getenv("JAVA_SECURITY_PROPERTIES")
17+
systemProperty "javax.net.ssl.keyStore", "/etc/java/security/keystore.bcfks"
18+
systemProperty "javax.net.ssl.keyStoreType", "BCFKS"
19+
systemProperty "javax.net.ssl.keyStoreProvider", "BCFIPS"
20+
systemProperty "javax.net.ssl.keyStorePassword", "changeit"
21+
systemProperty "javax.net.ssl.trustStore", "/etc/java/security/cacerts.bcfks"
22+
systemProperty "javax.net.ssl.trustStoreType", "BCFKS"
23+
systemProperty "javax.net.ssl.trustStoreProvider", "BCFIPS"
24+
systemProperty "javax.net.ssl.trustStorePassword", "changeit"
25+
systemProperty "ssl.KeyManagerFactory.algorithm", "PKIX"
26+
systemProperty "ssl.TrustManagerFactory.algorithm", "PKIX"
27+
systemProperty "org.bouncycastle.fips.approved_only", "true"
28+
}
29+
}
30+
}
31+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
grant {
2+
// Your existing permissions
3+
permission java.lang.PropertyPermission "java.runtime.name", "read";
4+
permission java.lang.RuntimePermission "accessClassInPackage.sun.security.internal.spec";
5+
permission java.lang.RuntimePermission "getProtectionDomain";
6+
permission java.lang.RuntimePermission "accessDeclaredMembers";
7+
permission org.bouncycastle.crypto.CryptoServicesPermission "tlsAlgorithmsEnabled";
8+
permission org.bouncycastle.crypto.CryptoServicesPermission "exportKeys";
9+
10+
// Add provider permissions
11+
permission java.security.SecurityPermission "putProviderProperty.BCFIPS";
12+
permission java.security.SecurityPermission "insertProvider.BCFIPS";
13+
permission java.security.SecurityPermission "putProviderProperty.BCJSSE";
14+
permission java.security.SecurityPermission "insertProvider.BCJSSE";
15+
};
16+
17+
deny {
18+
permission java.security.SecurityPermission "putProviderProperty.BC";
19+
permission java.security.SecurityPermission "insertProvider.BC";
20+
permission java.security.SecurityPermission "removeProvider.BC";
21+
};
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
2+
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
3+
security.provider.3=SUN
4+
security.provider.11=-BC
5+
6+
securerandom.source=file:/dev/random
7+
securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN
8+
securerandom.drbg.config=
9+
10+
login.configuration.provider=sun.security.provider.ConfigFile
11+
12+
policy.provider=sun.security.provider.PolicyFile
13+
policy.url.1=file:/etc/java/security/java.policy
14+
policy.expandProperties=true
15+
policy.allowSystemProperty=true
16+
policy.ignoreIdentityScope=false
17+
18+
keystore.type=bcfks
19+
keystore.type.compat=true
20+
21+
package.access=sun.misc.,\
22+
sun.reflect.
23+
package.definition=sun.misc.,\
24+
sun.reflect.
25+
26+
security.overridePropertiesFile=true
27+
28+
ssl.KeyManagerFactory.algorithm=PKIX
29+
ssl.TrustManagerFactory.algorithm=PKIX
30+
31+
networkaddress.cache.negative.ttl=10
32+
33+
krb5.kdc.bad.policy = tryLast
34+
35+
sun.security.krb5.disableReferrals=false
36+
sun.security.krb5.maxReferrals=5
37+
38+
jdk.disabled.namedCurves = secp112r1, secp112r2, secp128r1, secp128r2, \
39+
secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, \
40+
secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, \
41+
sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, \
42+
sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, \
43+
sect571k1, sect571r1, X9.62 c2tnb191v1, X9.62 c2tnb191v2, \
44+
X9.62 c2tnb191v3, X9.62 c2tnb239v1, X9.62 c2tnb239v2, X9.62 c2tnb239v3, \
45+
X9.62 c2tnb359v1, X9.62 c2tnb431r1, X9.62 prime192v2, X9.62 prime192v3, \
46+
X9.62 prime239v1, X9.62 prime239v2, X9.62 prime239v3, brainpoolP256r1, \
47+
brainpoolP320r1, brainpoolP384r1, brainpoolP512r1
48+
49+
jdk.certpath.disabledAlgorithms=MD2, MD5, \
50+
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, \
51+
SHA1, \
52+
secp112r1, secp112r2, secp128r1, secp128r2, \
53+
secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, \
54+
secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, \
55+
sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, \
56+
sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, \
57+
sect571k1, sect571r1, \
58+
brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, brainpoolP512r1
59+
60+
jdk.security.legacyAlgorithms=SHA1, \
61+
RSA keySize < 2048, DSA keySize < 2048
62+
63+
jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
64+
DSA keySize < 1024, SHA1, \
65+
secp112r1, secp112r2, secp128r1, secp128r2, \
66+
secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, \
67+
secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, \
68+
sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, \
69+
sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, \
70+
sect571k1, sect571r1, X9.62 c2tnb191v1, X9.62 c2tnb191v2, \
71+
X9.62 c2tnb191v3, X9.62 c2tnb239v1, X9.62 c2tnb239v2, X9.62 c2tnb239v3, \
72+
X9.62 c2tnb359v1, X9.62 c2tnb431r1, X9.62 prime192v2, X9.62 prime192v3, \
73+
X9.62 prime239v1, X9.62 prime239v2, X9.62 prime239v3, brainpoolP256r1, \
74+
brainpoolP320r1, brainpoolP384r1, brainpoolP512r1
75+
76+
jdk.tls.disabledAlgorithms=MD5, SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
77+
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
78+
secp112r1, secp112r2, secp128r1, secp128r2, \
79+
secp160k1, secp160r1, secp160r2, secp192k1, secp192r1, secp224k1, \
80+
secp224r1, secp256k1, sect113r1, sect113r2, sect131r1, sect131r2, \
81+
sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, \
82+
sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, \
83+
sect571k1, sect571r1, brainpoolP256r1, \
84+
brainpoolP320r1, brainpoolP384r1, brainpoolP512r1
85+
jdk.tls.legacyAlgorithms= \
86+
K_NULL, C_NULL, M_NULL, \
87+
DH_anon, ECDH_anon, \
88+
RC4_128, RC4_40, DES_CBC, DES40_CBC, \
89+
3DES_EDE_CBC
90+
jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37, \
91+
ChaCha20-Poly1305 KeyUpdate 2^37
92+
93+
crypto.policy=unlimited
94+
95+
jdk.xml.dsig.secureValidationPolicy=\
96+
disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\
97+
disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\
98+
disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\
99+
disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\
100+
maxTransforms 5,\
101+
maxReferences 30,\
102+
disallowReferenceUriSchemes file http https,\
103+
minKeySize RSA 1024,\
104+
minKeySize DSA 1024,\
105+
minKeySize EC 224,\
106+
noDuplicateIds,\
107+
noRetrievalMethodLoops
108+
109+
jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep;\
110+
java.base/java.security.KeyRep$Type;java.base/javax.crypto.spec.SecretKeySpec;!*
111+
112+
jdk.sasl.disabledMechanisms=CRAM-MD5, DIGEST-MD5
113+
jdk.security.caDistrustPolicies=SYMANTEC_TLS
114+
jdk.io.permissionsUseCanonicalPath=false
115+
116+
jdk.tls.alpnCharset=ISO_8859_1
117+
118+
org.bouncycastle.fips.approved_only=true
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Start from the FIPS-compliant base image
2+
FROM docker.elastic.co/wolfi/chainguard-base-fips:latest
3+
4+
# Install OpenJDK 21
5+
RUN apk add --no-cache \
6+
openjdk-21 \
7+
bash \
8+
git
9+
10+
# Create directory for security configuration
11+
RUN mkdir -p /etc/java/security
12+
RUN mkdir -p /root/.gradle
13+
14+
# Copy configuration files
15+
COPY x-pack/distributions/internal/observabilitySRE/config/security/java.security /etc/java/security/
16+
COPY x-pack/distributions/internal/observabilitySRE/config/security/java.policy /etc/java/security/
17+
18+
# Set environment variables
19+
ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk
20+
ENV PATH="${JAVA_HOME}/bin:${PATH}"
21+
22+
# Create working directory
23+
WORKDIR /logstash
24+
25+
# Copy the local Logstash source
26+
COPY . .
27+
28+
# Initial build using JKS truststore
29+
RUN ./gradlew clean bootstrap assemble installDefaultGems
30+
31+
# Convert JKS to BCFKS for truststore and keystore
32+
RUN keytool -importkeystore \
33+
-srckeystore $JAVA_HOME/lib/security/cacerts \
34+
-destkeystore /etc/java/security/cacerts.bcfks \
35+
-srcstoretype jks \
36+
-deststoretype bcfks \
37+
-providerpath /logstash/logstash-core/lib/jars/bc-fips-2.0.0.jar \
38+
-provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
39+
-deststorepass changeit \
40+
-srcstorepass changeit \
41+
-noprompt
42+
43+
RUN keytool -importkeystore \
44+
-srckeystore $JAVA_HOME/lib/security/cacerts \
45+
-destkeystore /etc/java/security/keystore.bcfks \
46+
-srcstoretype jks \
47+
-deststoretype bcfks \
48+
-providerpath /logstash/logstash-core/lib/jars/bc-fips-2.0.0.jar \
49+
-provider org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
50+
-deststorepass changeit \
51+
-srcstorepass changeit \
52+
-noprompt
53+
54+
ENV JAVA_SECURITY_PROPERTIES=/etc/java/security/java.security
55+
ENV LS_JAVA_OPTS="\
56+
-Dio.netty.ssl.provider=JDK \
57+
-Djava.security.debug=ssl,provider,certpath \
58+
-Djava.security.properties=${JAVA_SECURITY_PROPERTIES} \
59+
-Djavax.net.ssl.keyStore=/etc/java/security/keystore.bcfks \
60+
-Djavax.net.ssl.keyStoreType=BCFKS \
61+
-Djavax.net.ssl.keyStoreProvider=BCFIPS \
62+
-Djavax.net.ssl.keyStorePassword=changeit \
63+
-Djavax.net.ssl.trustStore=/etc/java/security/cacerts.bcfks \
64+
-Djavax.net.ssl.trustStoreType=BCFKS \
65+
-Djavax.net.ssl.trustStoreProvider=BCFIPS \
66+
-Djavax.net.ssl.trustStorePassword=changeit \
67+
-Dssl.KeyManagerFactory.algorithm=PKIX \
68+
-Dssl.TrustManagerFactory.algorithm=PKIX \
69+
-Dorg.bouncycastle.fips.approved_only=true"
70+
71+
# Example test run, most use cases will override this
72+
CMD ["./gradlew", "--info", "--stacktrace", "-PrunTestsInFIPSMode=true", "runIntegrationTests"]

0 commit comments

Comments
 (0)