I am using envoy has an edge proxy.
Basically I want mTLS downstream on all http paths except for one.
I have the following config:
Notice how I set require_client_certificate: false
in the first route
admin:
access_log_path: /dev/stdout
address:
socket_address:
address: 127.0.0.1
port_value: 9901
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 443
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
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/s1/request/get"
headers:
- name: ":method"
exact_match: "GET"
route:
host_rewrite_literal: service1
cluster: internal_service1
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
require_client_certificate: false
common_tls_context:
tls_certificates:
certificate_chain:
filename: /etc/ssl/listener/cert.pem
private_key:
filename: /etc/ssl/listener/key.pem
validation_context:
trusted_ca:
filename: /etc/ssl/cluster/cabundle.pem
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/s1/request/post"
headers:
- name: ":method"
exact_match: "POST"
route:
host_rewrite_literal: service1
cluster: internal_service1
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
require_client_certificate: true
common_tls_context:
tls_certificates:
certificate_chain:
filename: /etc/ssl/listener/cert.pem
private_key:
filename: /etc/ssl/listener/key.pem
validation_context:
trusted_ca:
filename: /etc/ssl/cluster/cabundle.pem
clusters:
- name: internal_service1
connect_timeout: 0.25s
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: internal_service1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: service1
port_value: 443
tls_context:
allow_renegotiation: true
common_tls_context:
tls_certificates:
certificate_chain:
filename: /etc/ssl/listener/cert.pem
private_key:
filename: /etc/ssl/listener/key.pem
validation_context:
trusted_ca:
filename: /etc/ssl/cluster/cabundle.pem
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: service1
So, when I do a
curl -k --location --cacert cabundle.pem --request GET 'http://localhost:443/s1/request/get'
I expect the request to go through and get a 200 response
Whereas, I if I hit /s1/request/post
, then I expect mTLS to take place so I should be providing a certificate and a key.
However, when I start the envoy, I get the following error
[2020-10-28 05:42:40.674][1][debug][init] [source/common/init/watcher_impl.cc:27] init manager Server destroyed
error adding listener '0.0.0.0:443': multiple filter chains with the same matching rules are defined
make: *** [run-local] Error 1
Is this the correct way to do the stuff I want?
I think I found the answer. Referring to https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/route/route_components.proto#envoy-api-msg-route-routematch-tlscontextmatchoptions
The only caveat is that this has to be repeat for each route, setting the values appropriately for each route.