You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2017/11/27 17:07:33 UTC
[trafficserver] branch master updated: Doc: Add Layer 4 / SNI
Routing documentation.
This is an automated email from the ASF dual-hosted git repository.
amc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 91f1bb7 Doc: Add Layer 4 / SNI Routing documentation.
91f1bb7 is described below
commit 91f1bb7b54827f80bd5b976e83e25bc86e4e3a3b
Author: Alan M. Carroll <am...@apache.org>
AuthorDate: Tue Nov 21 10:38:04 2017 -0600
Doc: Add Layer 4 / SNI Routing documentation.
---
doc/admin-guide/files/index.en.rst | 6 +-
doc/admin-guide/files/records.config.en.rst | 5 +
.../files/ssl_server_name.config.en.rst | 141 +++++++++++++++++++++
doc/admin-guide/index.en.rst | 2 +-
doc/admin-guide/layer-4-routing.en.rst | 128 +++++++++++++++++++
doc/uml/Makefile | 23 ++++
doc/uml/images/.gitignore | 5 +
doc/uml/images/l4-basic-sequence.svg | 30 +++++
doc/uml/images/l4-example-cdn-layout.svg | 27 ++++
doc/uml/images/l4-sni-routing-seq.svg | 34 +++++
doc/uml/l4-basic-sequence.uml | 24 ++++
doc/uml/l4-example-cdn-layout.uml | 21 +++
doc/uml/l4-sni-routing-seq.uml | 28 ++++
doc/uml/l4-tcp-routing.uml | 23 ++++
14 files changed, 495 insertions(+), 2 deletions(-)
diff --git a/doc/admin-guide/files/index.en.rst b/doc/admin-guide/files/index.en.rst
index e3cee5f..4a158f7 100644
--- a/doc/admin-guide/files/index.en.rst
+++ b/doc/admin-guide/files/index.en.rst
@@ -38,6 +38,7 @@ Configuration Files
remap.config.en
splitdns.config.en
ssl_multicert.config.en
+ ssl_server_name.config.en
storage.config.en
vaddrs.config.en
volume.config.en
@@ -88,9 +89,12 @@ Configuration Files
Configures |TS| to use different server certificates for SSL termination
when listening on multiple addresses or when clients employ SNI.
+:doc:`ssl_server_name.config.en`
+ Configures SNI based Layer 4 routing.
+
:doc:`storage.config.en`
Configures all storage devices and paths to be used for the |TS| cache.
-
+
:doc:`vaddrs.config.en`
Deprecated file formerly used for cluster configuration.
diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst
index 24310a8..3718237 100644
--- a/doc/admin-guide/files/records.config.en.rst
+++ b/doc/admin-guide/files/records.config.en.rst
@@ -3194,6 +3194,11 @@ SSL Termination
``head -c48 /dev/urandom | openssl enc -base64 | head -c48 > file.ticket``. Also
note that OpenSSL session tickets are sensitive to the version of the ca-certificates.
+.. ts:cv:: CONFIG proxy.config.ssl.servername.filename STRING ssl_server_name.config
+
+ The filename of the :file:`ssl_server_name.config` configuration file. If relative, it is relative to the
+ configuration directory (ts:cv:`proxy.config.config_dir`).
+
.. ts:cv:: CONFIG proxy.config.ssl.max_record_size INT 0
This configuration specifies the maximum number of bytes to write
diff --git a/doc/admin-guide/files/ssl_server_name.config.en.rst b/doc/admin-guide/files/ssl_server_name.config.en.rst
new file mode 100644
index 0000000..de40db9
--- /dev/null
+++ b/doc/admin-guide/files/ssl_server_name.config.en.rst
@@ -0,0 +1,141 @@
+.. 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.
+
+.. include:: ../../common.defs
+
+ssl_server_name.config
+**********************
+
+.. configfile:: ssl_server_name.config
+
+Description
+===========
+
+This file is used to configure aspects of TLS connection handling for both inbound and outbound
+connections. The configuration is driven by the SNI values provided by the inbound connection. The
+file consists of a set of configuration items, each identified by an SNI value (``fqdn``).
+When an inbound TLS connection is made, the SNI value from the TLS negotiation is matched against
+the items specified by this file and if there is a match, the values specified in that item override
+the defaults. This is done during the inbound connection processing and be some outbound properties
+can be overridden again later, such as via :file:`remap.config` or plugins.
+
+By default this is named :file:`ssl_server_name.config`. The file can be changed by settting
+:ts:cv:`proxy.config.ssl.servername.filename`. This file is loaded on start up and by
+:option:`traffic_ctl config reload` if the file has been modified since process start.
+
+The configuration file is Lua based. After parsing and executing the Lua code, the global Lua
+variable :code:`server_config` is examined. Its value should be a list of tables. Each table is set
+of key / value pairs that create a configuration item.
+
+======================= ==============================================================================
+Key Meaning
+======================= ==============================================================================
+fqdn Fully Qualified Domain Name. This item is used if the SNI value matches this.
+
+verify_origin_server One of the values :code:`NONE`, :code:`MODERATE`, or :code:`STRICT`.
+
+ By default this is :ts:cv:`proxy.config.ssl.client.verify.server`.
+
+verify_client One of the values :code:`NONE`, :code:`MODERATE`, or :code:`STRICT`.
+
+ By default this is :ts:cv:`proxy.config.ssl.client.certification_level`.
+
+client_cert The client certificate to use for the outbound connection.
+
+ If this is relative it is relative to the path in
+ :ts:cv:`proxy.config.ssl.server.cert.path`. If not set
+ :ts:cv:`proxy.config.ssl.client.cert.filename` is used.
+
+disable_h2 :code:`true` or :code:`false`.
+
+ If :code:`false` then HTTP/2 is removed from
+ the valid next protocol list. It is not an error to set this to :code:`false`
+ for proxy ports on which HTTP/2 is not enabled.
+
+tunnel_route Destination as an FQDN and port, separated by a colon ``:``.
+======================= ==============================================================================
+
+Client verification, via ``verify_client``, correponds to setting
+:ts:cv:`proxy.config.ssl.client.certification_level` for this connection as noted below.
+
+:code:`NONE` -- ``0``
+ Do not request a client certificate, ignore it if one is provided.
+
+:code:`MODERATE` - ``1``
+ Request a client certificate and do verification if one is provided, but do not enforce
+ verification. If the verification fails the failure is logged to :file:`diags.log` but the
+ connection is allowed.
+
+:code:`STRICT` - ``2``
+ Request a client certificate and require one to be provided and verified.
+ If the verification fails the failure is logged to :file:`diags.log` and the connection is
+ denied.
+
+Upstream (server) verification, via ``verify_origin_server``, is similar to client verification
+except there is always an upstream certificate. This is equivalent to setting
+:ts:cv:`proxy.config.ssl.client.verify.server` for this connection.
+
+:code:`NONE` - ``0``
+ Do not verify the upstream server certificate.
+
+:code:`MODERATE` - ``2``
+ Do verification of the upstream certificate but do not enforce. If the verification fails the
+ failure is logged in :file:`diags.log` but the connection is allowed.
+
+:code:`STRICT` - ``1``
+ Do verification of the upstream certificate. If verification fails, the failure is
+ logged in :file:`diags.log` and the connection is denied.
+
+If ``tunnel_route`` is specified, none of the certificate verification will be done because the TLS
+negotiation will be tunneled to the upstream target, making those values irrelevant for that
+configuration item. This option is explained in more detail in :ref:`sni-routing`.
+
+Examples
+========
+
+Disable HTTP/2 for ``no-http2.example.com``.
+
+.. code-block:: Lua
+
+ server_config = {{ fqdn="no-http2.example.com", disable_h2=true }}
+
+Require client certificate verification for ``example.com`` and ``yahoo.com``.
+
+.. code-block:: Lua
+
+ server_config = {
+ { fqdn="example.com", verify_client=STRICT },
+ { fqdn="yahoo.com", verify_client=STRICT }
+ }
+
+Disable outbound server certificate verification for ``trusted.example.com`` and require a valid
+client certificate.
+
+.. code-block:: Lua
+
+ server_config = {
+ {
+ fqdn="trusted.example.com",
+ verify_origin_server=NONE,
+ verify_client=STRICT
+ }
+ }
+
+See Also
+========
+
+:ref:`sni-routing`
diff --git a/doc/admin-guide/index.en.rst b/doc/admin-guide/index.en.rst
index c2bf2eb..0557b69 100644
--- a/doc/admin-guide/index.en.rst
+++ b/doc/admin-guide/index.en.rst
@@ -37,6 +37,7 @@ Table of Contents:
logging/index.en
monitoring/index.en
configuring-traffic-server.en
+ layer-4-routing.en
performance/index.en
files/index.en
@@ -54,4 +55,3 @@ running with your own instance of |TS|. Or so is our hope.
Should you encounter problems, or find any of the instructions unclear or
lacking, please seek help through one of the avenues listed in
:ref:`intro-other-resources`.
-
diff --git a/doc/admin-guide/layer-4-routing.en.rst b/doc/admin-guide/layer-4-routing.en.rst
new file mode 100644
index 0000000..5395449
--- /dev/null
+++ b/doc/admin-guide/layer-4-routing.en.rst
@@ -0,0 +1,128 @@
+.. 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.
+
+.. include:: ../common.defs
+.. default-domain:: c
+.. _layer-4-routing:
+
+Layer 4 Routing
+**************************
+
+|TS| supports a limited set of layer 4 routing options. In such use |TS| acts effectively as a
+router, moving network data between two endpoints without modifying the data. The routing is
+accomplished by examining the initial data from the inbound connection to decide the outbound
+destination. The initial data is then sent to the destination and subsequently |TS| forwards all
+data read on one connection to the other and vice versa.
+
+.. image:: ../uml/images/l4-basic-sequence.svg
+ :align: center
+
+In this way it acts similary to `nc <https://linux.die.net/man/1/nc>`__.
+
+The primary differences between different types of layer 4 routing is the mechanism by which |TS|
+creates the outbound connection. This is described in detail in the type specific documentation.
+
+Transparency
+============
+
+Transparency is in some sense layer 4 routing because the outbound connection is determined by
+examining the destination address in the client TCP packets. This is discussed in detail
+:ref:`elsewhere <transparent-proxy>`.
+
+.. _sni-routing:
+
+SNI Routing
+===========
+
+Currently the only directly supported layer 4 routing (as of version 8.0) is SNI based routing. This
+imposes some requirements on the traffic.
+
+* The inbound connection must be TLS.
+* The outbound destination must handle the HTTP ``CONNECT`` method.
+
+SNI routing is configured by :file:`ssl_server_name.config`.
+
+If SNI Routing is enabled the initial "`CLIENT HELLO
+<https://tools.ietf.org/html/rfc5246#section-7.4.1.2>`__" data of an inbound TLS connection is
+examined to extract the "`SNI <https://tools.ietf.org/html/rfc3546#section-3.1>`__" value. This is
+matched against the configuration data to select an action for the inbound connection. In this case
+the option of interest is ``tunnel_route``. If this is set then |TS| will connect to the specified
+destination and issue an HTTP ``CONNECT`` request using the SNI value as the URL for the request.
+Because the destination and the ``CONNECT`` are the same in general it will be necessary to use
+a plugin to change the URL in the ``CONNECT``.
+
+Example
+-------
+
+Consider a Content Delivery Network (CDN) that has an edge layer of externally facing |TS|
+instances. The goal is to enable external clients to connect to internal services and do their own
+client certificate verification, possibly because distribution of private keys to the edge |TS|
+instances is too difficult or too risky. To achieve this, the edge |TS| instances can be configured
+to route inbound TLS connections with specific SNI values directly to the internal services without
+TLS termination on the edge. This enables the edge to provide controlled external access to the
+internal services without each internal service having to stand up its own edge. Note the services
+do not require global routable addresses as long as the edge |TS| instances can route to the
+services.
+
+The basic set up is therefore
+
+.. figure:: ../uml/images/l4-example-cdn-layout.svg
+ :align: center
+
+ A Client connects to an edge |TS| which forwards the connection to the internal Service.
+ The Client then negotiates TLS with the Service.
+
+
+For the example, let us define two services inside the corporate network of Example, Inc.
+``service-1`` and ``service-2``. ``service-1`` is on port 443 on host ``app-server-29`` while
+``service-2`` is on port 4443 on host ``app-server-56``. The SNI routing set up for this would be
+
+========================== =====================================
+SNI value Destination
+========================== =====================================
+service-1.example.com app-server-29:443
+service-2.example.com app-server-56:4443
+========================== =====================================
+
+The :file:`ssl_server_name.config` contents would be
+
+.. code-block:: lua
+
+ server_config = {
+ {
+ fqdn = 'service-1.example.com'
+ tunnel_route = 'app-server-29:443'
+ },
+ {
+ fqdn = 'service-2.example.com'
+ tunnel_route = 'app-server-56:4443'
+ }
+ }
+
+The sequence of network activity for a Client connecting to ``service-2`` is
+
+.. image:: ../uml/images/l4-sni-routing-seq.svg
+ :align: center
+
+Note the destination for the outbound TCP connection and the HTTP ``CONNECT`` is the same. If this
+is a problem (which it will be in general) a plugin is needed to change the URL in the ``CONNECT``.
+In this case the proxy request is available in the :c:macro:`TS_HTTP_TXN_START_HOOK` hook. This
+cannot be done using remap because for a ``CONNECT`` there is no remap phase. Note that for a
+tunneled connection like this, the only transaction hooks that will be triggered are
+:c:macro`TS_HTTP_TXN_START_HOOK` and :c:macro:`TS_HTTP_TXN_CLOSE_HOOK`. In addition, because |TS|
+does not terminate (and thefore does not decrypt) the connection, it cannot be cached or served from
+cache.
diff --git a/doc/uml/Makefile b/doc/uml/Makefile
new file mode 100644
index 0000000..0f387a9
--- /dev/null
+++ b/doc/uml/Makefile
@@ -0,0 +1,23 @@
+# doc/uml Makefile
+#
+# 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 is exlicitly not tied in to the general make setup. It is intended
+# to be run manually only as needed so that only people who need to update
+# diagrams must install Java support for plantuml.
+all:
+ java -jar ~/bin/plantuml.jar -o images -tsvg *.uml
diff --git a/doc/uml/images/.gitignore b/doc/uml/images/.gitignore
new file mode 100644
index 0000000..85efa6a
--- /dev/null
+++ b/doc/uml/images/.gitignore
@@ -0,0 +1,5 @@
+## Directory for images generated from UML diagrams.
+# Ignore everything - files are only checked in / updated here manually using `git add -f`.
+# That may change if requiring Java to build the docs for plantuml is approved.
+*
+!.gitignore
diff --git a/doc/uml/images/l4-basic-sequence.svg b/doc/uml/images/l4-basic-sequence.svg
new file mode 100644
index 0000000..6a0c687
--- /dev/null
+++ b/doc/uml/images/l4-basic-sequence.svg
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="496px" preserveAspectRatio="none" style="width:428px;height:496px;" version="1.1" viewBox="0 0 428 496" width="428px" zoomAndPan="magnify"><defs><filter height="300%" id="fsmtqap5irkzc" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMa [...]
+@startuml
+
+actor Inbound
+participant "Traffic\nServer" as TS
+participant Outbound
+
+Inbound <-[#green]> TS : <font color="green">//TCP//</font> Handshake
+Inbound -[#blue]> TS : <font color="blue">//initial data//</font>
+note over TS : Examine initial data\nselect Outbound
+TS <-[#green]> Outbound : <font color="green">//TCP//</font> Handshake
+note over TS, Outbound : Additional Setup\n(in some cases)
+TS -[#blue]> Outbound : <font color="blue">//initial data//</font>
+note left : Duplicate of data from Inbound.
+note over TS : Forward bytes\nInbound <&arrow-thick-left> <&arrow-thick-right> Outbound
+Inbound <- -> Outbound
+
+@enduml
+
+PlantUML version 1.2017.18(Fri Oct 06 11:56:32 CDT 2017)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Java Version: 1.8.0_151-b12
+Operating System: Linux
+OS Version: 4.13.13-200.fc26.x86_64
+Default Encoding: UTF-8
+Language: en
+Country: US
+--></g></svg>
\ No newline at end of file
diff --git a/doc/uml/images/l4-example-cdn-layout.svg b/doc/uml/images/l4-example-cdn-layout.svg
new file mode 100644
index 0000000..14a0e2f
--- /dev/null
+++ b/doc/uml/images/l4-example-cdn-layout.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="109px" preserveAspectRatio="none" style="width:513px;height:109px;" version="1.1" viewBox="0 0 513 109" width="513px" zoomAndPan="magnify"><defs><filter height="300%" id="f18p37jwo5ssms" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorM [...]
+@startuml
+hide empty members
+
+node Client
+cloud "Untrusted\nNetworks" as Cloud
+node "Edge TS"
+package "Corporate Net" {
+ node Service
+}
+
+[Client] <-> [Cloud]
+[Cloud] <-> [Edge TS]
+[Edge TS] <-> [Service]
+@enduml
+
+PlantUML version 1.2017.18(Fri Oct 06 11:56:32 CDT 2017)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Java Version: 1.8.0_151-b12
+Operating System: Linux
+OS Version: 4.13.13-200.fc26.x86_64
+Default Encoding: UTF-8
+Language: en
+Country: US
+--></g></svg>
\ No newline at end of file
diff --git a/doc/uml/images/l4-sni-routing-seq.svg b/doc/uml/images/l4-sni-routing-seq.svg
new file mode 100644
index 0000000..8a965be
--- /dev/null
+++ b/doc/uml/images/l4-sni-routing-seq.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="613px" preserveAspectRatio="none" style="width:596px;height:613px;" version="1.1" viewBox="0 0 596 613" width="596px" zoomAndPan="magnify"><defs><filter height="300%" id="fz7842w3qribd" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMa [...]
+@startuml
+
+actor Inbound
+participant "Traffic\nServer" as TS
+entity "app-server-56:4443" as Outbound
+
+Inbound <-[#green]> TS : <font color="green">//TCP//</font> Handshake
+Inbound -[#blue]> TS : <font color="blue">//TLS//</font> Client HELLO\nSNI=service-2.example.com
+note over TS : Examine SNI value\nSelect Outbound
+TS <-[#green]> Outbound : <font color="green">//TCP//</font> Handshake
+TS -> Outbound : <font color="red">//HTTP//</font> ""CONNECT"" app-server-56:4443
+Outbound -> TS : ""200 OK""
+TS -[#blue]> Outbound : <font color="blue">//TLS//</font> Client HELLO\nSNI=service-2.example.com
+note left : Duplicate of Inbound HELLO
+note over TS : Forward bytes\nInbound <&arrow-thick-left> <&arrow-thick-right> Outbound
+note over Inbound, Outbound : <font color="blue">TLS negotiation</font>
+Inbound <-[#blue]-> Outbound
+note over Inbound, Outbound : Transactions
+Inbound <-[#black]-> Outbound
+
+@enduml
+
+PlantUML version 1.2017.18(Fri Oct 06 11:56:32 CDT 2017)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Java Version: 1.8.0_151-b12
+Operating System: Linux
+OS Version: 4.13.13-200.fc26.x86_64
+Default Encoding: UTF-8
+Language: en
+Country: US
+--></g></svg>
\ No newline at end of file
diff --git a/doc/uml/l4-basic-sequence.uml b/doc/uml/l4-basic-sequence.uml
new file mode 100644
index 0000000..5ecc3c5
--- /dev/null
+++ b/doc/uml/l4-basic-sequence.uml
@@ -0,0 +1,24 @@
+' Licensed 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.
+
+@startuml
+
+actor Inbound
+participant "Traffic\nServer" as TS
+participant Outbound
+
+Inbound <-[#green]> TS : <font color="green">//TCP//</font> Handshake
+Inbound -[#blue]> TS : <font color="blue">//initial data//</font>
+note over TS : Examine initial data\nselect Outbound
+TS <-[#green]> Outbound : <font color="green">//TCP//</font> Handshake
+note over TS, Outbound : Additional Setup\n(in some cases)
+TS -[#blue]> Outbound : <font color="blue">//initial data//</font>
+note left : Duplicate of data from Inbound.
+note over TS : Forward bytes\nInbound <&arrow-thick-left> <&arrow-thick-right> Outbound
+Inbound <--> Outbound
+
+@enduml
diff --git a/doc/uml/l4-example-cdn-layout.uml b/doc/uml/l4-example-cdn-layout.uml
new file mode 100644
index 0000000..5f4f8b5
--- /dev/null
+++ b/doc/uml/l4-example-cdn-layout.uml
@@ -0,0 +1,21 @@
+' Licensed 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.
+
+@startuml
+hide empty members
+
+node Client
+cloud "Untrusted\nNetworks" as Cloud
+node "Edge TS"
+package "Corporate Net" {
+ node Service
+}
+
+[Client] <-> [Cloud]
+[Cloud] <-> [Edge TS]
+[Edge TS] <-> [Service]
+@enduml
diff --git a/doc/uml/l4-sni-routing-seq.uml b/doc/uml/l4-sni-routing-seq.uml
new file mode 100644
index 0000000..00eb967
--- /dev/null
+++ b/doc/uml/l4-sni-routing-seq.uml
@@ -0,0 +1,28 @@
+' Licensed 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.
+
+@startuml
+
+actor Inbound
+participant "Traffic\nServer" as TS
+entity "app-server-56:4443" as Outbound
+
+Inbound <-[#green]> TS : <font color="green">//TCP//</font> Handshake
+Inbound -[#blue]> TS : <font color="blue">//TLS//</font> Client HELLO\nSNI=service-2.example.com
+note over TS : Examine SNI value\nSelect Outbound
+TS <-[#green]> Outbound : <font color="green">//TCP//</font> Handshake
+TS -> Outbound : <font color="red">//HTTP//</font> ""CONNECT"" app-server-56:4443
+Outbound -> TS : ""200 OK""
+TS -[#blue]> Outbound : <font color="blue">//TLS//</font> Client HELLO\nSNI=service-2.example.com
+note left : Duplicate of Inbound HELLO
+note over TS : Forward bytes\nInbound <&arrow-thick-left> <&arrow-thick-right> Outbound
+note over Inbound, Outbound : <font color="blue">TLS negotiation</font>
+Inbound <-[#blue]-> Outbound
+note over Inbound, Outbound : Transactions
+Inbound <-[#black]-> Outbound
+
+@enduml
diff --git a/doc/uml/l4-tcp-routing.uml b/doc/uml/l4-tcp-routing.uml
new file mode 100644
index 0000000..f59ff34
--- /dev/null
+++ b/doc/uml/l4-tcp-routing.uml
@@ -0,0 +1,23 @@
+' Licensed 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.
+
+@startuml
+
+actor Inbound
+participant "Traffic\nServer" as TS
+participant Outbound
+
+Inbound <-[#green]> TS : //TCP Connect//
+Inbound -[#blue]-> TS : <font color="blue">//initial data//</font>
+note over TS : Examine initial data\nselect Outbound
+TS <-[#green]> Outbound : //TCP Connect//
+TS -[#blue]-> Outbound : <font color="blue">//initial data//</font>
+note right : Duplicate of data from Inbound.
+note over TS : Forward bytes between Inbound <&arrow-thick-left> <&arrow-thick-right> Outbound
+Inbound <--> Outbound
+
+@enduml
--
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].