diff --git a/tests/gold_tests/pluginTest/traffic_dump/replay/traffic_dump.yaml b/tests/gold_tests/pluginTest/traffic_dump/replay/traffic_dump.yaml new file mode 100644 index 00000000000..2a55a490080 --- /dev/null +++ b/tests/gold_tests/pluginTest/traffic_dump/replay/traffic_dump.yaml @@ -0,0 +1,335 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +meta: + version: "1.0" + + blocks: + - 200_ok_response: &200_ok_response + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Content-Length, 16 ] + - [ Connection, close ] + +sessions: +- transactions: + - client-request: + method: GET + url: /one + version: 1.1 + headers: + fields: + - [ Host, www.notls.com ] + - [ X-Request-1, ultra_sensitive ] + - [ Content-Length, 0 ] + - [ uuid, 1 ] + + proxy-request: + headers: + fields: + # The field should get through to the server. The traffic dump, though, + # should not contain it since x-request-1 is a sensitive field. + - [ X-Request-1, { value: ultra_sensitive, as: equal } ] + + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Content-Length, 16 ] + - [ Set-Cookie, classified_not_for_logging ] + + proxy-response: + status: 200 + headers: + field: + # Again, the sensitive set-cookie should get through to the client, it + # just shouldn't be dumped in traffic dumps. + - [ Set-Cookie, { value: classified_not_for_logging, as: equal } ] + +- transactions: + - client-request: + method: GET + url: /two + version: 1.1 + headers: + fields: + - [ Host, www.notls.com ] + - [ X-Request-2, also_very_sensitive ] + - [ Content-Length, 0 ] + - [ uuid, 2 ] + + proxy-request: + headers: + fields: + # The field should get through to the server. The traffic dump, though, + # should not contain it since x-request-1 is a sensitive field. + - [ X-Request-2, { value: also_very_sensitive, as: equal } ] + + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Content-Length, 16 ] + - [ Set-Cookie, classified_not_for_logging ] + + proxy-response: + status: 200 + headers: + field: + # Again, the sensitive set-cookie should get through to the client, it + # just shouldn't be dumped in traffic dumps. + - [ Set-Cookie, { value: classified_not_for_logging, as: equal } ] + +- transactions: + - client-request: + method: GET + url: "http://www.some.host.com/candy" + version: 1.1 + headers: + fields: + - [ Host, www.some.host.com ] + - [ Content-Length, 0 ] + - [ uuid, 3 ] + + proxy-request: + # Having a mismatch in the Host header and the request target is + # malformed. ATS, by default, deals with this by choosing the host from + # the request target, making that the Host header value, and then + # adjusting the request target to just have the path. + url: + - [ scheme, { as: absent } ] + - [ host, { as: absent } ] + - [ path, { value: /candy, as: equal } ] + + headers: + fields: + - [ Host, { value: www.some.host.com, as: equal } ] + + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Content-Length, 16 ] + - [ Set-Cookie, classified_not_for_logging ] + + proxy-response: + status: 200 + headers: + field: + - [ Set-Cookie, { value: classified_not_for_logging, as: equal } ] + +- transactions: + # The test expects a POST with a body of 12345 bytes. + - client-request: + method: POST + url: /post/with/body + version: 1.1 + headers: + fields: + - [ Host, www.notls.com ] + - [ Content-Length, 12345 ] + - [ uuid, 4 ] + + proxy-request: + url: + - [ path, { value: /post/with/body, as: equal } ] + + headers: + fields: + - [ Host, { value: www.notls.com, as: equal } ] + + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Content-Length, 16 ] + - [ Set-Cookie, classified_not_for_logging ] + + proxy-response: + status: 200 + headers: + field: + - [ Set-Cookie, { value: classified_not_for_logging, as: equal } ] + +- transactions: + + # Make a couple requests for the same target and expect it to be served out + # of the cache. + + - client-request: + method: GET + url: /expect/this/to/be/cached + version: 1.1 + headers: + fields: + - [ Host, www.notls.com ] + - [ Content-Length, 0 ] + - [ uuid, 5 ] + + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Content-Length, 16 ] + - [ Cache-Control, max-age=300 ] + + proxy-response: + status: 200 + headers: + field: + - [ Cache-Control, { value: max-age=300, as: equal } ] + +# The delay here is needed because it gives the ATS cache time to finish IO. +- delay: 50ms + transactions: + + - client-request: + method: GET + url: /expect/this/to/be/cached + version: 1.1 + headers: + fields: + - [ Host, www.notls.com ] + - [ Content-Length, 0 ] + - [ uuid, 6 ] + + # We do not expect this to make it to the server since it should be served + # out of the cache. If it makes it to the server, reply with a 503 so + # we can detect that this happened. + server-response: + status: 503 + reason: Service Unavailable + headers: + fields: + - [ Content-Length, 16 ] + + # Expect the cached 200 response. + proxy-response: + status: 200 + +- transactions: + - client-request: + method: GET + url: /first + version: 1.1 + headers: + fields: + - [ Host, www.notls.com ] + - [ Content-Length, 0 ] + - [ uuid, 7 ] + + <<: *200_ok_response + + proxy-response: + status: 200 + + - client-request: + method: GET + url: /second + version: 1.1 + headers: + fields: + - [ Host, www.notls.com ] + - [ Content-Length, 0 ] + - [ uuid, 8 ] + + <<: *200_ok_response + + proxy-response: + status: 200 + +- protocol: [ {name: tls, sni: www.tls.com }, + {name: tcp }, + {name: ip} ] + + transactions: + - client-request: + method: GET + url: /tls + version: 1.1 + headers: + fields: + - [ Host, www.tls.com ] + - [ Content-Length, 0 ] + - [ uuid, 9 ] + + <<: *200_ok_response + + proxy-response: + status: 200 + +- protocol: [ {name: http, version: 2}, + {name: tls, sni: www.tls.com}, + {name: tcp}, + {name: ip} ] + + transactions: + - client-request: + headers: + fields: + - [ :method, GET ] + - [ :scheme, https ] + - [ :authority, www.tls.com ] + - [ :path, /h2_first ] + - [ uuid, 10 ] + + <<: *200_ok_response + + proxy-response: + status: 200 + + - client-request: + headers: + fields: + - [ :method, GET ] + - [ :scheme, https ] + - [ :authority, www.tls.com ] + - [ :path, /h2_second ] + - [ uuid, 11 ] + + <<: *200_ok_response + + proxy-response: + status: 200 + +- protocol: [ {name: tls, sni: www.client_only_tls.com}, + {name: tcp}, + {name: ip} ] + + transactions: + - client-request: + method: GET + url: /client_only_tls + version: 1.1 + headers: + fields: + - [ Host, www.client_only_tls.com ] + - [ Content-Length, 0 ] + - [ uuid, 12 ] + + <<: *200_ok_response + + proxy-response: + status: 200 + diff --git a/tests/gold_tests/pluginTest/traffic_dump/replay/various_sni.yaml b/tests/gold_tests/pluginTest/traffic_dump/replay/various_sni.yaml new file mode 100644 index 00000000000..4d5f30b16c2 --- /dev/null +++ b/tests/gold_tests/pluginTest/traffic_dump/replay/various_sni.yaml @@ -0,0 +1,112 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# This replay file assumes that caching is enabled and +# proxy.config.http.cache.ignore_client_cc_max_age is set to 0 so that we can +# test max-age in the client requests. +# + +meta: + version: "1.0" + + blocks: + - 200_ok_response: &200_ok_response + server-response: + status: 200 + reason: OK + headers: + fields: + - [ Content-Length, 16 ] + - [ Connection, close ] + +sessions: + +# +# Test 1: Create a session using an SNI of "bob". +# +- protocol: [ {name: http, version: 2}, + {name: tls, sni: bob.com}, + {name: tcp }, + {name: ip} ] + + transactions: + + - all: { headers: { fields: [[ uuid, 1 ]]}} + client-request: + headers: + fields: + - [ :method, GET ] + - [ :scheme, https ] + - [ :authority, bob.com ] + - [ :path, '/path/use/sni/bob' ] + + + <<: *200_ok_response + + proxy-response: + status: 200 + +# +# Test 2: Create a session using an SNI of "dave.com". +# +- protocol: [ {name: http, version: 2}, + {name: tls, sni: dave.com}, + {name: tcp }, + {name: ip} ] + + transactions: + + - all: { headers: { fields: [[ uuid, 2 ]]}} + client-request: + headers: + fields: + - [ :method, GET ] + - [ :scheme, https ] + - [ :authority, dave.com ] + - [ :path, '/path/use/sni/dave' ] + + + <<: *200_ok_response + + proxy-response: + status: 200 + +# +# Test 3: Create a session using no SNI. +# +- protocol: [ {name: http, version: 2}, + {name: tls}, + {name: tcp }, + {name: ip} ] + + transactions: + + - all: { headers: { fields: [[ uuid, 3 ]]}} + client-request: + headers: + fields: + - [ :method, GET ] + - [ :scheme, https ] + - [ :authority, example.com ] + - [ :path, '/path/use/sni/absent' ] + + + <<: *200_ok_response + + proxy-response: + status: 200 + diff --git a/tests/gold_tests/pluginTest/traffic_dump/ssl/server_combined.pem b/tests/gold_tests/pluginTest/traffic_dump/ssl/server_combined.pem new file mode 100644 index 00000000000..cd1bfc9669b --- /dev/null +++ b/tests/gold_tests/pluginTest/traffic_dump/ssl/server_combined.pem @@ -0,0 +1,49 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCZkEXSlZ+ZFKFg +CPpcDG39e73BuK6E5uE38q2PHh4DV0xcsJnIUx51viqLPwYughxfP0crHyBdXoHV +dW/3WX4gpiGrdiM/dvCouheo0DPaqUUJ2nZKVYh2M57oyeiuJidlKb7BGkfw3HWP +9TV7dVyGWok/cowjopqaLHJWxg/kh2KqvUBD0CHt9Kd1XvgXVmHwE7vCv0j5owv2 +MaExTsFb16uWmVLhl1gNHI2RqCX2yLaebH1DvtbLrit1XErjtaSYeJE9clVRaqT6 +vsvLOhyB5tA9WfZqfBYr/MHDeXQfrbIf+4Cp3aTpq5grc5InIMMH0eOk6/f/4tW+ +nq1lfszZAgMBAAECggEAYvYAqRbXRRVwca0Xel5gO2yU+tSDUw5esWlow8RK3yhR +A6KjV9+Iz6P/UsEIwMwEcLUcrgNfHgybau5Fe4dmqq+lHxQA3xNNP869FIMoB4/x +98mbVYgNau8VRztnAWOBG8ZtMZA4MFZCRMVm8+rL96E8tXCiMwzEyPo/rP/ymfhN +3GRunX+GhfIA79AYNbd7HMVL+cvWWUGUF5Bc5i1wXcLy4I7b9NYtv920BeCLzSFK +BypFB7ku/vKgTcBxe4yxThxPeXPwm4WFzGYKk/Afl1j8tVXCE2U4Y3yykfC0Qk6S +ECZbCKLO2Rxi9fclIDZBHWuKejZhdjHfjeNvZ2vLoQKBgQDJzLmkVLvWAxgl1yvF +U7gwqj/TzYqtVowbjEvTNEnPU1j/hIVI343SVV/EvJmif/iRUop6sRYfLsUjpMsH +CmPysNKL3UtgSYOxLs+0xLhG4OOQRpPSf/uvl9YyWY9G3AqiC7ScthkQjEhZa4c1 +eycYy0jr42kX0OL9MuIH9q0ENQKBgQDCzvGKMs8r5E/Qd3YB9VYB60dx+6G83AHZ +YqIelykObhCdxL9n4K+p4VKKLvgTcCOLYYIkBSWRJWR+ue3s3ey9+XWd2/q4Xvfh +TCjAuO2ibMV+y5ClNlW0fQ/doIVWSDbjO2tZW1jh7YWZ4CtuVrsEisv1sk3KltMB +MguhpTUylQKBgG6TfrncMFzxrx61C+gBmvEXqQffHfkjbnx94OKnSTaQ3jiNHhez +X9v8KhD8o1bWtpay2uyl8pA9qYqBdzqxZ9kJKSW4qd/mCIJjOy87iBpWint5IPD8 +biZmldlbF9ZlJnJq5ZnlclCN/er5r8oPZHoCkj+nieOh8294nUBt25ptAoGAMnPA +EIeaKgbmONpHgLhWPwb9KOL/f1cHT5KA5CVH58nPmdyTqcaCGCAX7Vu+ueIIApgN +SWDf2thxT3S9zuOm5YiO0oRfSZKm5f2AbHE4ciFzgKQd4PvSdH0TN9XT0oW/WVhR +NAI5YcHPIQvyk4/4vXNo4Uf9Z6NqIFwisQmFXoUCgYBK/ZI/HsFsvnR5MV0tFdGM +AdNe6bsQRSZkowoaPxuWbklE4Hn6QvwEmQg3ST2O+vCQV1f1yI6YiWYoptOYscJc +MSs/HxhhaaO5ZsiuPUO6WEPzpNb2CxuIGDDtl83VtUQyjxCmOb6pqqjwzFmZ2bsw +JNMaBCzokrJTxknvauCuSQ== +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDZDCCAkygAwIBAgIJANod1+h9CtCaMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJJTDEPMA0GA1UECgwGQXBhY2hlMRowGAYDVQQDDBFy +YW5kb20uc2VydmVyLmNvbTAeFw0xODExMTkxNzEwMTlaFw0yODExMTYxNzEwMTla +MEcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJJTDEPMA0GA1UECgwGQXBhY2hlMRow +GAYDVQQDDBFyYW5kb20uc2VydmVyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAJmQRdKVn5kUoWAI+lwMbf17vcG4roTm4TfyrY8eHgNXTFywmchT +HnW+Kos/Bi6CHF8/RysfIF1egdV1b/dZfiCmIat2Iz928Ki6F6jQM9qpRQnadkpV +iHYznujJ6K4mJ2UpvsEaR/DcdY/1NXt1XIZaiT9yjCOimposclbGD+SHYqq9QEPQ +Ie30p3Ve+BdWYfATu8K/SPmjC/YxoTFOwVvXq5aZUuGXWA0cjZGoJfbItp5sfUO+ +1suuK3VcSuO1pJh4kT1yVVFqpPq+y8s6HIHm0D1Z9mp8Fiv8wcN5dB+tsh/7gKnd +pOmrmCtzkicgwwfR46Tr9//i1b6erWV+zNkCAwEAAaNTMFEwHQYDVR0OBBYEFI2y +qm0+UAChDAnLrAINeFOuyUlhMB8GA1UdIwQYMBaAFI2yqm0+UAChDAnLrAINeFOu +yUlhMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAA3ZNFbqxcOX +szS5A4EXCepyBJBFejEYy0CsvwQX/ai/pMrw5jqVeF0GAOTpBCVLddyY+ZV1arD2 +Pqi7Qwot9OxEZOzbCBiuMJGotruKgnWFQDHzJ9HA7KDQs270uNESAOG/xW9os9zN +MXApzqfBSR5EIQU5L3RtaiPzoKdQenGQUOj86s0Kon7snDSUzaA2VcfstMWgGvXP +JHtaVusULm0gry32cEap5G5UK+gII6DfLWgFwFGhHHmTz3mKjyGiJQ+09XBtu4lb +ENE+HGRBBA49dUKSr3kwErO4HyHnS0YrsTDnbYURCsGUDma12oijX2sCos6Q4zn8 +3svaouRrucw= +-----END CERTIFICATE----- diff --git a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py index 5051a993ea7..e692c471d55 100644 --- a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py +++ b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py @@ -27,71 +27,11 @@ ) # Configure the origin server. -server = Test.MakeOriginServer("server", both=True) - -request_header = {"headers": "GET /one HTTP/1.1\r\n" - "Host: www.notls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -response_header = {"headers": "HTTP/1.1 200 OK" - "\r\nConnection: close\r\nContent-Length: 0" - "\r\nSet-Cookie: classified_not_for_logging\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_header) -request_header = {"headers": "GET /two HTTP/1.1\r\n" - "Host: www.notls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -response_header = {"headers": "HTTP/1.1 200 OK" - "\r\nConnection: close\r\nContent-Length: 0" - "\r\nSet-Cookie: classified_not_for_logging\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_header) -request_header = {"headers": "GET /three HTTP/1.1\r\n" - "Host: www.notls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -response_header = {"headers": "HTTP/1.1 200 OK" - "\r\nConnection: close\r\nContent-Length: 0" - "\r\nSet-Cookie: classified_not_for_logging\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_header) -request_header = {"headers": "GET /post_with_body HTTP/1.1\r\n" - "Host: www.notls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -response_200 = {"headers": "HTTP/1.1 200 OK" - "\r\nConnection: close\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_200) -request_header = {"headers": "GET /cache_test HTTP/1.1\r\n" - "Host: www.notls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -response_header = {"headers": "HTTP/1.1 200 OK" - "\r\nConnection: close\r\nCache-Control: max-age=300\r\n" - "Content-Length: 4\r\n\r\n", - "timestamp": "1469733493.993", "body": "1234"} -server.addResponse("sessionfile.log", request_header, response_header) -request_header = {"headers": "GET /first HTTP/1.1\r\n" - "Host: www.notls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_200) -request_header = {"headers": "GET /second HTTP/1.1\r\n" - "Host: www.notls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_200) -request_header = {"headers": "GET /tls HTTP/1.1\r\n" - "Host: www.tls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_200) -request_header = {"headers": "GET /h2_first HTTP/2\r\n" - "Host: www.tls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_200) -request_header = {"headers": "GET /h2_second HTTP/2\r\n" - "Host: www.tls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_200) -request_header = {"headers": "GET /client_only_tls HTTP/1.1\r\n" - "Host: www.client_only_tls.com\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_200) +replay_file = "replay/traffic_dump.yaml" +server = Test.MakeVerifierServerProcess( + "server", replay_file, + ssl_cert="ssl/server_combined.pem", ca_cert="ssl/signer.pem") + # Define ATS and configure it. ts = Test.MakeATSProcess("ts", enable_tls=True) @@ -124,13 +64,13 @@ ) ts.Disk.remap_config.AddLine( - 'map https://www.client_only_tls.com/ http://127.0.0.1:{0}'.format(server.Variables.Port) + 'map https://www.client_only_tls.com/ http://127.0.0.1:{0}'.format(server.Variables.http_port) ) ts.Disk.remap_config.AddLine( - 'map https://www.tls.com/ https://127.0.0.1:{0}'.format(server.Variables.SSL_Port) + 'map https://www.tls.com/ https://127.0.0.1:{0}'.format(server.Variables.https_port) ) ts.Disk.remap_config.AddLine( - 'map / http://127.0.0.1:{0}'.format(server.Variables.Port) + 'map / http://127.0.0.1:{0}'.format(server.Variables.http_port) ) # Configure traffic_dump. @@ -186,38 +126,27 @@ replay_file_session_10 = os.path.join(replay_dir, "127", "0000000000000009") ts.Disk.File(replay_file_session_10, exists=True) -# -# Test 1: Verify the correct behavior of two transactions across two sessions. -# - -# Execute the first transaction. -tr = Test.AddTestRun("First transaction") - -tr.Processes.Default.StartBefore(server, ready=When.PortOpen(server.Variables.Port)) -tr.Processes.Default.StartBefore(Test.Processes.ts) -tr.Processes.Default.Command = \ - ('curl --http1.1 http://127.0.0.1:{0}/one -H"Cookie: donotlogthis" ' - '-H"Host: www.notls.com" -H"X-Request-1: ultra_sensitive" --verbose'.format( - ts.Variables.port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/200.gold" +# Execute the first transaction. We limit the threads to 1 so that the sessions +# are run in serial. +tr = Test.AddTestRun("Run the test traffic.") +tr.AddVerifierClientProcess( + "client", replay_file, http_ports=[ts.Variables.port], + https_ports=[ts.Variables.ssl_port], + ssl_cert="ssl/server_combined.pem", ca_cert="ssl/signer.pem", + other_args='--thread-limit 1') + +tr.Processes.Default.StartBefore(server) +tr.Processes.Default.StartBefore(ts) tr.StillRunningAfter = server tr.StillRunningAfter = ts -http_protocols = "tcp,ip" -# Execute the second transaction. -tr = Test.AddTestRun("Second transaction") -tr.Processes.Default.Command = \ - ('curl --http1.0 http://127.0.0.1:{0}/two -H"Host: www.notls.com" ' - '-H"X-Request-2: also_very_sensitive" --verbose'.format( - ts.Variables.port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/200_http10.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts +# +# Test 1: Verify the correct behavior of two transactions across two sessions. +# # Verify the properties of the replay file for the first transaction. tr = Test.AddTestRun("Verify the json content of the first session") +http_protocols = "tcp,ip" verify_replay = "verify_replay.py" sensitive_fields_arg = ( "--sensitive-fields cookie " @@ -241,7 +170,7 @@ tr = Test.AddTestRun("Verify the json content of the second session") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) tr.Processes.Default.Command = \ - ('python3 {0} {1} {2} {3} --client-http-version "1.0" ' + ('python3 {0} {1} {2} {3} --client-http-version "1.1" ' '--request-target "/two"'.format( verify_replay, os.path.join(Test.Variables.AtsTestToolsDir, 'lib', 'replay_schema.json'), @@ -255,18 +184,7 @@ # Test 2: Verify the correct behavior of an explicit path in the request line. # -# Verify that an explicit path in the request line is recorded. -tr = Test.AddTestRun("Make a request with an explicit target.") -request_target = "http://localhost:{0}/candy".format(ts.Variables.port) -tr.Processes.Default.Command = ( - 'curl --request-target "{0}" ' - 'http://127.0.0.1:{1}/three -H"Host: www.notls.com" --verbose'.format( - request_target, ts.Variables.port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/explicit_target.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - +# Verify recording of a request target with the host specified. tr = Test.AddTestRun("Verify the replay file has the explicit target.") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) @@ -275,7 +193,7 @@ os.path.join(Test.Variables.AtsTestToolsDir, 'lib', 'replay_schema.json'), replay_file_session_3, sensitive_fields_arg, - request_target) + "http://www.some.host.com/candy") tr.Processes.Default.ReturnCode = 0 tr.StillRunningAfter = server tr.StillRunningAfter = ts @@ -284,31 +202,18 @@ # Test 3: Verify correct handling of a POST with body data. # -tr = Test.AddTestRun("Make a POST request with a body.") -request_target = "http://localhost:{0}/post_with_body".format(ts.Variables.port) - -# Send the replay file as the request body because it is conveniently already -# in the test run directory. -tr.Processes.Default.Command = ( - 'curl --data-binary @{0} --request-target "{1}" ' - 'http://127.0.0.1:{2} -H"Host: www.notls.com" --verbose'.format( - verify_replay, request_target, ts.Variables.port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/post_with_body.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - -tr = Test.AddTestRun("Verify the client-request size node has the expected value.") +tr = Test.AddTestRun("Verify the client-request size node for a request with a body.") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) size_of_verify_replay_file = os.path.getsize(os.path.join(Test.TestDirectory, verify_replay)) +expected_body_size = 12345 tr.Processes.Default.Command = \ "python3 {0} {1} {2} {3} --client-request-size {4}".format( verify_replay, os.path.join(Test.Variables.AtsTestToolsDir, 'lib', 'replay_schema.json'), replay_file_session_4, sensitive_fields_arg, - size_of_verify_replay_file) + expected_body_size) tr.Processes.Default.ReturnCode = 0 tr.StillRunningAfter = server tr.StillRunningAfter = ts @@ -316,24 +221,6 @@ # # Test 4: Verify correct handling of a response produced out of the cache. # -tr = Test.AddTestRun("Make a request for an uncached object.") -tr.Processes.Default.Command = \ - ('curl --http1.1 http://127.0.0.1:{0}/cache_test -H"Host: www.notls.com" --verbose'.format( - ts.Variables.port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/4_byte_response_body.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - -tr = Test.AddTestRun("Repeat the previous request: should be cached now.") -tr.Processes.Default.Command = \ - ('curl --http1.1 http://127.0.0.1:{0}/cache_test -H"Host: www.notls.com" --verbose'.format( - ts.Variables.port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/4_byte_response_body.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - tr = Test.AddTestRun("Verify that the cached response's replay file looks appropriate.") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) tr.Processes.Default.Command = 'python3 {0} {1} {2} --client-protocols "{3}"'.format( @@ -348,17 +235,7 @@ # # Test 5: Verify correct handling of two transactions in a session. # -tr = Test.AddTestRun("Conduct two transactions in the same session.") -tr.Processes.Default.Command = \ - ('curl --http1.1 http://127.0.0.1:{0}/first -H"Host: www.notls.com" --verbose --next ' - 'curl --http1.1 http://127.0.0.1:{0}/second -H"Host: www.notls.com" --verbose' - .format(ts.Variables.port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/two_transactions.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - -tr = Test.AddTestRun("Verify that the dump file can be read.") +tr = Test.AddTestRun("Verify the dump file of two transactions in a session.") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) tr.Processes.Default.Command = 'python3 {0} {1} {2} --client-protocols "{3}"'.format( verify_replay, @@ -372,17 +249,7 @@ # # Test 6: Verify correct protcol dumping of a TLS connection. # -tr = Test.AddTestRun("Perform an HTTP/1 transaction over a TLS connection.") -tr.Processes.Default.Command = \ - ('curl --http1.1 -k -H"Host: www.tls.com" --resolve "www.tls.com:{0}:127.0.0.1" ' - '--cert ./signed-foo.pem --key ./signed-foo.key --verbose https://www.tls.com:{0}/tls'.format( - ts.Variables.ssl_port)) - -tr.Processes.Default.ReturnCode = 0 -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - -tr = Test.AddTestRun("Verify the client protocol stack.") +tr = Test.AddTestRun("Verify the client protocol stack of a TLS session.") https_protocols = "tls,tcp,ip" client_tls_features = "sni:www.tls.com,proxy-verify-mode:0,proxy-provided-cert:true" tr.Setup.CopyAs(verify_replay, Test.RunDirectory) @@ -396,7 +263,7 @@ tr.StillRunningAfter = server tr.StillRunningAfter = ts -tr = Test.AddTestRun("Verify the server protocol stack.") +tr = Test.AddTestRun("Verify the server TLS protocol stack.") https_server_stack = "http,tls,tcp,ip" tr.Setup.CopyAs(verify_replay, Test.RunDirectory) server_tls_features = 'proxy-provided-cert:false,sni:www.tls.com,proxy-verify-mode:1' @@ -413,19 +280,7 @@ # # Test 7: Verify correct protcol dumping of TLS and HTTP/2 connections. # -tr = Test.AddTestRun("Conduct two HTTP/2 transactions over a TLS connection.") -tr.Processes.Default.Command = \ - ('curl --http2 -k -H"Host: www.tls.com" --resolve "www.tls.com:{0}:127.0.0.1" ' - '--cert ./signed-foo.pem --key ./signed-foo.key --verbose https://www.tls.com:{0}/h2_first ' - '--next --http2 -k -H"Host: www.tls.com" --resolve "www.tls.com:{0}:127.0.0.1" ' - '--cert ./signed-foo.pem --key ./signed-foo.key --verbose https://www.tls.com:{0}/h2_second'.format( - ts.Variables.ssl_port)) - -tr.Processes.Default.ReturnCode = 0 -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - -tr = Test.AddTestRun("Verify the client protocol stack.") +tr = Test.AddTestRun("Verify the client HTTP/2 protocol stack.") h2_protocols = "http,tls,tcp,ip" tr.Setup.CopyAs(verify_replay, Test.RunDirectory) tr.Processes.Default.Command = \ @@ -440,7 +295,7 @@ tr.StillRunningAfter = server tr.StillRunningAfter = ts -tr = Test.AddTestRun("Verify the server protocol stack.") +tr = Test.AddTestRun("Verify the server HTTP/2 protocol stack.") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) tr.Processes.Default.Command = 'python3 {0} {1} {2} --server-protocols "{3}" --server-tls-features "{4}"'.format( verify_replay, @@ -455,19 +310,7 @@ # # Test 8: Verify correct protcol dumping of client-side TLS and server-side HTTP. # -tr = Test.AddTestRun("Conduct a client-side TLS connection with an HTTP server-side connection.") -tr.Processes.Default.Command = \ - ('curl --http1.1 -k -H"Host: www.client_only_tls.com" ' - '--resolve "www.client_only_tls.com:{0}:127.0.0.1" ' - '--cert ./signed-foo.pem --key ./signed-foo.key ' - '--verbose https://www.client_only_tls.com:{0}/client_only_tls'.format( - ts.Variables.ssl_port)) - -tr.Processes.Default.ReturnCode = 0 -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - -tr = Test.AddTestRun("Verify the client protocol stack.") +tr = Test.AddTestRun("Verify the client TLS protocol stack.") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) tr.Processes.Default.Command = 'python3 {0} {1} {2} --client-http-version "1.1" --client-protocols "{3}"'.format( verify_replay, @@ -478,7 +321,7 @@ tr.StillRunningAfter = server tr.StillRunningAfter = ts -tr = Test.AddTestRun("Verify the server protocol stack.") +tr = Test.AddTestRun("Verify the server HTTP protocol stack.") tr.Setup.CopyAs(verify_replay, Test.RunDirectory) http_server_stack = "http,tcp,ip" tr.Processes.Default.Command = 'python3 {0} {1} {2} --server-protocols "{3}"'.format( diff --git a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py index 9d1e8a88b59..43bbdaa3403 100644 --- a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py +++ b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py @@ -26,17 +26,10 @@ Condition.PluginExists('traffic_dump.so'), ) -# Configure the origin server. -server = Test.MakeOriginServer("server") - -request_header = {"headers": "GET / HTTP/1.1\r\n" - "Host: bob\r\nContent-Length: 0\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -response_header = {"headers": "HTTP/1.1 200 OK" - "\r\nConnection: close\r\nContent-Length: 0" - "\r\nSet-Cookie: classified_not_for_logging\r\n\r\n", - "timestamp": "1469733493.993", "body": ""} -server.addResponse("sessionfile.log", request_header, response_header) +replay_file = "replay/various_sni.yaml" +server = Test.MakeVerifierServerProcess( + "server-various-sni", replay_file, + ssl_cert="ssl/server_combined.pem", ca_cert="ssl/signer.pem") # Define ATS and configure ts = Test.MakeATSProcess("ts", select_ports=True, enable_tls=True) @@ -46,9 +39,6 @@ ts.addSSLfile("ssl/server.key") ts.addSSLfile("ssl/signer.pem") -ts.Setup.Copy("ssl/signed-foo.pem") -ts.Setup.Copy("ssl/signed-foo.key") - ts.Disk.records_config.update({ 'proxy.config.diags.debug.enabled': 1, 'proxy.config.diags.debug.tags': 'traffic_dump', @@ -68,20 +58,18 @@ ) ts.Disk.remap_config.AddLine( - 'map / http://127.0.0.1:{0}'.format(server.Variables.Port) + 'map / https://127.0.0.1:{0}'.format(server.Variables.https_port) ) ts.Disk.sni_yaml.AddLines([ 'sni:', - '- fqdn: boblite', - ' verify_client: STRICT', + '- fqdn: bob.com', + ' verify_client: NONE', ' host_sni_policy: PERMISSIVE', - '- fqdn: bob', - ' verify_client: STRICT', ]) -# Configure traffic_dump's SNI filter to only dump connections with SNI bob. -sni_filter = "bob" +# Configure traffic_dump's SNI filter to only dump connections with SNI bob.com. +sni_filter = "bob.com" ts.Disk.plugin_config.AddLine( 'traffic_dump.so --logdir {0} --sample 1 --limit 1000000000 ' '--sni-filter "{1}"'.format(replay_dir, sni_filter) @@ -110,49 +98,23 @@ replay_file_session_2 = os.path.join(replay_dir, "127", "0000000000000002") ts.Disk.File(replay_file_session_2, exists=False) -# -# Test 1: Verify dumping a session with the desired SNI and not dumping -# the session with the other SNI. -# - -# Execute the first transaction with an SNI of bob. -tr = Test.AddTestRun("Verify dumping of a session with the filtered SNI") -tr.Processes.Default.StartBefore(server, ready=When.PortOpen(server.Variables.Port)) -tr.Processes.Default.StartBefore(Test.Processes.ts) -tr.Processes.Default.Command = \ - ('curl --http2 --tls-max 1.2 -k -H"Host: bob" --resolve "bob:{0}:127.0.0.1" ' - '--cert ./signed-foo.pem --key ./signed-foo.key --verbose https://bob:{0}'.format(ts.Variables.ssl_port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/200_sni_bob.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts -session_1_protocols = "http,tls,tcp,ip" -# Observe that the sni.yaml config dictates STRICT as the verify_client -# attribute. -session_1_tls_features = 'sni:bob,proxy-verify-mode:7,proxy-provided-cert:true' - -# Execute the second transaction with an SNI of dave. -tr = Test.AddTestRun("Verify that a session of a different SNI is not dumped.") -tr.Processes.Default.Command = \ - ('curl --tls-max 1.2 -k -H"Host: dave" --resolve "dave:{0}:127.0.0.1" ' - '--cert ./signed-foo.pem --key ./signed-foo.key --verbose https://dave:{0}'.format(ts.Variables.ssl_port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/200_sni_dave.gold" -tr.StillRunningAfter = server -tr.StillRunningAfter = ts - -# Execute the third transaction without any SNI. -tr = Test.AddTestRun("Verify that a session of a non-existent SNI is not dumped.") -tr.Processes.Default.Command = \ - ('curl --tls-max 1.2 -k -H"Host: bob"' - '--cert ./signed-foo.pem --key ./signed-foo.key --verbose https://127.0.0.1:{0}'.format(ts.Variables.ssl_port)) -tr.Processes.Default.ReturnCode = 0 -tr.Processes.Default.Streams.stderr = "gold/200_bob_no_sni.gold" +# Run the traffic with connections containing various SNI values. +tr = Test.AddTestRun("Test SNI filter with various SNI values in the handshakes.") +# Use the same port across the two servers so that the remap config will work +# across both. +server_port = server.Variables.http_port +tr.AddVerifierClientProcess( + "client-various-sni", replay_file, https_ports=[ts.Variables.ssl_port], + ssl_cert="ssl/server_combined.pem", ca_cert="ssl/signer.pem") +tr.Processes.Default.StartBefore(server) +tr.Processes.Default.StartBefore(ts) tr.StillRunningAfter = server tr.StillRunningAfter = ts # Verify the properties of the replay file for the dumped transaction. tr = Test.AddTestRun("Verify the json content of the first session") +session_1_protocols = "http,tls,tcp,ip" +session_1_tls_features = 'sni:bob.com,proxy-verify-mode:0,proxy-provided-cert:true' verify_replay = "verify_replay.py" tr.Setup.CopyAs(verify_replay, Test.RunDirectory) tr.Processes.Default.Command = 'python3 {0} {1} {2} --client-protocols "{3}" --client-tls-features "{4}"'.format( @@ -162,5 +124,3 @@ session_1_protocols, session_1_tls_features) tr.Processes.Default.ReturnCode = 0 -tr.StillRunningAfter = server -tr.StillRunningAfter = ts