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

[trafficserver] branch 8.0.x updated (ad6fa96 -> ea34099)

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

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


    from ad6fa96  Bumped version to 8.0.2, and updated STATUS
     new 9a5b3c0  sslheaders experimental plugin:  fix doc typo, improve container use.
     new ea34099  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      | 82 ++++++++++++++-----
 plugins/experimental/sslheaders/sslheaders.h       |  8 +-
 .../observer.py}                                   | 11 ++-
 .../pluginTest/sslheaders/ssl/server.key           | 28 +++++++
 .../pluginTest/sslheaders/ssl/server.pem           | 21 +++++
 .../pluginTest/sslheaders/sslheaders.gold          |  1 +
 .../pluginTest/sslheaders/sslheaders.test.py       | 91 ++++++++++++++++++++++
 9 files changed, 218 insertions(+), 28 deletions(-)
 copy tests/gold_tests/pluginTest/{compress/compress_observer.py => sslheaders/observer.py} (78%)
 mode change 100755 => 100644
 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 bc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9a5b3c023e16390562116343dc8bea059d3c77eb
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)
---
 doc/admin-guide/plugins/sslheaders.en.rst     |  2 +-
 plugins/experimental/sslheaders/sslheaders.cc | 18 ++++++++----------
 plugins/experimental/sslheaders/sslheaders.h  |  8 +++++---
 3 files changed, 14 insertions(+), 14 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 085c7ac..6c6838d 100644
--- a/plugins/experimental/sslheaders/sslheaders.cc
+++ b/plugins/experimental/sslheaders/sslheaders.cc
@@ -124,14 +124,14 @@ SslHdrExpand(SSL *ssl, const SslHdrInstance::expansion_list &expansions, TSMBuff
 {
   if (ssl == nullptr) {
     for (const auto &expansion : expansions) {
-      SslHdrRemoveHeader(mbuf, mhdr, expansion->name);
+      SslHdrRemoveHeader(mbuf, mhdr, expansion.name);
     }
   } else {
     X509 *x509;
     BIO *exp = BIO_new(BIO_s_mem());
 
     for (const auto &expansion : expansions) {
-      switch (expansion->scope) {
+      switch (expansion.scope) {
       case SSL_HEADERS_SCOPE_CLIENT:
         x509 = SSL_get_peer_certificate(ssl);
         break;
@@ -146,15 +146,15 @@ SslHdrExpand(SSL *ssl, const SslHdrInstance::expansion_list &expansions, TSMBuff
         continue;
       }
 
-      SslHdrExpandX509Field(exp, x509, expansion->field);
+      SslHdrExpandX509Field(exp, x509, expansion.field);
       if (BIO_pending(exp)) {
-        SslHdrSetHeader(mbuf, mhdr, expansion->name, exp);
+        SslHdrSetHeader(mbuf, mhdr, expansion.name, exp);
       } else {
-        SslHdrRemoveHeader(mbuf, mhdr, expansion->name);
+        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) {
+      if (x509 && expansion.scope == SSL_HEADERS_SCOPE_CLIENT) {
         X509_free(x509);
       }
     }
@@ -199,14 +199,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 b7b66dd..ff72100 100644
--- a/plugins/experimental/sslheaders/sslheaders.h
+++ b/plugins/experimental/sslheaders/sslheaders.h
@@ -19,7 +19,7 @@
 #include <ts/ts.h>
 #include <ts/remap.h>
 #include <cstring>
-#include <list>
+#include <vector>
 #include <string>
 
 extern "C" {
@@ -67,13 +67,15 @@ struct SslHdrExpansion {
   ExpansionScope scope;
   ExpansionField field;
 
-  // noncopyable
+  // 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 bc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ea340992f25a6b4ec905a8ce192604006a216211
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/expand.cc          |  2 +-
 plugins/experimental/sslheaders/sslheaders.cc      | 66 +++++++++++++---
 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       | 91 ++++++++++++++++++++++
 7 files changed, 228 insertions(+), 12 deletions(-)

diff --git a/plugins/experimental/sslheaders/expand.cc b/plugins/experimental/sslheaders/expand.cc
index 15b20d6..d271837 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 6c6838d..657a9cd 100644
--- a/plugins/experimental/sslheaders/sslheaders.cc
+++ b/plugins/experimental/sslheaders/sslheaders.cc
@@ -116,6 +116,49 @@ 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 +170,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 +201,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/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..26c3a43
--- /dev/null
+++ b/tests/gold_tests/pluginTest/sslheaders/sslheaders.test.py
@@ -0,0 +1,91 @@
+'''
+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.ssl_server_name_yaml.AddLines([
+    '- fqdn: "*bar.com"',
+    '  verify_client: STRICT',
+])
+
+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