Last active
February 10, 2024 07:26
-
-
Save ofek/6051508cd0dfa98fc6c13153b647c6f8 to your computer and use it in GitHub Desktop.
Envoy secured stats endpoint example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"listeners": [ | |
{ | |
"address": "tcp://0.0.0.0:80", | |
"filters": [ | |
{ | |
"type": "read", | |
"name": "http_connection_manager", | |
"config": { | |
"codec_type": "auto", | |
"stat_prefix": "ingress_http", | |
"route_config": { | |
"virtual_hosts": [ | |
{ | |
"name": "backend", | |
"domains": ["*"], | |
"routes": [ | |
{ | |
"timeout_ms": 0, | |
"prefix": "/stats", | |
"cluster": "service_stats" | |
} | |
] | |
} | |
] | |
}, | |
"filters": [ | |
{ | |
"type": "decoder", | |
"name": "router", | |
"config": {} | |
} | |
] | |
} | |
} | |
] | |
} | |
], | |
"admin": { | |
"access_log_path": "/dev/null", | |
"address": "tcp://127.0.0.1:8001" | |
}, | |
"cluster_manager": { | |
"clusters": [ | |
{ | |
"name": "service_stats", | |
"connect_timeout_ms": 250, | |
"type": "logical_dns", | |
"lb_type": "round_robin", | |
"hosts": [ | |
{ | |
"url": "tcp://127.0.0.1:8001" | |
} | |
] | |
} | |
] | |
} | |
} |
I like the idea of splitting off read-only vs read-write access to admin. I am not convinced that restricting r/w access to localhost is sufficient however.
@junr03 has converted this to the v2 format
admin:
access_log_path: /dev/null
address:
socket_address:
protocol: TCP
address: 127.0.0.1
port_value: 8081
static_resources:
listeners:
- address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
codec_type: AUTO
stat_prefix: ingress_http
route_config:
virtual_hosts:
- name: backend
domains:
- "*"
routes:
- match:
prefix: /stats
route:
cluster: service_stats
http_filters:
- name: envoy.router
config:
clusters:
- name: service_stats
connect_timeout: 0.250s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
hosts:
- socket_address:
protocol: TCP
address: 127.0.0.1
port_value: 8081
thanks for sharing the config! I tried it out and works as expected! @ofek is the last line suppose to be port 8081, if I'm not mistaken.
^ yep that's correct, the service_stats
cluster should point to 127.0.0.1:8081
Updated!
@ofek I assume existing docs on Datadog page are actually for v2 xDS version? So it will be something like this for v3 (haven't tried it though)
admin:
access_log_path: /dev/null
address:
socket_address:
address: 127.0.0.1
port_value: 8081
static_resources:
listeners:
- name: listener_1
address:
socket_address:
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: /stats
route:
cluster: service_stats
clusters:
- name: service_stats
connect_timeout: 0.250s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8081
@ofek @michaelDovgal this is an updated config for v3 (I was also trying to implement Datadog monitoring and this works)
admin:
access_log_path: /dev/null
address:
socket_address:
protocol: TCP
address: 127.0.0.1
port_value: 8081
static_resources:
listeners:
- name: stats_listener # exposes the stats endpoint for datadog monitoring
address:
socket_address:
protocol: TCP
address: 0.0.0.0
port_value: 80
filter_chains:
- filters:
- name: envoy.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
virtual_hosts:
- name: backend
domains:
- "*"
routes:
- match:
prefix: /stats
route:
cluster: service_stats
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: service_stats
connect_timeout: 0.250s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_stats
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8081
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Problem: Currently, if you want to allow a non-localhost scraper to access
/stats
, you also give it access to other admin things like/quitquitquit
.Solution (from a Slack discussion):
Idea courtesy of @ggreenway
Config courtesy of @bndw
Create a listener/vhost that routes to the admin endpoint (Envoy connecting to itself), but only has a route for
/stats
; all other routes get a static/error response. Additionally, this allows nice integration with L3 filters for auth, for example.