You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2019/01/08 17:50:49 UTC

[trafficserver] branch 7.1.x updated (5a238e5 -> c1559a6)

This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a change to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git.


    from 5a238e5  Doc: Repair various format errors. Tweak traffic-server.py support for Python 3.
     new b8bb380  sslheaders experimental plugin:  fix doc typo, improve container use.
     new c1559a6  Make sslheaders plugin better conform to documentation.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 doc/admin-guide/plugins/sslheaders.en.rst          |  2 +-
 plugins/experimental/sslheaders/expand.cc          |  2 +-
 plugins/experimental/sslheaders/sslheaders.cc      | 71 ++++++++++++++----
 plugins/experimental/sslheaders/sslheaders.h       | 13 ++--
 .../pluginTest/sslheaders/observer.py}             | 22 +++---
 .../pluginTest/sslheaders/ssl/server.key           | 28 +++++++
 .../pluginTest/sslheaders/ssl/server.pem           | 21 ++++++
 .../pluginTest/sslheaders/sslheaders.gold          |  1 +
 .../pluginTest/sslheaders/sslheaders.test.py       | 86 ++++++++++++++++++++++
 9 files changed, 213 insertions(+), 33 deletions(-)
 copy tests/{tools/traffic-replay/Config.py => gold_tests/pluginTest/sslheaders/observer.py} (70%)
 create mode 100644 tests/gold_tests/pluginTest/sslheaders/ssl/server.key
 create mode 100644 tests/gold_tests/pluginTest/sslheaders/ssl/server.pem
 create mode 100644 tests/gold_tests/pluginTest/sslheaders/sslheaders.gold
 create mode 100644 tests/gold_tests/pluginTest/sslheaders/sslheaders.test.py


[trafficserver] 01/02: sslheaders experimental plugin: fix doc typo, improve container use.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit b8bb3807d3c67126b050584707f9dd82da43ae4b
Author: Walter Karas <wk...@oath.com>
AuthorDate: Mon Dec 10 12:12:24 2018 -0600

    sslheaders experimental plugin:  fix doc typo, improve container use.
    
    (cherry picked from commit 9da865baad311542ecd4142a7a111b6e7e46c595)
    
    Conflicts:
    plugins/experimental/sslheaders/sslheaders.cc
    plugins/experimental/sslheaders/sslheaders.h
    
    WARNING:  This commit is present only to record the cherry-pick, otherwise it is useless/non-functional.
---
 doc/admin-guide/plugins/sslheaders.en.rst     |  2 +-
 plugins/experimental/sslheaders/sslheaders.cc |  6 ++----
 plugins/experimental/sslheaders/sslheaders.h  | 14 ++++++++------
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/doc/admin-guide/plugins/sslheaders.en.rst b/doc/admin-guide/plugins/sslheaders.en.rst
index 8fc0881..49a8777 100644
--- a/doc/admin-guide/plugins/sslheaders.en.rst
+++ b/doc/admin-guide/plugins/sslheaders.en.rst
@@ -66,7 +66,7 @@ The `client.certificate` and `server.certificate` fields emit
 the corresponding certificate in PEM format, with newline characters
 replaced by spaces.
 
-If the ``sslheaders`` plugin activtes on non-SSL connections, it
+If the ``sslheaders`` plugin activates on non-SSL connections, it
 will delete all the configured HTTP header names so that malicious
 clients cannot inject misleading information. If any of the SSL
 fields expand to an empty string, those headers are also deleted.
diff --git a/plugins/experimental/sslheaders/sslheaders.cc b/plugins/experimental/sslheaders/sslheaders.cc
index 850f97d..100a27e 100644
--- a/plugins/experimental/sslheaders/sslheaders.cc
+++ b/plugins/experimental/sslheaders/sslheaders.cc
@@ -198,14 +198,12 @@ SslHdrParseOptions(int argc, const char **argv)
   }
 
   // Pick up the remaining options as SSL header expansions.
+  hdr->expansions.resize(argc - optind);
   for (int i = optind; i < argc; ++i) {
-    SslHdrExpansion exp;
-    if (!SslHdrParseExpansion(argv[i], exp)) {
+    if (!SslHdrParseExpansion(argv[i], hdr->expansions[i - optind])) {
       // If we fail, the expansion parsing logs the error.
       return nullptr;
     }
-
-    hdr->expansions.push_back(exp);
   }
 
   return hdr.release();
diff --git a/plugins/experimental/sslheaders/sslheaders.h b/plugins/experimental/sslheaders/sslheaders.h
index 6d43011..9cc2d62 100644
--- a/plugins/experimental/sslheaders/sslheaders.h
+++ b/plugins/experimental/sslheaders/sslheaders.h
@@ -18,9 +18,8 @@
 
 #include <ts/ts.h>
 #include <ts/remap.h>
-#include <string.h>
-#include <list>
-#include <string>
+#include <cstring>
+#include <vector>
 
 extern "C" {
 typedef struct x509_st X509;
@@ -67,12 +66,15 @@ struct SslHdrExpansion {
   ExpansionScope scope;
   ExpansionField field;
 
-private:
-  SslHdrExpansion &operator=(const SslHdrExpansion &);
+  // noncopyable but moveable
+  SslHdrExpansion(const SslHdrExpansion &) = delete;
+  SslHdrExpansion &operator=(const SslHdrExpansion &) = delete;
+  SslHdrExpansion(SslHdrExpansion &&)                 = default;
+  SslHdrExpansion &operator=(SslHdrExpansion &&) = default;
 };
 
 struct SslHdrInstance {
-  typedef std::list<SslHdrExpansion> expansion_list;
+  typedef std::vector<SslHdrExpansion> expansion_list;
 
   SslHdrInstance();
   ~SslHdrInstance();


[trafficserver] 02/02: Make sslheaders plugin better conform to documentation.

Posted by zw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit c1559a654a42fc469be133319c1bd6cda995aea7
Author: Walter Karas <wk...@oath.com>
AuthorDate: Mon Dec 10 11:36:59 2018 -0600

    Make sslheaders plugin better conform to documentation.
    
    (cherry picked from commit 7f63d1630a11cd324b8ebdd606d896a5b475c279)
    
    Conflicts:
    plugins/experimental/sslheaders/expand.cc
    plugins/experimental/sslheaders/sslheaders.h
    tests/gold_tests/pluginTest/sslheaders/sslheaders.test.py
---
 plugins/experimental/sslheaders/expand.cc          |  2 +-
 plugins/experimental/sslheaders/sslheaders.cc      | 65 +++++++++++++---
 plugins/experimental/sslheaders/sslheaders.h       |  1 +
 tests/gold_tests/pluginTest/sslheaders/observer.py | 31 ++++++++
 .../pluginTest/sslheaders/ssl/server.key           | 28 +++++++
 .../pluginTest/sslheaders/ssl/server.pem           | 21 ++++++
 .../pluginTest/sslheaders/sslheaders.gold          |  1 +
 .../pluginTest/sslheaders/sslheaders.test.py       | 86 ++++++++++++++++++++++
 8 files changed, 223 insertions(+), 12 deletions(-)

diff --git a/plugins/experimental/sslheaders/expand.cc b/plugins/experimental/sslheaders/expand.cc
index 142a98e..6a6f822 100644
--- a/plugins/experimental/sslheaders/expand.cc
+++ b/plugins/experimental/sslheaders/expand.cc
@@ -114,7 +114,7 @@ static const x509_expansion expansions[SSL_HEADERS_FIELD_MAX] = {
   x509_expand_serial,      // SSL_HEADERS_FIELD_SERIAL
   x509_expand_signature,   // SSL_HEADERS_FIELD_SIGNATURE
   x509_expand_notbefore,   // SSL_HEADERS_FIELD_NOTBEFORE
-  x509_expand_notafter,    // SSL_HEADERS_FIELD_NOTBEFORE
+  x509_expand_notafter,    // SSL_HEADERS_FIELD_NOTAFTER
 };
 
 bool
diff --git a/plugins/experimental/sslheaders/sslheaders.cc b/plugins/experimental/sslheaders/sslheaders.cc
index 100a27e..7cb6638 100644
--- a/plugins/experimental/sslheaders/sslheaders.cc
+++ b/plugins/experimental/sslheaders/sslheaders.cc
@@ -116,6 +116,48 @@ SslHdrSetHeader(TSMBuffer mbuf, TSMLoc mhdr, const std::string &name, BIO *value
   }
 }
 
+namespace
+{
+template <bool IsClient> class WrapX509
+{
+public:
+  WrapX509(SSL *ssl) : _ssl(ssl), _x509(_nonNullInvalidValue()) {}
+  X509 *
+  get()
+  {
+    if (_x509 == _nonNullInvalidValue()) {
+      _set();
+    }
+
+    return _x509;
+  }
+
+  ~WrapX509()
+  {
+    if (IsClient && (_x509 != _nonNullInvalidValue()) && (_x509 != nullptr)) {
+      X509_free(_x509);
+    }
+  }
+
+private:
+  SSL *_ssl;
+  X509 *_x509;
+
+  // The address of this object can not be a valid X509 structure address.
+  X509 *
+  _nonNullInvalidValue() const
+  {
+    return reinterpret_cast<X509 *>(const_cast<WrapX509 *>(this));
+  }
+
+  void
+  _set()
+  {
+    _x509 = (IsClient ? SSL_get_peer_certificate : SSL_get_certificate)(_ssl);
+  }
+};
+} // end anonymous namespace
+
 // Process SSL header expansions. If this is not an SSL connection, then we need to delete the SSL headers
 // so that malicious clients cannot inject bogus information. Otherwise, we populate the header with the
 // expanded value. If the value expands to something empty, we nuke the header.
@@ -127,22 +169,28 @@ SslHdrExpand(SSL *ssl, const SslHdrInstance::expansion_list &expansions, TSMBuff
       SslHdrRemoveHeader(mbuf, mhdr, expansion.name);
     }
   } else {
+    WrapX509<true> clientX509(ssl);
+    WrapX509<false> serverX509(ssl);
     X509 *x509;
+
     BIO *exp = BIO_new(BIO_s_mem());
 
     for (const auto &expansion : expansions) {
       switch (expansion.scope) {
       case SSL_HEADERS_SCOPE_CLIENT:
-        x509 = SSL_get_peer_certificate(ssl);
+        x509 = clientX509.get();
+        if (x509 == nullptr) {
+          SslHdrRemoveHeader(mbuf, mhdr, expansion.name);
+          continue;
+        }
         break;
       case SSL_HEADERS_SCOPE_SERVER:
-        x509 = SSL_get_certificate(ssl);
+        x509 = serverX509.get();
+        if (x509 == nullptr) {
+          continue;
+        }
         break;
       default:
-        x509 = nullptr;
-      }
-
-      if (x509 == nullptr) {
         continue;
       }
 
@@ -152,11 +200,6 @@ SslHdrExpand(SSL *ssl, const SslHdrInstance::expansion_list &expansions, TSMBuff
       } else {
         SslHdrRemoveHeader(mbuf, mhdr, expansion.name);
       }
-
-      // Getting the peer certificate takes a reference count, but the server certificate doesn't.
-      if (x509 && expansion.scope == SSL_HEADERS_SCOPE_CLIENT) {
-        X509_free(x509);
-      }
     }
 
     BIO_free(exp);
diff --git a/plugins/experimental/sslheaders/sslheaders.h b/plugins/experimental/sslheaders/sslheaders.h
index 9cc2d62..3e4a407 100644
--- a/plugins/experimental/sslheaders/sslheaders.h
+++ b/plugins/experimental/sslheaders/sslheaders.h
@@ -20,6 +20,7 @@
 #include <ts/remap.h>
 #include <cstring>
 #include <vector>
+#include <string>
 
 extern "C" {
 typedef struct x509_st X509;
diff --git a/tests/gold_tests/pluginTest/sslheaders/observer.py b/tests/gold_tests/pluginTest/sslheaders/observer.py
new file mode 100644
index 0000000..673a56e
--- /dev/null
+++ b/tests/gold_tests/pluginTest/sslheaders/observer.py
@@ -0,0 +1,31 @@
+'''
+Extract ssl-* headers and store in a log file for later verification.
+'''
+#  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.
+
+log = open('sslheaders.log', 'w')
+
+def observe(headers):
+
+    for h in headers.items():
+        if h[0].lower().startswith('ssl-'):
+
+            log.write(h[0] + ": " + h[1] + "\n");
+    log.write("-\n")
+    log.flush()
+
+Hooks.register(Hooks.ReadRequestHook, observe)
diff --git a/tests/gold_tests/pluginTest/sslheaders/ssl/server.key b/tests/gold_tests/pluginTest/sslheaders/ssl/server.key
new file mode 100644
index 0000000..9cdfc36
--- /dev/null
+++ b/tests/gold_tests/pluginTest/sslheaders/ssl/server.key
@@ -0,0 +1,28 @@
+-----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-----
diff --git a/tests/gold_tests/pluginTest/sslheaders/ssl/server.pem b/tests/gold_tests/pluginTest/sslheaders/ssl/server.pem
new file mode 100644
index 0000000..2b56cc8
--- /dev/null
+++ b/tests/gold_tests/pluginTest/sslheaders/ssl/server.pem
@@ -0,0 +1,21 @@
+-----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/sslheaders/sslheaders.gold b/tests/gold_tests/pluginTest/sslheaders/sslheaders.gold
new file mode 100644
index 0000000..39cdd0d
--- /dev/null
+++ b/tests/gold_tests/pluginTest/sslheaders/sslheaders.gold
@@ -0,0 +1 @@
+-
diff --git a/tests/gold_tests/pluginTest/sslheaders/sslheaders.test.py b/tests/gold_tests/pluginTest/sslheaders/sslheaders.test.py
new file mode 100644
index 0000000..58040a7
--- /dev/null
+++ b/tests/gold_tests/pluginTest/sslheaders/sslheaders.test.py
@@ -0,0 +1,86 @@
+'''
+Test the sslheaders plugin.
+'''
+#  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.
+
+Test.Summary = '''
+Test sslheaders plugin.
+'''
+
+Test.SkipUnless(
+    Condition.HasATSFeature('TS_USE_TLS_ALPN'),
+    Condition.HasCurlFeature('http2'),
+)
+
+Test.Disk.File('sslheaders.log').Content = 'sslheaders.gold'
+
+server = Test.MakeOriginServer("server", options={'--load': Test.TestDirectory + '/observer.py'})
+
+request_header = {
+    "headers": "GET / HTTP/1.1\r\nHost: doesnotmatter\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+response_header = {"headers": "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n", "timestamp": "1469733493.993", "body": ""}
+server.addResponse("sessionlog.json", request_header, response_header)
+
+ts = Test.MakeATSProcess("ts", select_ports=False)
+
+ts.addSSLfile("ssl/server.pem")
+ts.addSSLfile("ssl/server.key")
+# ts.addSSLfile("ssl/signer.pem")
+
+ts.Variables.ssl_port = 4443
+
+ts.Disk.records_config.update({
+    'proxy.config.diags.debug.enabled': 0,
+    'proxy.config.diags.debug.tags': 'http',
+    'proxy.config.http.cache.http': 0,  # Make sure each request is forwarded to the origin server.
+    'proxy.config.proxy_name': 'Poxy_Proxy',  # This will be the server name.
+    'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir),
+    'proxy.config.http.server_ports': (
+        'ipv4:{0} ipv4:{1}:proto=http2;http:ssl ipv6:{0} ipv6:{1}:proto=http2;http:ssl'
+        .format(ts.Variables.port, ts.Variables.ssl_port)),
+#    'proxy.config.ssl.client.verify.server':  0,
+#    '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',
+#    'proxy.config.url_remap.pristine_host_hdr' : 1,
+#    'proxy.config.ssl.client.certification_level': 2,
+#    'proxy.config.ssl.CA.cert.filename': '{0}/signer.pem'.format(ts.Variables.SSLDir),
+#    'proxy.config.ssl.TLSv1_3': 0
+})
+
+ts.Disk.ssl_multicert_config.AddLine(
+    'dest_ip=* ssl_cert_name=server.pem ssl_key_name=server.key'
+)
+
+ts.Disk.remap_config.AddLine(
+    'map http://bar.com http://127.0.0.1:{0}'.format(server.Variables.Port)
+)
+ts.Disk.remap_config.AddLine(
+    'map https://bar.com http://127.0.0.1:{0}'.format(server.Variables.Port)
+)
+
+ts.Disk.plugin_config.AddLine(
+    'sslheaders.so SSL-Client-ID=client.subject'
+)
+
+tr = Test.AddTestRun()
+tr.Processes.Default.StartBefore(server)
+tr.Processes.Default.StartBefore(Test.Processes.ts, ready=When.PortOpen(ts.Variables.ssl_port))
+tr.Processes.Default.Command = (
+    'curl -H "SSL-Client-ID: My Fake Client ID" --verbose --ipv4 --insecure --header "Host: bar.com"' +
+    ' https://localhost:{}'.format(ts.Variables.ssl_port)
+)
+tr.Processes.Default.ReturnCode = 0