Securing Envoy¶
Envoy provides a number of features to secure traffic in and out of your network, and between proxies and services within your network.
Transport Layer Security (TLS
) can be used to secure all types of HTTP
traffic, including WebSockets
.
Envoy also has support for transmitting and receiving generic TCP
traffic with TLS
.
Envoy also offers a number of other HTTP
-based protocols for authentication and authorization
such as JWT, RBAC
and OAuth.
Warning
The following guide takes you through individual aspects of securing traffic.
To secure traffic over a network that is untrusted, you are strongly advised to make use of encryption and mutual authentication wherever you control both sides of the connection or where relevant protocols are available.
Here we provide a guide to using mTLS which provides both encryption and mutual authentication.
When using TLS
, you are strongly encouraged to validate
all certificates wherever possible.
It is your responsibility to ensure the integrity of your certificate chain, and outside the scope of this guide.
Upstream and downstream TLS
contexts¶
Machines connecting to Envoy to proxy traffic are “downstream” in relation to Envoy.
Specifying a TLS
context that clients can connect to is achieved by setting the
DownstreamTLSContext
in the transport_socket of a
listener.
You will also need to provide valid certificates.
1static_resources:
2
3 listeners:
4 - name: listener_0
5 address:
6 socket_address:
7 address: 0.0.0.0
8 port_value: 10000
9 filter_chains:
10 - filters:
11 - name: envoy.filters.network.http_connection_manager
12 typed_config:
13 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
14 stat_prefix: ingress_http
15 http_filters:
16 - name: envoy.filters.http.router
17 typed_config:
18 "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
19 route_config:
20 name: local_route
21 virtual_hosts:
22 - name: local_service
23 domains: ["*"]
24 routes:
25 - match:
26 prefix: "/"
27 route:
28 host_rewrite_literal: www.envoyproxy.io
29 cluster: service_envoyproxy_io
30 transport_socket:
31 name: envoy.transport_sockets.tls
32 typed_config:
33 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
34 common_tls_context:
35 tls_certificates:
36 - certificate_chain:
37 filename: certs/servercert.pem
38 private_key:
39 filename: certs/serverkey.pem
Connecting to an “upstream” TLS
service is conversely done by adding an
UpstreamTLSContext
to the transport_socket of a
cluster.
40 clusters:
41 - name: service_envoyproxy_io
42 type: LOGICAL_DNS
43 # Comment out the following line to test on v6 networks
44 dns_lookup_family: V4_ONLY
45 load_assignment:
46 cluster_name: service_envoyproxy_io
47 endpoints:
48 - lb_endpoints:
49 - endpoint:
50 address:
51 socket_address:
52 address: www.envoyproxy.io
53 port_value: 443
54 transport_socket:
55 name: envoy.transport_sockets.tls
56 typed_config:
57 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
Validate an endpoint’s certificates when connecting¶
When Envoy connects to an upstream TLS
service, it does not, by default, validate the certificates
that it is presented with.
You can use the validation_context to specify how Envoy should validate these certificates.
Firstly, you can ensure that the certificates are from a mutually trusted certificate authority:
42 socket_address:
43 address: www.envoyproxy.io
44 port_value: 443
45 transport_socket:
46 name: envoy.transport_sockets.tls
47 typed_config:
48 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
49 common_tls_context:
50 validation_context:
51 trusted_ca:
52 filename: certs/cacert.pem
You can also ensure that the “Subject Alternative Names” for the cerficate match.
This is commonly used by web certificates (X.509) to identify the domain or domains that a certificate is valid for.
44 port_value: 443
45 transport_socket:
46 name: envoy.transport_sockets.tls
47 typed_config:
48 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
49 common_tls_context:
50 validation_context:
51 trusted_ca:
52 filename: certs/cacert.pem
53 match_typed_subject_alt_names:
54 - san_type: DNS
Note
If the “Subject Alternative Names” for a certificate are for a wildcard domain, eg *.example.com
,
this is what you should use when matching with match_typed_subject_alt_names
.
Note
See here to view all of the possible configurations for certificate validation.
Use mutual TLS
(mTLS
) to enforce client certificate authentication¶
With mutual TLS
(mTLS
), Envoy also provides a way to authenticate connecting clients.
At a minimum you will need to set require_client_certificate and specify a mutually trusted certificate authority:
29 cluster: service_envoyproxy_io
30 transport_socket:
31 name: envoy.transport_sockets.tls
32 typed_config:
33 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
34 require_client_certificate: true
35 common_tls_context:
36 validation_context:
37 trusted_ca:
38 filename: certs/cacert.pem
39 match_typed_subject_alt_names:
40 - san_type: DNS
41 matcher:
42 exact: proxy-postgres-frontend.example.com
43 tls_certificates:
You can further restrict the authentication of connecting clients by specifying the allowed “Subject Alternative Names” in match_typed_subject_alt_names, similar to validating upstream certificates described above.
29 cluster: service_envoyproxy_io
30 transport_socket:
31 name: envoy.transport_sockets.tls
32 typed_config:
33 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
34 require_client_certificate: true
35 common_tls_context:
36 validation_context:
37 trusted_ca:
38 filename: certs/cacert.pem
39 match_typed_subject_alt_names:
40 - san_type: DNS
41 matcher:
42 exact: proxy-postgres-frontend.example.com
43 tls_certificates:
Note
See here to view all of the possible configurations for certificate validation.
Use mutual TLS
(mTLS
) to connect with client certificates¶
When connecting to an upstream with client certificates you can set them as follows:
46 private_key:
47 filename: certs/serverkey.pem
48
49 clusters:
50 - name: service_envoyproxy_io
51 type: LOGICAL_DNS
52 # Comment out the following line to test on v6 networks
53 dns_lookup_family: V4_ONLY
54 load_assignment:
55 cluster_name: service_envoyproxy_io
56 endpoints:
57 - lb_endpoints:
58 - endpoint:
59 address:
60 socket_address:
61 address: www.envoyproxy.io
62 port_value: 443
63 transport_socket:
64 name: envoy.transport_sockets.tls
65 typed_config:
66 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
67 common_tls_context:
68 tls_certificates:
69 - certificate_chain:
70 filename: certs/clientcert.pem
Provide multiple TLS
domains at the same IP
address with SNI
¶
SNI
is an extension to the TLS
protocol which allows multiple domains served
from the same IP
address to be secured with TLS
.
To secure specific domains on a listening connection with SNI
, you should set the
filter_chain_match of the
listener:
29 cluster: service_envoyproxy_io
30 filter_chain_match:
31 server_names:
32 - my-service-name.example.com
33 transport_socket:
34 name: envoy.transport_sockets.tls
35 typed_config:
36 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
37 common_tls_context:
See here for more info about creating multiple endpoints with SNI
Connect to an endpoint with SNI
¶
When connecting to a TLS
endpoint that uses SNI
you should set
sni in the configuration
of the UpstreamTLSContext.
This will usually be the DNS name of the service you are connecting to.
57 port_value: 443
58 transport_socket:
59 name: envoy.transport_sockets.tls
60 typed_config:
61 "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
62 sni: www.envoyproxy.io
When connecting to an Envoy endpoint that is protected by SNI
, this must match one of the
server_names set in the endpoint’s
filter_chain_match, as
described above.