33require 'json'
44require 'timeout'
55
6- describe "ObservabilitySRE FIPS container running on FIPS vm" do
6+ describe "ObservabilitySRE FIPS container" do
7+ def es_request ( path , body = nil )
8+ es_url = "https://localhost:9200"
9+ es_user = 'elastic'
10+ es_password = 'changeme'
11+ uri = URI . parse ( es_url + path )
12+ http = Net ::HTTP . new ( uri . host , uri . port )
13+ http . use_ssl = true
14+ http . verify_mode = OpenSSL ::SSL ::VERIFY_NONE
15+
16+ request = body ? Net ::HTTP ::Post . new ( uri . request_uri ) : Net ::HTTP ::Get . new ( uri . request_uri )
17+ request . basic_auth ( es_user , es_password ) q
18+ request [ "Content-Type" ] = "application/json"
19+ request . body = body if body
20+
21+ http . request ( request )
22+ end
23+
24+ def wait_until ( timeout : 30 , interval : 1 , message : nil )
25+ Timeout . timeout ( timeout ) do
26+ loop do
27+ break if yield
28+ sleep interval
29+ end
30+ end
31+ rescue Timeout ::Error
32+ raise message || "Condition not met within #{ timeout } seconds"
33+ end
734
8- before ( :all ) do
9- # Start docker-compose and wait for ES
10- system ( "cd #{ __dir__ } /../docker && docker-compose up -d" ) or fail "Failed to start Docker Compose environment"
11- max_retries = 120
35+ def wait_for_elasticsearch ( max_retries = 120 )
1236 retries = 0
1337 ready = false
14-
38+
1539 while !ready && retries < max_retries
1640 begin
17- # Wait for elasticsearch to be ready
1841 response = es_request ( "/_cluster/health" )
1942 if response . code == "200"
2043 health = JSON . parse ( response . body )
3255 end
3356 end
3457 end
35-
58+
3659 raise "System not ready after #{ max_retries } seconds" unless ready
3760 end
38-
39- after ( :all ) do
40- # stop docker network
41- system ( "cd #{ __dir__ } /../docker && docker-compose down -v" )
42- end
43-
44- it "data flows from Logstash to Elasticsearch using FIPS-approved SSL" do
45- # Wait for index to appear, indicating data is flowing
46- wait_until ( timeout : 30 , message : "Index logstash-fips-test not found" ) do
47- response = es_request ( "/_cat/indices?v" )
48- response . code == "200" && response . body . include? ( "logstash-fips-test" )
61+
62+ context "when running with FIPS-compliant configuration" do
63+ before ( :all ) do
64+ system ( "cd #{ __dir__ } /../docker && docker-compose up -d" ) or fail "Failed to start Docker Compose environment"
65+ wait_for_elasticsearch
4966 end
50- # Wait until specific data from logstash generator/mutate filters are observed
51- query = { query : { match_all : { } } } . to_json
52- result = nil
53- wait_until ( timeout : 30 , message : "Index logstash-fips-test not found" ) do
54- response = es_request ( "/logstash-fips-test-*/_search" , query )
55- result = JSON . parse ( response . body )
56- response . code == "200" && result [ "hits" ] [ "total" ] [ "value" ] > 0
57- end
58- expect ( result [ "hits" ] [ "hits" ] . first [ "_source" ] ) . to include ( "fips_test" )
59- end
6067
61- def wait_until ( timeout : 30 , interval : 1 , message : nil )
62- Timeout . timeout ( timeout ) do
63- loop do
64- break if yield
65- sleep interval
68+ after ( :all ) do
69+ system ( "cd #{ __dir__ } /../docker && docker-compose down -v" )
70+ end
71+
72+ it "data flows from Logstash to Elasticsearch using FIPS-approved SSL" do
73+ # Wait for index to appear, indicating data is flowing
74+ wait_until ( timeout : 30 , message : "Index logstash-fips-test not found" ) do
75+ response = es_request ( "/_cat/indices?v" )
76+ response . code == "200" && response . body . include? ( "logstash-fips-test" )
6677 end
78+ # Wait until specific data from logstash generator/mutate filters are observed
79+ query = { query : { match_all : { } } } . to_json
80+ result = nil
81+ wait_until ( timeout : 30 , message : "Index logstash-fips-test not found" ) do
82+ response = es_request ( "/logstash-fips-test-*/_search" , query )
83+ result = JSON . parse ( response . body )
84+ response . code == "200" && result [ "hits" ] [ "total" ] [ "value" ] > 0
85+ end
86+ expect ( result [ "hits" ] [ "hits" ] . first [ "_source" ] ) . to include ( "fips_test" )
6787 end
68- rescue Timeout ::Error
69- raise message || "Condition not met within #{ timeout } seconds"
7088 end
7189
72- def es_request ( path , body = nil )
73- es_url = "https://localhost:9200"
74- es_user = 'elastic'
75- es_password = 'changeme'
76- uri = URI . parse ( es_url + path )
77- http = Net ::HTTP . new ( uri . host , uri . port )
78- http . use_ssl = true
79- http . verify_mode = OpenSSL ::SSL ::VERIFY_NONE
80-
81- request = body ? Net ::HTTP ::Post . new ( uri . request_uri ) : Net ::HTTP ::Get . new ( uri . request_uri )
82- request . basic_auth ( es_user , es_password )
83- request [ "Content-Type" ] = "application/json"
84- request . body = body if body
85-
86- http . request ( request )
90+ context "when running with non-FIPS compliant configuration" do
91+ before ( :all ) do
92+ system ( "cd #{ __dir__ } /../docker && LOGSTASH_PIPELINE=logstash-to-elasticsearch-weak.conf docker-compose up -d" ) or fail "Failed to start Docker Compose with weak SSL"
93+ wait_for_elasticsearch
94+ end
95+
96+ after ( :all ) do
97+ system ( "cd #{ __dir__ } /../docker && docker-compose down -v" )
98+ end
99+
100+ it "prevents data flow when using TLSv1.1 which is not FIPS-compliant" do
101+ # Allow time for Logstash to attempt connections (and fail)
102+ sleep 15
103+
104+ # Verify that no index has been created that would indicate successful data flow
105+ response = es_request ( "/_cat/indices?v" )
106+ today_pattern = "logstash-weak-ssl-test-#{ Time . now . strftime ( '%Y.%m.%d' ) } "
107+ expect ( response . body ) . not_to include ( today_pattern )
108+
109+ # Check logs for the specific BouncyCastle FIPS error we expect
110+ logs = `docker logs fips_test_logstash 2>&1`
111+
112+ # Verify the logs contain the FIPS-mode TLS protocol error
113+ expect ( logs ) . to include ( "No usable protocols enabled" )
114+ expect ( logs ) . to include ( "IllegalStateException" )
115+ expect ( logs ) . to include ( "org.bouncycastle" )
116+ end
87117 end
88118end
0 commit comments