配置特使以跳过特定 http 路由上的 mTLS
Configuring envoy to skip mTLS on a specific http route
我正在使用 envoy 有一个边缘代理。
基本上我希望 mTLS 在除一个之外的所有 http 路径上下游。
我有以下配置:
请注意我如何在第一条路线
中设置 require_client_certificate: false
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
所以,当我做一个
curl -k --location --cacert cabundle.pem --request GET 'http://localhost:443/s1/request/get'
我希望请求通过并获得 200 响应
然而,如果我点击 /s1/request/post
,那么我希望 mTLS 发生,所以我应该提供证书和密钥。
但是,当我启动 envoy 时,出现以下错误
[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
这是完成我想要的事情的正确方法吗?
@kosta 您需要在 TLS 侦听器上指定一个新字段 filter_chain_match
。基本上,现在您的两个侦听器应该匹配所有传入连接,因此特使不知道对任何给定连接使用哪个。
如果您将下面的字段添加到您的第二个侦听器,它将仅匹配 TLS 连接,这将允许 Envoy 启动。
filter_chain_match:
transport_protocol: tls
我修改了您的第二个侦听器,如下所示,Envoy 启动正常。
- 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
filter_chain_match:
transport_protocol: "tls"
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
唯一需要注意的是,必须为每条路线重复此操作,为每条路线设置适当的值。
我正在使用 envoy 有一个边缘代理。 基本上我希望 mTLS 在除一个之外的所有 http 路径上下游。 我有以下配置: 请注意我如何在第一条路线
中设置require_client_certificate: false
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
所以,当我做一个
curl -k --location --cacert cabundle.pem --request GET 'http://localhost:443/s1/request/get'
我希望请求通过并获得 200 响应
然而,如果我点击 /s1/request/post
,那么我希望 mTLS 发生,所以我应该提供证书和密钥。
但是,当我启动 envoy 时,出现以下错误
[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
这是完成我想要的事情的正确方法吗?
@kosta 您需要在 TLS 侦听器上指定一个新字段 filter_chain_match
。基本上,现在您的两个侦听器应该匹配所有传入连接,因此特使不知道对任何给定连接使用哪个。
如果您将下面的字段添加到您的第二个侦听器,它将仅匹配 TLS 连接,这将允许 Envoy 启动。
filter_chain_match:
transport_protocol: tls
我修改了您的第二个侦听器,如下所示,Envoy 启动正常。
- 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
filter_chain_match:
transport_protocol: "tls"
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
唯一需要注意的是,必须为每条路线重复此操作,为每条路线设置适当的值。