Skip to content

Commit

Permalink
examples: Add TLS sandbox (envoyproxy#13844)
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Northey <[email protected]>
  • Loading branch information
phlax authored Nov 11, 2020
1 parent d525ae7 commit 5fc8127
Show file tree
Hide file tree
Showing 15 changed files with 577 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/root/start/sandboxes/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ features. The following sandboxes are available:
mysql
postgres
redis
tls
wasm-cc
zipkin_tracing
skywalking_tracing
172 changes: 172 additions & 0 deletions docs/root/start/sandboxes/tls.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
.. _install_sandboxes_tls:

TLS
===

.. sidebar:: Requirements

`jq <https://stedolan.github.io/jq/>`_
Used to parse ``json`` output from the upstream echo servers.

This example walks through some of the ways that Envoy can be configured to make
use of encrypted connections using ``HTTP`` over ``TLS``.

It demonstrates a number of commonly used proxying and ``TLS`` termination patterns:

- ``https`` -> ``http``
- ``https`` -> ``https``
- ``http`` -> ``https``
- ``https`` passthrough

To better understand the provided examples, and for a description of how ``TLS`` is
configured with Envoy, please see the :ref:`securing Envoy quick start guide <start_quick_start_securing>`.

.. warning::

For the sake of simplicity, the examples provided here do not authenticate any client certificates,
or validate any of the provided certificates.

When using ``TLS``, you are strongly encouraged to :ref:`validate <start_quick_start_securing_validation>`
all certificates wherever possible.

You should also :ref:`authenticate clients <start_quick_start_securing_mtls>`
where you control both sides of the connection, or relevant protocols are available.

.. include:: _include/docker-env-setup.rst

Change directory to ``examples/tls`` in the Envoy repository.

Step 3: Build the sandbox
*************************

This starts four proxies listening on ``localhost`` ports ``10000-10003``.

It also starts two upstream services, one ``HTTP`` and one ``HTTPS``, which echo back received headers
in ``json`` format.

The upstream services listen on the internal Docker network on ports ``80`` and ``443`` respectively.

.. code-block:: console
$ pwd
envoy/examples/tls
$ docker-compose pull
$ docker-compose up --build -d
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------
tls_proxy-https-to-http_1 /docker-entrypoint.sh /usr ... Up 0.0.0.0:10000->10000/tcp
tls_proxy-https-to-https_1 /docker-entrypoint.sh /usr ... Up 0.0.0.0:10001->10000/tcp
tls_proxy-http-to-https_1 /docker-entrypoint.sh /usr ... Up 0.0.0.0:10002->10000/tcp
tls_proxy-https-passthrough_1 /docker-entrypoint.sh /usr ... Up 0.0.0.0:10003->10000/tcp
tls_service-http_1 node ./index.js Up
tls_service-https_1 node ./index.js Up
Step 4: Test proxying ``https`` -> ``http``
*******************************************

The Envoy proxy listening on https://localhost:10000 terminates ``HTTPS`` and proxies to the upstream ``HTTP`` service.

The :download:`https -> http configuration <_include/tls/envoy-https-http.yaml>` adds a ``TLS``
:ref:`transport_socket <extension_envoy.transport_sockets.tls>` to the
:ref:`listener <envoy_v3_api_msg_config.listener.v3.Listener>`.

Querying the service at port ``10000`` you should see an ``x-forwarded-proto`` header of ``https`` has
been added:

.. code-block:: console
$ curl -sk https://localhost:10000 | jq -r '.headers["x-forwarded-proto"]'
https
The upstream ``service-http`` handles the request.

.. code-block:: console
$ curl -sk https://localhost:10000 | jq -r '.os.hostname'
service-http
Step 5: Test proxying ``https`` -> ``https``
********************************************

The Envoy proxy listening on https://localhost:10001 terminates ``HTTPS`` and proxies to the upstream ``HTTPS`` service.

The :download:`https -> https configuration <_include/tls/envoy-https-https.yaml>` adds a ``TLS``
:ref:`transport_socket <extension_envoy.transport_sockets.tls>` to both the
:ref:`listener <envoy_v3_api_msg_config.listener.v3.Listener>` and the
:ref:`cluster <envoy_v3_api_msg_config.cluster.v3.Cluster>`.

Querying the service at port ``10001`` you should see an ``x-forwarded-proto`` header of ``https`` has
been added:

.. code-block:: console
$ curl -sk https://localhost:10001 | jq -r '.headers["x-forwarded-proto"]'
https
The upstream ``service-https`` handles the request.

.. code-block:: console
$ curl -sk https://localhost:10001 | jq -r '.os.hostname'
service-https
Step 6: Test proxying ``http`` -> ``https``
*******************************************

The Envoy proxy listening on http://localhost:10002 terminates ``HTTP`` and proxies to the upstream ``HTTPS`` service.

The :download:`http -> https configuration <_include/tls/envoy-http-https.yaml>` adds a ``TLS``
:ref:`transport_socket <extension_envoy.transport_sockets.tls>` to the
:ref:`cluster <envoy_v3_api_msg_config.cluster.v3.Cluster>`.

Querying the service at port ``10001`` you should see an ``x-forwarded-proto`` header of ``http`` has
been added:

.. code-block:: console
$ curl -s http://localhost:10002 | jq -r '.headers["x-forwarded-proto"]'
http
The upstream ``service-https`` handles the request.

.. code-block:: console
$ curl -s http://localhost:10002 | jq -r '.os.hostname'
service-https
Step 7: Test proxying ``https`` passthrough
*******************************************

The Envoy proxy listening on https://localhost:10003 proxies directly to the upstream ``HTTPS`` service which
does the ``TLS`` termination.

The :download:`https passthrough configuration <_include/tls/envoy-https-passthrough.yaml>` requires no ``TLS``
or ``HTTP`` setup, and instead uses a simple
:ref:`tcp_proxy <envoy_v3_api_msg_extensions.filters.network.tcp_proxy.v3.TcpProxy>`.

Querying the service at port ``10003`` you should see that no ``x-forwarded-proto`` header has been
added:

.. code-block:: console
$ curl -sk https://localhost:10003 | jq -r '.headers["x-forwarded-proto"]'
null
The upstream ``service-https`` handles the request.

.. code-block:: console
$ curl -sk https://localhost:10003 | jq -r '.os.hostname'
service-https
.. seealso::

:ref:`Securing Envoy quick start guide <start_quick_start_securing>`
Outline of key concepts for securing Envoy.

:ref:`Double proxy sandbox <install_sandboxes_double_proxy>`
An example of securing traffic between proxies with validation and
mutual authentication using ``mTLS`` with non-``HTTP`` traffic.
12 changes: 12 additions & 0 deletions examples/DEVELOPER.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ responds_with \
-H 'Origin: https://example-service.com'
```

#### Utility functions: `responds_without`

You can also check that a request *does not* respond with given `HTTP` content:

```bash
responds_without \
"Anything unexpected" \
"http://localhost:8000"
```

`responds_without` can accept additional curl arguments like `responds_with`

#### Utility functions: `responds_with_header`

You can check that a request responds with an expected header as follows:
Expand Down
5 changes: 5 additions & 0 deletions examples/tls/Dockerfile-proxy-http-https
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM envoyproxy/envoy-dev:latest

COPY ./envoy-http-https.yaml /etc/envoy.yaml
RUN chmod go+r /etc/envoy.yaml
CMD ["/usr/local/bin/envoy", "-c /etc/envoy.yaml"]
5 changes: 5 additions & 0 deletions examples/tls/Dockerfile-proxy-https-http
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM envoyproxy/envoy-dev:latest

COPY ./envoy-https-http.yaml /etc/envoy.yaml
RUN chmod go+r /etc/envoy.yaml
CMD ["/usr/local/bin/envoy", "-c /etc/envoy.yaml"]
5 changes: 5 additions & 0 deletions examples/tls/Dockerfile-proxy-https-https
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM envoyproxy/envoy-dev:latest

COPY ./envoy-https-https.yaml /etc/envoy.yaml
RUN chmod go+r /etc/envoy.yaml
CMD ["/usr/local/bin/envoy", "-c /etc/envoy.yaml"]
5 changes: 5 additions & 0 deletions examples/tls/Dockerfile-proxy-https-passthrough
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM envoyproxy/envoy-dev:latest

COPY ./envoy-https-passthrough.yaml /etc/envoy.yaml
RUN chmod go+r /etc/envoy.yaml
CMD ["/usr/local/bin/envoy", "-c /etc/envoy.yaml"]
2 changes: 2 additions & 0 deletions examples/tls/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To learn about this sandbox and for instructions on how to run it please head over
to the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/tls.html).
42 changes: 42 additions & 0 deletions examples/tls/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
version: "3.7"
services:

proxy-https-to-http:
build:
context: .
dockerfile: Dockerfile-proxy-https-http
ports:
- "10000:10000"

proxy-https-to-https:
build:
context: .
dockerfile: Dockerfile-proxy-https-https
ports:
- "10001:10000"

proxy-http-to-https:
build:
context: .
dockerfile: Dockerfile-proxy-http-https
ports:
- "10002:10000"

proxy-https-passthrough:
build:
context: .
dockerfile: Dockerfile-proxy-https-passthrough
ports:
- "10003:10000"

service-http:
image: mendhak/http-https-echo
hostname: service-http
environment:
- HTTPS_PORT=0

service-https:
image: mendhak/http-https-echo
hostname: service-https
environment:
- HTTP_PORT=0
45 changes: 45 additions & 0 deletions examples/tls/envoy-http-https.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: app
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: service-https
http_filters:
- name: envoy.filters.http.router

clusters:
- name: service-https
connect_timeout: 0.25s
type: strict_dns
lb_policy: round_robin
load_assignment:
cluster_name: service-https
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: service-https
port_value: 443
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
Loading

0 comments on commit 5fc8127

Please sign in to comment.