feat: добавил prometheus экспортер
Backend CI / build-and-test (push) Successful in 43s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 7s
Backend CI / build-and-test (pull_request) Successful in 44s
Frontend Playwright / e2e (pull_request) Has been cancelled
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 59s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Has been skipped
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 4s
Backend CI / build-and-test (push) Successful in 43s
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 7s
Backend CI / build-and-test (pull_request) Successful in 44s
Frontend Playwright / e2e (pull_request) Has been cancelled
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 59s
🚀 Create and publish a Docker image / Build & publish frontend image (push) Has been skipped
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 4s
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace UniVerse.Api.Middleware;
|
||||
|
||||
public sealed class LocalNetworksOnlyMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ILogger<LocalNetworksOnlyMiddleware> _logger;
|
||||
|
||||
public LocalNetworksOnlyMiddleware(RequestDelegate next, ILogger<LocalNetworksOnlyMiddleware> logger)
|
||||
{
|
||||
_next = next;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
var remoteIpAddress = context.Connection.RemoteIpAddress;
|
||||
|
||||
if (remoteIpAddress is null || !IsLocalNetwork(remoteIpAddress))
|
||||
{
|
||||
_logger.LogWarning("Blocked metrics request from non-local address {RemoteIpAddress}", remoteIpAddress);
|
||||
context.Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||
await context.Response.WriteAsync("Metrics endpoint is available only from local networks.");
|
||||
return;
|
||||
}
|
||||
|
||||
await _next(context);
|
||||
}
|
||||
|
||||
private static bool IsLocalNetwork(IPAddress ipAddress)
|
||||
{
|
||||
if (IPAddress.IsLoopback(ipAddress))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ipAddress.IsIPv4MappedToIPv6)
|
||||
{
|
||||
ipAddress = ipAddress.MapToIPv4();
|
||||
}
|
||||
|
||||
return ipAddress.AddressFamily switch
|
||||
{
|
||||
AddressFamily.InterNetwork => IsPrivateOrLinkLocalIPv4(ipAddress),
|
||||
AddressFamily.InterNetworkV6 => IsPrivateOrLinkLocalIPv6(ipAddress),
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
private static bool IsPrivateOrLinkLocalIPv4(IPAddress ipAddress)
|
||||
{
|
||||
var bytes = ipAddress.GetAddressBytes();
|
||||
|
||||
return bytes[0] == 10
|
||||
|| bytes[0] == 127
|
||||
|| (bytes[0] == 192 && bytes[1] == 168)
|
||||
|| (bytes[0] == 172 && bytes[1] is >= 16 and <= 31)
|
||||
|| (bytes[0] == 169 && bytes[1] == 254);
|
||||
}
|
||||
|
||||
private static bool IsPrivateOrLinkLocalIPv6(IPAddress ipAddress)
|
||||
{
|
||||
var bytes = ipAddress.GetAddressBytes();
|
||||
|
||||
return ipAddress.IsIPv6LinkLocal
|
||||
|| ipAddress.IsIPv6SiteLocal
|
||||
|| (bytes[0] & 0xfe) == 0xfc;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user