diff --git a/ci/verify_examples.sh b/ci/verify_examples.sh index 03a26be026a3..974e46b7ad89 100755 --- a/ci/verify_examples.sh +++ b/ci/verify_examples.sh @@ -29,7 +29,7 @@ trap exit 1 INT run_examples () { local examples example cd "${SRCDIR}/examples" || exit 1 - examples=$(find . -mindepth 1 -maxdepth 1 -type d -name "$TESTFILTER" | sort) + examples=$(find . -mindepth 1 -maxdepth 1 -type d -name "$TESTFILTER" ! -iname "_*" | sort) for example in $examples; do pushd "$example" > /dev/null || return 1 ./verify.sh diff --git a/docs/root/start/sandboxes/index.rst b/docs/root/start/sandboxes/index.rst index d1b686d01820..4bf8c5f8c102 100644 --- a/docs/root/start/sandboxes/index.rst +++ b/docs/root/start/sandboxes/index.rst @@ -63,6 +63,7 @@ The following sandboxes are available: postgres redis skywalking_tracing + tls-sni tls wasm-cc websocket diff --git a/docs/root/start/sandboxes/tls-sni.rst b/docs/root/start/sandboxes/tls-sni.rst new file mode 100644 index 000000000000..f61817027b5a --- /dev/null +++ b/docs/root/start/sandboxes/tls-sni.rst @@ -0,0 +1,175 @@ +.. _install_sandboxes_tls_sni: + +TLS Server name indication (``SNI``) +==================================== + +.. sidebar:: Requirements + + .. include:: _include/docker-env-setup-link.rst + + :ref:`curl ` + Used to make ``HTTP`` requests. + + :ref:`jq ` + Parse ``json`` output from the upstream echo servers. + +This example demonstrates an Envoy proxy that listens on three ``TLS`` domains +on the same ``IP`` address. + +The first two domains (``domain1`` and ``domain2``) terminate the ``TLS`` and proxy +to upstream ``HTTP`` hosts. + +The other domain (``domain3``) is proxied unterminated, based on the ``SNI`` headers. + +It also demonstrates Envoy acting as a client proxy connecting to upstream ``SNI`` services. + +.. _install_sandboxes_tls_sni_step1: + +Step 1: Create keypairs for each of the domain endpoints +******************************************************** + +Change directory to ``examples/tls-sni`` in the Envoy repository. + +The example creates two Envoy ``TLS`` endpoints and they will require their own +keypairs. + +Create self-signed certificates for these endpoints as follows: + +.. code-block:: console + + $ pwd + envoy/examples/tls-sni + + $ mkdir -p certs + + $ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \ + -subj "/C=US/ST=CA/O=MyExample, Inc./CN=domain1.example.com" \ + -keyout certs/domain1.key.pem \ + -out certs/domain1.crt.pem + Generating a RSA private key + .............+++++ + ...................+++++ + writing new private key to 'certs/domain1.key.pem' + ----- + + $ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \ + -subj "/C=US/ST=CA/O=MyExample, Inc./CN=domain2.example.com" \ + -keyout certs/domain2.key.pem \ + -out certs/domain2.crt.pem + Generating a RSA private key + .............+++++ + ...................+++++ + writing new private key to 'certs/domain2.key.pem' + ----- + +.. warning:: + + ``SNI`` does *not* validate that the certificates presented are correct for the domain, or that they + were issued by a recognised certificate authority. + + See the :ref:`Securing Envoy quick start guide ` for more information about + :ref:`validating cerfificates `. + +.. _install_sandboxes_tls_sni_step2: + +Step 2: Start the containers +**************************** + +Build and start the containers. + +This starts two upstream ``HTTP`` containers listening on the internal Docker network on port ``80``, and +an upstream ``HTTPS`` service listening on internal port ``443`` + +In front of these is an Envoy proxy that listens on https://localhost:10000 and serves three ``SNI`` routed +``TLS`` domains: + +- ``domain1.example.com`` +- ``domain2.example.com`` +- ``domain3.example.com`` + +The first two domains use the keys and certificates :ref:`you created in step 1 ` to terminate ``TLS`` and +proxy to the two upstream ``HTTP`` servers. + +The third domain proxies to the upstream ``TLS`` server based on the requested ``SNI`` address, but does no ``TLS`` termination itself. + +The composition also starts an Envoy proxy client which listens on http://localhost:20000. + +The client proxy has no ``TLS`` termination but instead proxies three routed paths - +``/domain1``, ``/domain2`` and ``/domain3`` - to the ``SNI``-enabled proxy. + +.. code-block:: console + + $ pwd + envoy/examples/tls-sni + $ docker-compose build --pull + $ docker-compose up -d + $ docker-compose ps + + Name Command State Ports + ------------------------------------------------------------------------------------------- + tls-sni_http-upstream1_1 node ./index.js Up + tls-sni_http-upstream2_1 node ./index.js Up + tls-sni_http-upstream3_1 node ./index.js Up + tls-sni_proxy_1 /docker-entrypoint.sh /usr ... Up 0.0.0.0:10000->10000/tcp + tls-sni_proxy-client_1 /docker-entrypoint.sh /usr ... Up 0.0.0.0:20000->10000/tcp + +Step 2: Query the ``SNI`` endpoints directly with curl +****************************************************** + +You can use curl to query the ``SNI``-routed ``HTTPS`` endpoints of the Envoy proxy directly. + +To do this you must explicitly tell curl to resolve the ``DNS`` for the endpoints correctly. + +Each endpoint should proxy to the respective ``http-upstream`` or ``https-upstream`` service. + +.. code-block:: console + + $ curl -sk --resolve domain1.example.com:10000:127.0.0.1 \ + https://domain1.example.com:10000 \ + | jq -r '.os.hostname' + http-upstream1 + + $ curl -sk --resolve domain2.example.com:10000:127.0.0.1 \ + https://domain2.example.com:10000 \ + | jq -r '.os.hostname' + http-upstream2 + + $ curl -sk --resolve domain3.example.com:10000:127.0.0.1 \ + https://domain3.example.com:10000 \ + | jq -r '.os.hostname' + https-upstream3 + +Step 3: Query the ``SNI`` endpoints via an Envoy proxy client +************************************************************* + +Next, query the Envoy proxy client using the routed paths. + +These route via the ``SNI`` proxy endpoints to the respective ``http-upstream`` or +``https-upstream`` services. + +.. code-block:: console + + $ curl -s http://localhost:20000/domain1 \ + | jq '.os.hostname' + http-upstream1 + + $ curl -s http://localhost:20000/domain2 \ + | jq '.os.hostname' + http-upstream2 + + $ curl -s http://localhost:20000/domain3 \ + | jq '.os.hostname' + https-upstream3 + +.. seealso:: + + :ref:`Securing Envoy quick start guide ` + Outline of key concepts for securing Envoy. + + :ref:`TLS sandbox ` + Sandbox featuring examples of how Envoy can be configured to make + use of encrypted connections using ``HTTP`` over ``TLS``. + + :ref:`Double proxy sandbox ` + An example of securing traffic between proxies with validation and + mutual authentication using ``mTLS`` with non-``HTTP`` traffic. diff --git a/docs/root/start/sandboxes/tls.rst b/docs/root/start/sandboxes/tls.rst index 84942094bb81..ecfbcaf4e3cb 100644 --- a/docs/root/start/sandboxes/tls.rst +++ b/docs/root/start/sandboxes/tls.rst @@ -170,6 +170,10 @@ The upstream ``service-https`` handles the request. :ref:`Securing Envoy quick start guide ` Outline of key concepts for securing Envoy. + :ref:`TLS SNI sandbox ` + Example of using Envoy to serve multiple domains protected by TLS and + served from the same ``IP`` address. + :ref:`Double proxy sandbox ` An example of securing traffic between proxies with validation and mutual authentication using ``mTLS`` with non-``HTTP`` traffic. diff --git a/examples/BUILD b/examples/BUILD index 59d945583b06..47e7740bc91c 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -15,6 +15,7 @@ filegroup( [ "**/*.yaml", "**/*.lua", + "_extra_certs/*.pem", ], exclude = [ "cache/responses.yaml", diff --git a/examples/_extra_certs/README.md b/examples/_extra_certs/README.md new file mode 100644 index 000000000000..3e4b69997626 --- /dev/null +++ b/examples/_extra_certs/README.md @@ -0,0 +1,7 @@ +Extra certificates for config validation testing +================================================ + +This folder contains certs that are referenced in the sandbox examples, that end users are +expected to create themselves. + +In order to test the related configs we need to provide the certs to CI. diff --git a/examples/_extra_certs/domain1.crt.pem b/examples/_extra_certs/domain1.crt.pem new file mode 100644 index 000000000000..33be12e8b02c --- /dev/null +++ b/examples/_extra_certs/domain1.crt.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhDCCAmygAwIBAgITAJlvbEs3wtayr3rx+TyuBtu0mTANBgkqhkiG9w0BAQsF +ADBSMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExGDAWBgNVBAoMD015RXhhbXBs +ZSwgSW5jLjEcMBoGA1UEAwwTZG9tYWluMS5leGFtcGxlLmNvbTAeFw0yMDExMTIx +MTA3MDdaFw0yMTExMTIxMTA3MDdaMFIxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJD +QTEYMBYGA1UECgwPTXlFeGFtcGxlLCBJbmMuMRwwGgYDVQQDDBNkb21haW4xLmV4 +YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA15Q63skf +pc5o2mhBE0dOcJaTqLS+nmIO5jK8QUKctpbOQz2p7j9zi9ZUh++4N84yjF56GQEw +/KqPvPHNA/tJKpkDugWHq4IFPU+o1k2AJKLVEvN3wXpbiae77eqgUCg0aS6kWDaT +LrCie/laxnSpnfRGDo1xsLRqNLzZxF3CPvA/WbgpR1JXYUAnoXZGHISrnXLzyI1O +DaDdDoi8Nn54neZ9jXtkeDWfuO5NkXK/U1dNnCez9a7EGO+h8ZF0Uc12UqPiX86L +frK0v25n94lPTGq5SOgswATMSOfN6g4pGaUFofZIyenHamUngzqm55M+/tMeiaF7 +Pwf4wcTyXEaXcQIDAQABo1MwUTAdBgNVHQ4EFgQUTSuIMFANakAWSPIUiqdMUrFq +66YwHwYDVR0jBBgwFoAUTSuIMFANakAWSPIUiqdMUrFq66YwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAdbdIBKAomEsGtcuWWc8vI4r0l+AMegGK +yg86byKm9WRHtpYnO+iZ+SopTLTFhgLsGfEMoN+HGeUIexUvwDzb384EJ4kLPr3E +Yqt5uNz9YMuFpkhuFTL+V5RczcPKfir5hzAgvAtj6eaRf9WPlObF+Rr0t8pJZG0k +9dEtBqE87XVUDvj6waMCpTFxwv22E/xjRJ5nSDjfk9y8LDpIF5SOunncVMRVfcjg +Qp0Q9KpZpbxXFMYVBfMxp4Z/KQd0W5nVWZlwg/D03n0IkS0e8irUyrerFLdOTwxf +G5M/n/VeCwC2GPlT8Eo/3BUa+SeX2iHl93/osqfWNQAY3riaN0y+FA== +-----END CERTIFICATE----- diff --git a/examples/_extra_certs/domain1.key.pem b/examples/_extra_certs/domain1.key.pem new file mode 100644 index 000000000000..eefcca26453f --- /dev/null +++ b/examples/_extra_certs/domain1.key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXlDreyR+lzmja +aEETR05wlpOotL6eYg7mMrxBQpy2ls5DPanuP3OL1lSH77g3zjKMXnoZATD8qo+8 +8c0D+0kqmQO6BYerggU9T6jWTYAkotUS83fBeluJp7vt6qBQKDRpLqRYNpMusKJ7 ++VrGdKmd9EYOjXGwtGo0vNnEXcI+8D9ZuClHUldhQCehdkYchKudcvPIjU4NoN0O +iLw2fnid5n2Ne2R4NZ+47k2Rcr9TV02cJ7P1rsQY76HxkXRRzXZSo+Jfzot+srS/ +bmf3iU9MarlI6CzABMxI583qDikZpQWh9kjJ6cdqZSeDOqbnkz7+0x6JoXs/B/jB +xPJcRpdxAgMBAAECggEBALvIi+tKaH3mqaEuVRk08NfT4jV/k9ek9POCWEfEfXvz +KyKZUS+OJ9k0TpfGscIypAdvuI2VYxWEgQaF3h7MwfQQK5XbgU1dSbEZdamPAsNm +75G9cKChM6FZ8bKRwSlxjA3fKhsJFvYBuNei4naiYqmLgYbloJXa4fSkWFDblvt4 +cmsP9iEZL7tBJ4bIGmugpPR83PPlfu/EQY2w8T+Rw8/JAXDd80V1egCucYpwOx94 +esXVpWzTA3xZyPTlQrFmOe9NEb2C5oqOx1s/zmfQpytKPjF7YojnHnYeHrDL5Y+j +sVP753celaYncWoANfAyV4FOxEsOa1OCKbF5OOuWPI0CgYEA/KyTK4NyRHqXrhuO +J/rRDhhZBomP4LkY2uTMdOH+n0hvy0m5eV5+88CQF6atSfKQ8h+zbhJVNeVilZDK +NhjAEm+x2vME41Wp1vqsALpPtuGFQm3EcwKDvTgyvm04X2RfZSZ4MT0993M/g07u +x+VQiZu127PjcNibDXXoDwM5p/MCgYEA2mqoRnTr/DCrO8u678ccv8MYHhh0ISOs +Tbmh83qROWehdoB6kRQ/i+kefbL6Rw0bY5+3rlvQ+3B3MvVoYLWUWuyhtYK2pt3i +R071WPCuR3PIVOEK+wuHi85peiGSHxfEDiUb3AvNnd8dZGBFnHe8mZObccc7b4uy +jT4VLJ56IAsCgYEAlg3GuKivS4uiWHt0yLljPYOoGwHGuCY0ZIpMAX3UwLM78PYv +d6xuqENLT0Bk2O18ts2suUmZ4RAAo+IAtG+uYUSD0wtPc9KDsm/bhfMfM/RqNzEI +4WQ06EJfoEcsmzn4jRFzf4pnKnT+2vQdSgkc8xvNvFPwVivMqQnEbmXz75ECgYBr +BTfOzhuTRoWglwLR2k5L59w5YuIEGuaibwLbuoLODekfl3R3AeThOSinjrrzdYim +F+x4kqSjj0fYwEaUnGRE6Q2TUqkMukvVhOrS2ZuLhz/x1xL6T3vrFQi5vxlKAusd +wzETcPUfFePg+wsgz8qptZnE9ko5LcofSvw1ELHmYQKBgBfT1GtRlYCEMbuSJY20 +AtoOg5vN2b6s2nqQGff7J8UOywPDk9hyboL4ByS9Udemap0USisGAZiEfq+VbA+2 +lPhV/gmBFDidCCYRXKi6qfcDG9ssJ5Gylg/8XaaMKAQ7vp73sQYTDlcgUcPx90ue +GMITMZWQr8Qs/u9zl22tnxAb +-----END PRIVATE KEY----- diff --git a/examples/_extra_certs/domain2.crt.pem b/examples/_extra_certs/domain2.crt.pem new file mode 100644 index 000000000000..9f983682ae6b --- /dev/null +++ b/examples/_extra_certs/domain2.crt.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIUXBZV/SLVGAdsb1mJrpuahYegPLEwDQYJKoZIhvcNAQEL +BQAwUjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRgwFgYDVQQKDA9NeUV4YW1w +bGUsIEluYy4xHDAaBgNVBAMME2RvbWFpbjIuZXhhbXBsZS5jb20wHhcNMjAxMTEy +MTEwNzA3WhcNMjExMTEyMTEwNzA3WjBSMQswCQYDVQQGEwJVUzELMAkGA1UECAwC +Q0ExGDAWBgNVBAoMD015RXhhbXBsZSwgSW5jLjEcMBoGA1UEAwwTZG9tYWluMi5l +eGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJfPje1r +nUfVnHobHRKReisGdGWHQhngJlp3II7sPk0vRuvOLsyLp0AKA/pS0isW1WFUh+Kz +BpOVrU/LPqi1ZW38mzCgGr91fc999vtsZyXOCEh7Vi3UVfzVtSNwnijlG3wovjGK +DqLlne03/lPFT1x9coIy7XvA1ZICfX8EfP5ajt60+UWYXAKN2FLas9K+3lzzbHx5 +F/iI134A695ozLNHT1qe+IOA6NwW5LoTwzoHRVMoJz2cvSRr0vCVkt0IvO5ARyyr +400Nx0vKkxhf0Z+yXGSowWVN8VtSPiRSeC4vGmPRl6O6XoiPwjus2jlXrJifcIyg +hNDrOQnYbYK5dA8CAwEAAaNTMFEwHQYDVR0OBBYEFIQfS5xxWYX7pWgc59p+h6y8 +sQMFMB8GA1UdIwQYMBaAFIQfS5xxWYX7pWgc59p+h6y8sQMFMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIHDjt+wxYuOJkI8VncVR6VpGy9hqntd +rnNxupReenhocPN/QIl1TQva/gGq4gz1vNWhHz1B5bxPoyPESed5+QQvJMo3/5Ub +OyDIKwspwRy6PUoyJDjhC/z7B2FhZPmxVmbHfhL0wiQjI7j/u+/c8Jq9YDr8ZsZs +whXjvSOl9+I0xWZFRN0O+cFszTnoucmLRdFVl648ghUlW3m6/YNWF+mLucleZVt3 +wFUKGwq88Z4sU6kqcXXG4GykZYmSwB3BmaaamQKq06v+k9Qjrj5gJD8S1Ygznc6/ +Z+ZzAb/FfHXHV6QbY5/35wVFO3OMk6NHy9oLZrfPxBn/C5brUz+dXnI= +-----END CERTIFICATE----- diff --git a/examples/_extra_certs/domain2.key.pem b/examples/_extra_certs/domain2.key.pem new file mode 100644 index 000000000000..12602841945f --- /dev/null +++ b/examples/_extra_certs/domain2.key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCXz43ta51H1Zx6 +Gx0SkXorBnRlh0IZ4CZadyCO7D5NL0brzi7Mi6dACgP6UtIrFtVhVIfiswaTla1P +yz6otWVt/JswoBq/dX3Pffb7bGclzghIe1Yt1FX81bUjcJ4o5Rt8KL4xig6i5Z3t +N/5TxU9cfXKCMu17wNWSAn1/BHz+Wo7etPlFmFwCjdhS2rPSvt5c82x8eRf4iNd+ +AOveaMyzR09anviDgOjcFuS6E8M6B0VTKCc9nL0ka9LwlZLdCLzuQEcsq+NNDcdL +ypMYX9GfslxkqMFlTfFbUj4kUnguLxpj0Zejul6Ij8I7rNo5V6yYn3CMoITQ6zkJ +2G2CuXQPAgMBAAECggEAJ089Rv8YqOMtM4kVzBsTcVSoiyms+hpKlB5ItfmCYGYf +jSvEfn6i/jgZs5YCidnNwvgqf48v4sNdL05HmVPvQb2pSbwLcQwxWasaaxw00Vs6 +VdpqBE/5PBDyaIzex2Qb69h490byZ0fhzu0y0+pBlId/QSuCxwq1wqsWZ+93ljzi +rDDoPSWcty0R3QWrMUmbihi6i8v8fbFz174jxGH1TRJ0+a9IuGZ9Yap1mSg9YC/0 +oM20lsvmQvczXYdJMUhg0CYJ3weThO9pK4fnDa7pvkBgxgOTOY2TZh3PUs7DmYa7 +YCE5xp8CviKZywaAqvowjfdWj8yCU5ZFzN4LdDmhMQKBgQDHL/dUg61+viWR7GyD +Kb9E9FjktwSu52Ec1jfcjFe8UkRJa7JiruagVXuekAVvA+R7ZifSb0Yfs1QaHwA3 +NPvVpwb3omW02gfbXR9AJ/eEJfgkcliPrJsL0QqbLu+w+5CFaj/iCN5SxE822WLx +3dGNDOrQEr0A+K3Hmj5SCtCmbQKBgQDDHEwxzjq6jw2n+K0ArIvpXa1/hteT6h1q +7Qcg9nEaSiVbYAfp+1qgQqoCMe7aSNJe/RuGP59mwlIgt1rn+QFgb8K9IoZYvb4N +jwLmuOx1tLWtbRLHHFdYA14XlwKOl79NwjJPepCZIU8eOzaDLBUUeH0DkgJgwSZ2 +TnJOmp6m6wKBgHL0tNpa0INoPAiWmR2tt0yVdMQy+An1UW+yFjU77dqq4+w3spEP +fdyk2R5u4iPq7C9niq4BOEhNV8lngNlbw8fPiM7cM7SHbKdmfAWry0bCHw7xyzjI +Fgdg0q0zDnRnC0ZkRpAuLBk6YLk4BsmuCiVMgiwp1Fi+LJUY6MSypy6VAoGAUFun +RhwaNBwXE8dn+Y8XUNY0TwHKaDFUTGWzOfBGRP2kxS2YFNZhTQAn5R+LsHutqVG1 +tGUf0cLW8IKT/lagKofdPOirTIFZdVwhZcVkHlZ/PR5fTYJutuEsL6sScogtUmlZ +L0LbqzX80AazPPM6+2NkmcPZFuB2ZuOIULd+AGECgYBt40PiCf1WmAQK9J3pylOD +s7kWwzapIAKf92JBJmo5sOushYsPXAnqUJaZERpBBCmsdtYyjQV8VYxg/CrU5CkE +0zdFmFcfw7swwaE+aJLwueV1qR7lKi89DYZ9OFI+Z0JoekQc/TPeJLg1MctK76qA +OMswum0oXiu/zZJGGtCegg== +-----END PRIVATE KEY----- diff --git a/examples/_extra_certs/domain3.crt.pem b/examples/_extra_certs/domain3.crt.pem new file mode 100644 index 000000000000..fdfbd07e9321 --- /dev/null +++ b/examples/_extra_certs/domain3.crt.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIUI/iTc/yKhX+HkiDCKAuCa25fxQwwDQYJKoZIhvcNAQEL +BQAwUjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRgwFgYDVQQKDA9NeUV4YW1w +bGUsIEluYy4xHDAaBgNVBAMME2RvbWFpbjMuZXhhbXBsZS5jb20wHhcNMjAxMTEy +MTEwNzA3WhcNMjExMTEyMTEwNzA3WjBSMQswCQYDVQQGEwJVUzELMAkGA1UECAwC +Q0ExGDAWBgNVBAoMD015RXhhbXBsZSwgSW5jLjEcMBoGA1UEAwwTZG9tYWluMy5l +eGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOO0k18 +6k3164UpYGVOC1oj8jbmdZeeg57mkamYE9CUk0W9KKgHOCSNMZXUxPtnqtqJgJ92 +ccawTe0WrbOKQA3ARK7WePbX3HepJfTFZgCC5d5njRPDfIgsk4MP89nc2p8qO5Vv +SvCTae8/ykTyfz5fKwaGMYwvrSGUpuhFD8OFMOAsvnoIXZd+ixLkDATupP/IaV0a +6tHs6BnC3vxn+baC30fuHKErfOh7Jlo3FDqXNMwfes6MJ7/u8odeFfuGOaaO4eRT +EAhy4VQBJkCtS3yCFEv3kCRXjmgEBDSQ9jDjtnykOqViO5euibeKxnz+7xjRWVGY +bT5Z+s6eUHkiraMCAwEAAaNTMFEwHQYDVR0OBBYEFDVYD/F+NzsKgfYsRM6XfMuB +qXmqMB8GA1UdIwQYMBaAFDVYD/F+NzsKgfYsRM6XfMuBqXmqMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBABwiF5AVDmQTLYE4wuHxq245qOj/vKfi +1L2lNgZ7G2Luobbvli2SQo7g8UYMSrwNF3Y1TDoEryeYMKYr2udb8WvdzhlL3z/J +a/qBElwWsATnpRfBAqxeWkx0x0E0C4nrjXM7PbAEjvEZ2AQKc5zmvii1Ek4h/+Sa +h2+Tmm5zg0Lo410CqujRmGtHU2AtkqguOhNrvJcRxEH4iLDB87WfUlLW6JrN+CLB +qIxkyLlhMUNMa200mpsfwQQRdImTjdn+VgpFR9BeZYU2gPZxqdxKcyrGfYXim1oJ +dC34TKistMWFs0C3l+Xs7unqSkqk5s1Nkdh6vnMF39PkwFoVP3Nn2wY= +-----END CERTIFICATE----- diff --git a/examples/_extra_certs/domain3.key.pem b/examples/_extra_certs/domain3.key.pem new file mode 100644 index 000000000000..84f259bd0a8a --- /dev/null +++ b/examples/_extra_certs/domain3.key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDDjtJNfOpN9euF +KWBlTgtaI/I25nWXnoOe5pGpmBPQlJNFvSioBzgkjTGV1MT7Z6raiYCfdnHGsE3t +Fq2zikANwESu1nj219x3qSX0xWYAguXeZ40Tw3yILJODD/PZ3NqfKjuVb0rwk2nv +P8pE8n8+XysGhjGML60hlKboRQ/DhTDgLL56CF2XfosS5AwE7qT/yGldGurR7OgZ +wt78Z/m2gt9H7hyhK3zoeyZaNxQ6lzTMH3rOjCe/7vKHXhX7hjmmjuHkUxAIcuFU +ASZArUt8ghRL95AkV45oBAQ0kPYw47Z8pDqlYjuXrom3isZ8/u8Y0VlRmG0+WfrO +nlB5Iq2jAgMBAAECggEBALe2MUzIP9kTYLlNIJiq07FPuZjnsarJKD8bvdWD34GA +QkYuqMYJWi3EUsO+CXtgbTo2GJY1kDcmo15Kgs3636fLavqQ0zyZlyz2w4iJ9QQf +9FCWGQtrB09qCP4D+4I8n0kNRMJithUBd3BiDePtp6nxf5r2cA+RLmUwoAft8Rws +GoZF5vm93iHF29H/nbP7KNTyBAoRq95y+SiXvcLOb9pN5IwAiqkAcVF8YpUCqsQL +PRTJZupSRU3Cg0Asq9nvqxeTBrySeOkoRid9b/5/MKP2CXNkGoOl7TCiHJ1SFYCd +waN+516Nd6Hu8WpH7n3eqcc/JhmP7jLv3vqLYAWpJ/ECgYEA9XigdnEiGFuP/SAE +l8InIGfNxGegEb9AMifZdir4lI1BKC+Ke84TD0V5tgHS5zsk8SOAIERHrclOTtHR +WPEx+GDrsukl3QDisdFE6sU1ktZ9S0uim9hYGaAtxME99U3EhDTBLApNyhxe2REC +yZoCuObqz7OVCu+SZ6/etw5mk+kCgYEAy/IgXJxCD3ais1Jy0DOfrzSExXulOi4X ++EWtMNcBkcYxE0Jl1mpsgd7GZNnJCf8ThajetREPFYzMCYiI6KOtOJBi+Bil6hpI +N2U29LD/dxIotHzdIau4ESFODJdgP2agzFx72JDKEBxGsuc7x5bd7P8hex+XURTW +KVuawJPXOasCgYEAoYXCcK149fYqBTGwU/vZqyUi7P4TAhqKr3YxTeRwta9NFJhT +06uCNyZMNEt279inMlVd1d2YHO69rHe7/X6YlwuPjKaF16rhgIhnhORHoFurDoSy +d0IglpwkAbf2gRevHB9qjQQqs7d/Ye4jm2zQJcMs94b/p7aE6915+5JqRSECgYAo +uC4n73btGXXAsfyEf1oppCXCPD6wEBXvFxJORw9kKJsRylcE6XjCsVURO759BXXD +YQUeR8qoNdVjLeSP9mYWfhWUjW9K/3ZdwRKo5lILVw/TgX6xQ1Tb7rdjojGwVvBR +/UEo6ze84bhn7e0sm32x3Pq1V4hhwvRDi6upOZtmQwKBgQDbjiPYdqKkbrC7YFsH +4m9VenSmnOppugcYU5h3zLORERfuTBT4cT2TEZT4zlz1vUZFjoQ5ML97xSGeCKzN +0Y0uh6zRgoy2zAQzwmtrNi80GuFEv1CJq7qxzz3aDU2Y/qYFmnl2cTwLNC+MxpbJ +lpvH9Ufkaj4vu/Iuw/Dnc2BPQg== +-----END PRIVATE KEY----- diff --git a/examples/tls-sni/Dockerfile b/examples/tls-sni/Dockerfile new file mode 100644 index 000000000000..e7d9edb34d93 --- /dev/null +++ b/examples/tls-sni/Dockerfile @@ -0,0 +1,9 @@ +FROM envoyproxy/envoy-dev:latest + +COPY ./envoy.yaml /etc/envoy.yaml +COPY ./certs /certs +RUN chmod go+r /etc/envoy.yaml \ + && chmod go+x /certs \ + && chmod go+r /certs/* + +CMD ["/usr/local/bin/envoy", "-c", "/etc/envoy.yaml", "-l", "debug"] diff --git a/examples/tls-sni/Dockerfile-client b/examples/tls-sni/Dockerfile-client new file mode 100644 index 000000000000..ef7428f83f6b --- /dev/null +++ b/examples/tls-sni/Dockerfile-client @@ -0,0 +1,6 @@ +FROM envoyproxy/envoy-dev:latest + +COPY ./envoy-client.yaml /etc/envoy.yaml +RUN chmod go+r /etc/envoy.yaml + +CMD ["/usr/local/bin/envoy", "-c /etc/envoy.yaml"] diff --git a/examples/tls-sni/README.md b/examples/tls-sni/README.md new file mode 100644 index 000000000000..8f43b19a059f --- /dev/null +++ b/examples/tls-sni/README.md @@ -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-sni.html). diff --git a/examples/tls-sni/docker-compose.yaml b/examples/tls-sni/docker-compose.yaml new file mode 100644 index 000000000000..0c5fbd4ac516 --- /dev/null +++ b/examples/tls-sni/docker-compose.yaml @@ -0,0 +1,34 @@ +version: "3.7" +services: + + proxy: + build: + context: . + dockerfile: Dockerfile + ports: + - "10000:10000" + + proxy-client: + build: + context: . + dockerfile: Dockerfile-client + ports: + - "20000:10000" + + http-upstream1: + image: mendhak/http-https-echo + hostname: http-upstream1 + environment: + - HTTPS_PORT=0 + + http-upstream2: + image: mendhak/http-https-echo + hostname: http-upstream2 + environment: + - HTTPS_PORT=0 + + https-upstream3: + image: mendhak/http-https-echo + hostname: https-upstream3 + environment: + - HTTP_PORT=0 diff --git a/examples/tls-sni/envoy-client.yaml b/examples/tls-sni/envoy-client.yaml new file mode 100644 index 000000000000..0ba5b2ebc8e2 --- /dev/null +++ b/examples/tls-sni/envoy-client.yaml @@ -0,0 +1,92 @@ +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: "/domain1" + route: + cluster: proxy-client-domain1 + - match: + prefix: "/domain2" + route: + cluster: proxy-client-domain2 + - match: + prefix: "/domain3" + route: + cluster: proxy-client-domain3 + http_filters: + - name: envoy.filters.http.router + + clusters: + - name: proxy-client-domain1 + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: proxy-client-domain1 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: proxy + port_value: 10000 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + sni: domain1.example.com + + - name: proxy-client-domain2 + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: proxy-client-domain2 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: proxy + port_value: 10000 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + sni: domain2.example.com + + - name: proxy-client-domain3 + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: proxy-client-domain3 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: proxy + port_value: 10000 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + sni: domain3.example.com diff --git a/examples/tls-sni/envoy.yaml b/examples/tls-sni/envoy.yaml new file mode 100644 index 000000000000..cd6245e8209b --- /dev/null +++ b/examples/tls-sni/envoy.yaml @@ -0,0 +1,127 @@ +static_resources: + listeners: + - address: + socket_address: + address: 0.0.0.0 + port_value: 10000 + listener_filters: + - name: "envoy.filters.listener.tls_inspector" + filter_chains: + - filter_chain_match: + server_names: + - domain1.example.com + 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: proxy-domain1 + http_filters: + - name: envoy.filters.http.router + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + common_tls_context: + tls_certificates: + certificate_chain: + filename: certs/domain1.crt.pem + private_key: + filename: certs/domain1.key.pem + + - filter_chain_match: + server_names: + - domain2.example.com + 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: proxy-domain2 + http_filters: + - name: envoy.filters.http.router + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + common_tls_context: + tls_certificates: + certificate_chain: + filename: certs/domain2.crt.pem + private_key: + filename: certs/domain2.key.pem + + - filter_chain_match: + server_names: + - domain3.example.com + filters: + - name: envoy.filters.network.tcp_proxy + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + cluster: proxy-domain3 + stat_prefix: ingress_domain3 + + clusters: + - name: proxy-domain1 + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: proxy-domain1 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: http-upstream1 + port_value: 80 + + - name: proxy-domain2 + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: proxy-domain2 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: http-upstream2 + port_value: 80 + + - name: proxy-domain3 + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: proxy-domain3 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: https-upstream3 + port_value: 443 diff --git a/examples/tls-sni/verify.sh b/examples/tls-sni/verify.sh new file mode 100755 index 000000000000..32f639cd7104 --- /dev/null +++ b/examples/tls-sni/verify.sh @@ -0,0 +1,51 @@ +#!/bin/bash -e + +export NAME=tls-sni +export MANUAL=true + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +create_self_signed_certs () { + local domain="$1" + openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \ + -subj "/C=US/ST=CA/O=MyExample, Inc./CN=${domain}.example.com" \ + -keyout "certs/${domain}.key.pem" \ + -out "certs/${domain}.crt.pem" +} + +mkdir -p certs + +run_log "Create certificates for each of the services" +create_self_signed_certs domain1 +create_self_signed_certs domain2 + +bring_up_example + +run_log "Query domain1 with curl and tls/sni" +curl -sk --resolve domain1.example.com:10000:127.0.0.1 \ + https://domain1.example.com:10000 \ + | jq '.os.hostname' | grep http-upstream1 + +run_log "Query domain2 with curl and tls/sni" +curl -sk --resolve domain2.example.com:10000:127.0.0.1 \ + https://domain2.example.com:10000 \ + | jq '.os.hostname' | grep http-upstream2 + +run_log "Query domain3 with curl and tls/sni" +curl -sk --resolve domain3.example.com:10000:127.0.0.1 \ + https://domain3.example.com:10000 \ + | jq '.os.hostname' | grep https-upstream3 + +run_log "Query domain1 via Envoy sni client" +curl -s http://localhost:20000/domain1 \ + | jq '.os.hostname' | grep http-upstream1 + +run_log "Query domain2 via Envoy sni client" +curl -s http://localhost:20000/domain2 \ + | jq '.os.hostname' | grep http-upstream2 + +run_log "Query domain3 via Envoy sni client" +curl -s http://localhost:20000/domain3 \ + | jq '.os.hostname' | grep https-upstream3