1''' 2''' 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, software 14# distributed under the License is distributed on an "AS IS" BASIS, 15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16# See the License for the specific language governing permissions and 17# limitations under the License. 18 19Test.Summary = ''' 20Test tunneling based on SNI 21''' 22 23# Define default ATS 24ts = Test.MakeATSProcess("ts", command="traffic_manager", select_ports=True, enable_tls=True) 25server_foo = Test.MakeOriginServer("server_foo", ssl=True) 26server_bar = Test.MakeOriginServer("server_bar", ssl=True) 27server2 = Test.MakeOriginServer("server2") 28#dns = Test.MakeDNServer("dns", default=['127.0.0.1']) 29dns = Test.MakeDNServer("dns") 30 31request_foo_header = {"headers": "GET / HTTP/1.1\r\nHost: foo.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} 32request_bar_header = {"headers": "GET / HTTP/1.1\r\nHost: bar.com\r\n\r\n", "timestamp": "1469733493.993", "body": ""} 33response_foo_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": "foo ok"} 34response_bar_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": "bar ok"} 35server_foo.addResponse("sessionlog.json", request_foo_header, response_foo_header) 36server_bar.addResponse("sessionlog.json", request_bar_header, response_bar_header) 37 38# add ssl materials like key, certificates for the server 39ts.addSSLfile("ssl/signed-foo.pem") 40ts.addSSLfile("ssl/signed-foo.key") 41ts.addSSLfile("ssl/signed-bar.pem") 42ts.addSSLfile("ssl/signed-bar.key") 43ts.addSSLfile("ssl/server.pem") 44ts.addSSLfile("ssl/server.key") 45ts.addSSLfile("ssl/signer.pem") 46ts.addSSLfile("ssl/signer.key") 47 48dns.addRecords(records={"localhost": ["127.0.0.1"]}) 49dns.addRecords(records={"one.testmatch": ["127.0.0.1"]}) 50dns.addRecords(records={"two.example.one": ["127.0.0.1"]}) 51# Need no remap rules. Everything should be processed by sni 52 53# Make sure the TS server certs are different from the origin certs 54ts.Disk.ssl_multicert_config.AddLine( 55 'dest_ip=* ssl_cert_name=signed-foo.pem ssl_key_name=signed-foo.key' 56) 57 58# Case 1, global config policy=permissive properties=signature 59# override for foo.com policy=enforced properties=all 60ts.Disk.records_config.update({ 61 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir), 62 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir), 63 'proxy.config.http.connect_ports': '{0} {1} {2}'.format(ts.Variables.ssl_port, server_foo.Variables.SSL_Port, server_bar.Variables.SSL_Port), 64 'proxy.config.ssl.server.cipher_suite': 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RC4-SHA:RC4-MD5:AES128-SHA:AES256-SHA:DES-CBC3-SHA!SRP:!DSS:!PSK:!aNULL:!eNULL:!SSLv2', 65 'proxy.config.ssl.client.CA.cert.path': '{0}'.format(ts.Variables.SSLDir), 66 'proxy.config.ssl.client.CA.cert.filename': 'signer.pem', 67 'proxy.config.exec_thread.autoconfig.scale': 1.0, 68 'proxy.config.url_remap.pristine_host_hdr': 1, 69 'proxy.config.dns.nameservers': '127.0.0.1:{0}'.format(dns.Variables.Port), 70 'proxy.config.dns.resolv_conf': 'NULL' 71}) 72 73# foo.com should not terminate. Just tunnel to server_foo 74# bar.com should terminate. Forward its tcp stream to server_bar 75# empty SNI should tunnel to server_bar 76ts.Disk.sni_yaml.AddLines([ 77 'sni:', 78 '- fqdn: foo.com', 79 " tunnel_route: localhost:{0}".format(server_foo.Variables.SSL_Port), 80 "- fqdn: bob.*.com", 81 " tunnel_route: localhost:{0}".format(server_foo.Variables.SSL_Port), 82 "- fqdn: '*.match.com'", 83 " tunnel_route: $1.testmatch:{0}".format(server_foo.Variables.SSL_Port), 84 "- fqdn: '*.ok.*.com'", 85 " tunnel_route: $2.example.$1:{0}".format(server_foo.Variables.SSL_Port), 86 "- fqdn: ''", # No SNI sent 87 " tunnel_route: localhost:{0}".format(server_bar.Variables.SSL_Port) 88]) 89 90tr = Test.AddTestRun("foo.com Tunnel-test") 91tr.Processes.Default.Command = "curl -v --resolve 'foo.com:{0}:127.0.0.1' -k https://foo.com:{0}".format(ts.Variables.ssl_port) 92tr.ReturnCode = 0 93tr.Processes.Default.StartBefore(server_foo) 94tr.Processes.Default.StartBefore(server_bar) 95tr.Processes.Default.StartBefore(dns) 96tr.Processes.Default.StartBefore(Test.Processes.ts) 97tr.StillRunningAfter = ts 98tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 99tr.Processes.Default.Streams.All += Testers.ExcludesExpression( 100 "Not Found on Accelerato", "Should not try to remap on Traffic Server") 101tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", "Should not TLS terminate on Traffic Server") 102tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 OK", "Should get a successful response") 103tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not terminate on Traffic Server") 104tr.Processes.Default.Streams.All += Testers.ContainsExpression("foo ok", "Should get a response from bar") 105 106tr = Test.AddTestRun("bob.bar.com Tunnel-test") 107tr.Processes.Default.Command = "curl -v --resolve 'bob.bar.com:{0}:127.0.0.1' -k https://bob.bar.com:{0}".format( 108 ts.Variables.ssl_port) 109tr.ReturnCode = 0 110tr.StillRunningAfter = ts 111tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 112tr.Processes.Default.Streams.All += Testers.ExcludesExpression( 113 "Not Found on Accelerato", "Should not try to remap on Traffic Server") 114tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", "Should not TLS terminate on Traffic Server") 115tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 OK", "Should get a successful response") 116tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not terminate on Traffic Server") 117tr.Processes.Default.Streams.All += Testers.ContainsExpression("foo ok", "Should get a response from bar") 118 119tr = Test.AddTestRun("bar.com no Tunnel-test") 120tr.Processes.Default.Command = "curl -v --resolve 'bar.com:{0}:127.0.0.1' -k https://bar.com:{0}".format(ts.Variables.ssl_port) 121tr.ReturnCode = 0 122tr.StillRunningAfter = ts 123tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 124tr.Processes.Default.Streams.All += Testers.ContainsExpression("Not Found on Accelerato", "Terminates on on Traffic Server") 125tr.Processes.Default.Streams.All += Testers.ContainsExpression("ATS", "Terminate on Traffic Server") 126 127tr = Test.AddTestRun("no SNI Tunnel-test") 128tr.Processes.Default.Command = "curl -v -k https://127.0.0.1:{0}".format(ts.Variables.ssl_port) 129tr.ReturnCode = 0 130tr.StillRunningAfter = ts 131tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 132tr.Processes.Default.Streams.All += Testers.ExcludesExpression( 133 "Not Found on Accelerato", "Should not try to remap on Traffic Server") 134tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 OK", "Should get a successful response") 135tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not terminate on Traffic Server") 136tr.Processes.Default.Streams.All += Testers.ContainsExpression("bar ok", "Should get a response from bar") 137 138 139tr = Test.AddTestRun("one.match.com Tunnel-test") 140tr.Processes.Default.Command = "curl -vvv --resolve 'one.match.com:{0}:127.0.0.1' -k https://one.match.com:{0}".format( 141 ts.Variables.ssl_port) 142tr.ReturnCode = 0 143tr.StillRunningAfter = ts 144tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 145tr.Processes.Default.Streams.All += Testers.ExcludesExpression( 146 "Not Found on Accelerato", "Should not try to remap on Traffic Server") 147tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", "Should not TLS terminate on Traffic Server") 148tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 OK", "Should get a successful response") 149tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not terminate on Traffic Server") 150tr.Processes.Default.Streams.All += Testers.ContainsExpression("foo ok", "Should get a response from tm") 151 152 153tr = Test.AddTestRun("one.ok.two.com Tunnel-test") 154tr.Processes.Default.Command = "curl -vvv --resolve 'one.ok.two.com:{0}:127.0.0.1' -k https:/one.ok.two.com:{0}".format( 155 ts.Variables.ssl_port) 156tr.ReturnCode = 0 157tr.StillRunningAfter = ts 158tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 159tr.Processes.Default.Streams.All += Testers.ExcludesExpression( 160 "Not Found on Accelerato", "Should not try to remap on Traffic Server") 161tr.Processes.Default.Streams.All += Testers.ExcludesExpression("CN=foo.com", "Should not TLS terminate on Traffic Server") 162tr.Processes.Default.Streams.All += Testers.ContainsExpression("HTTP/1.1 200 OK", "Should get a successful response") 163tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Do not terminate on Traffic Server") 164tr.Processes.Default.Streams.All += Testers.ContainsExpression("foo ok", "Should get a response from tm") 165 166 167# Update sni file and reload 168tr = Test.AddTestRun("Update config files") 169# Update the SNI config 170snipath = ts.Disk.sni_yaml.AbsPath 171recordspath = ts.Disk.records_config.AbsPath 172tr.Disk.File(snipath, id="sni_yaml", typename="ats:config"), 173tr.Disk.sni_yaml.AddLines([ 174 'sni:', 175 '- fqdn: bar.com', 176 ' tunnel_route: localhost:{0}'.format(server_bar.Variables.SSL_Port), 177]) 178tr.StillRunningAfter = ts 179tr.StillRunningAfter = server_foo 180tr.StillRunningAfter = server_bar 181tr.Processes.Default.Env = ts.Env 182tr.Processes.Default.Command = 'echo Updated configs' 183tr.Processes.Default.ReturnCode = 0 184 185trreload = Test.AddTestRun("Reload config") 186trreload.StillRunningAfter = ts 187trreload.StillRunningAfter = server_foo 188trreload.StillRunningAfter = server_bar 189trreload.Processes.Default.Command = 'traffic_ctl config reload' 190# Need to copy over the environment so traffic_ctl knows where to find the unix domain socket 191trreload.Processes.Default.Env = ts.Env 192trreload.Processes.Default.ReturnCode = 0 193 194# Should termimate on traffic_server (not tunnel) 195tr = Test.AddTestRun("foo.com no Tunnel-test") 196tr.StillRunningAfter = ts 197# Wait for the reload to complete by running the sni_reload_done test 198tr.Processes.Default.StartBefore(server2, ready=When.FileContains(ts.Disk.diags_log.Name, 'sni.yaml finished loading', 2)) 199tr.Processes.Default.Command = "curl -v --resolve 'foo.com:{0}:127.0.0.1' -k https://foo.com:{0}".format(ts.Variables.ssl_port) 200tr.Processes.Default.Streams.All += Testers.ContainsExpression("Not Found on Accelerato", "Terminates on on Traffic Server") 201tr.Processes.Default.Streams.All += Testers.ContainsExpression("ATS", "Terminate on Traffic Server") 202tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 203tr.TimeOut = 30 204 205# Should tunnel to server_bar 206tr = Test.AddTestRun("bar.com Tunnel-test") 207tr.Processes.Default.Command = "curl -v --resolve 'bar.com:{0}:127.0.0.1' -k https://bar.com:{0}".format(ts.Variables.ssl_port) 208tr.ReturnCode = 0 209tr.StillRunningAfter = ts 210tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Could Not Connect", "Curl attempt should have succeeded") 211tr.Processes.Default.Streams.All += Testers.ExcludesExpression("Not Found on Accelerato", "Terminates on on Traffic Server") 212tr.Processes.Default.Streams.All += Testers.ExcludesExpression("ATS", "Terminate on Traffic Server") 213tr.Processes.Default.Streams.All += Testers.ContainsExpression("bar ok", "Should get a response from bar") 214