app.UseOpenTelemetryPrometheusScrapingEndpoint();
添加端点 /metrics
,其中 Prometheus
抓取收集的指标。
然而,该端点没有任何身份验证,任何人都可以调用。
端点是否有配置来添加一些基本或自定义身份验证?
UseOpenTelemetryPrometheusScrapingEndpoint()
允许您提供返回 true 或 false 的谓词以服务于指标端点或不服务。您可以使用谓词检查授权标头,然后阻止或授予请求。
例如,您可以检查谓词中的
Basic
授权标头,如下所述:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/basic-authentication
app.UseOpenTelemetryPrometheusScrapingEndpoint(
context =>
{
if (context.Request.Path != "/metrics") return false;
var authHeader = context.Request.Headers.Authorization.FirstOrDefault();
if (authHeader == null) return false;
var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
if (authHeaderVal == null) return false;
// RFC 2617 sec 1.2, "scheme" name is case-insensitive
if (!authHeaderVal.Scheme.Equals("basic",
StringComparison.OrdinalIgnoreCase) ||
authHeaderVal.Parameter == null)
{
return false;
}
var encoding = Encoding.GetEncoding("iso-8859-1");
var credentials = encoding.GetString(Convert.FromBase64String(authHeaderVal.Parameter));
int separator = credentials.IndexOf(':');
string name = credentials.Substring(0, separator);
string password = credentials.Substring(separator + 1);
return name == "your_username" && password == "your_password";
});
当然,你的 prometheus 配置也必须与基本身份验证凭据匹配:
basic_auth:
username: your_username
password: your_password
为指标端点启用身份验证是一种方法,您是否考虑过另一种常用方法 ->
在不同端口上创建单独的 Web 服务器端点,例如 KestrelMetricServer 的新实例。 对此端点的访问受到防火墙规则的限制,仅允许特定的 IP 地址进行连接。有关实际示例,您可以参考 GitHub 上提供的sample。
在这种方法中,Prometheus 指标通过单独的 HTTP 服务器公开,与主应用程序一起运行。通过将防火墙配置为仅允许来自特定 IP 地址的访问,您可以确保只有授权方才能访问指标。这为您的指标端点提供了额外的安全层。
我最近在为应用程序设置遥测时遇到了类似的问题。我最终做了以下事情:
/metrics
端点的传入请求进行基本身份验证UseOpenTelemetryPrometheusScrapingEndpoint
方法允许通过分支管道处理请求,该分支管道可以配置任意中间件。我创建了一个中间件,它调用 AuthenticateAsync
并在传入的 http 上下文上使用我的自定义身份验证方案。如果请求成功验证,则调用下一个委托并处理请求,如果没有成功,则响应的状态码设置为 401 并且不返回任何数据。此方法会为具有无效凭据的请求返回正确的状态代码。相反,在谓词中运行身份验证代码将返回 404 - 谓词的 false 结果意味着“不要分支管道,端点
/metrics
不存在”。