C# (ASP.NET Core)
W środowiskach korporacyjnych Microsoft integracja ProxyTracer bezpośrednio z potokiem żądań HTTP (request pipeline) ASP.NET Core gwarantuje, że złośliwy ruch zostanie odrzucony przed uruchomieniem routingu, bindowania modeli (model binding) czy zapytań do bazy danych.
Middleware
Ta implementacja używa System.Text.Json do ultraszybkiej deserializacji, wymusza ścisły limit czasu przez HttpClient i natychmiast przerywa potok żądania (short-circuit), zwracając odpowiedź 403 Forbidden w przypadku wykrycia proxy.
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace ProxyTracer.Security
{
public class ProxyTracerMiddleware
{
private readonly RequestDelegate _next;
private readonly HttpClient _httpClient;
private readonly ILogger<ProxyTracerMiddleware> _logger;
private readonly string _apiKey;
public ProxyTracerMiddleware(RequestDelegate next, IConfiguration config, ILogger<ProxyTracerMiddleware> logger)
{
_next = next;
_logger = logger;
_apiKey = config["PROXYTRACER_API_KEY"] ?? throw new ArgumentNullException("PROXYTRACER_API_KEY is missing");
// Klient wielokrotnego użytku ze ścisłym limitem czasu 500 ms
_httpClient = new HttpClient { Timeout = TimeSpan.FromMilliseconds(500) };
}
public async Task InvokeAsync(HttpContext context)
{
// 1. Pobierz adres IP (Wymaga skonfigurowania app.UseForwardedHeaders() w Program.cs)
var ip = context.Connection.RemoteIpAddress?.ToString();
// Pomiń lokalne adresy IP środowiska deweloperskiego
if (!string.IsNullOrEmpty(ip) && ip != "127.0.0.1" && ip != "::1")
{
try
{
// 2. Odpytaj asynchronicznie API ProxyTracer
using var request = new HttpRequestMessage(HttpMethod.Get, $"https://api.proxytracer.com/v1/check/{ip}");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey);
using var response = await _httpClient.SendAsync(request);
if (response.IsSuccessStatusCode)
{
using var jsonStream = await response.Content.ReadAsStreamAsync();
var ptResponse = await JsonSerializer.DeserializeAsync<ProxyTracerResult>(jsonStream);
// 3. Odrzuć połączenie, jeśli wykryto proxy/VPN
if (ptResponse != null && ptResponse.Proxy)
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync("{\"error\": \"Access Denied: VPN or Proxy detected.\"}");
return; // Natychmiast zakończ przetwarzanie żądania (short-circuit)
}
}
}
catch (Exception ex)
{
// Fail-open: Zaloguj błąd i przepuść żądanie
_logger.LogWarning($"ProxyTracer validation failed: {ex.Message}");
}
}
// 4. Ruch jest czysty, przekaż żądanie do kontrolerów
await _next(context);
}
// Lekka struktura mapująca dokładnie odpowiedź {"proxy": true|false}
private class ProxyTracerResult
{
[JsonPropertyName("proxy")]
public bool Proxy { get; set; }
}
}
}Konfiguracja:
Aby włączyć ochronę, zarejestruj middleware w pliku Program.cs. Upewnij się, że znajduje się po UseForwardedHeaders, ale przed UseRouting i UseAuthentication.
var app = builder.Build();
// 1. Upewnij się, że prawdziwy adres IP jest poprawnie pobierany zza load balancera NGINX/Cloudflare
app.UseForwardedHeaders();
// 2. Wcześnie odrzucaj złośliwy ruch
app.UseMiddleware<ProxyTracer.Security.ProxyTracerMiddleware>();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();Ostatnia aktualizacja: