ServiceCollectionExtensions.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. using SharedKernel;
  2. using Microsoft.AspNetCore.HttpOverrides;
  3. using System.Net;
  4. namespace Web.Api.Extensions;
  5. public static class ServiceCollectionExtensions
  6. {
  7. /// <summary>
  8. /// Cloudflare → IIS reverse proxy → backend 환경에서 X-Forwarded-For/Proto/Host 헤더를 신뢰해
  9. /// HttpContext.Connection.RemoteIpAddress 등을 실 client 값으로 갱신.
  10. ///
  11. /// IIS web.config 가 `HTTP_X_FORWARDED_FOR = {HTTP_CF_CONNECTING_IP}` 로 단일 client IP 만 설정함.
  12. /// backend 가 직접 받는 peer 는 IIS (127.0.0.1) 라 KnownProxies 에 127.0.0.1 만 두면 충분.
  13. /// </summary>
  14. public static void AddApiForwardedHeaders(this IServiceCollection services, AppSettings settings)
  15. {
  16. services.Configure<ForwardedHeadersOptions>(options =>
  17. {
  18. options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
  19. options.ForwardLimit = settings.ForwardedHeaders.ForwardLimit <= 0 ? 1 : settings.ForwardedHeaders.ForwardLimit;
  20. var knownProxies = settings.ForwardedHeaders.KnownProxies;
  21. if (knownProxies != null)
  22. {
  23. foreach (var proxy in knownProxies)
  24. {
  25. if (IPAddress.TryParse(proxy, out var ip))
  26. {
  27. options.KnownProxies.Add(ip);
  28. }
  29. }
  30. }
  31. var knownNetworks = settings.ForwardedHeaders.KnownNetworks;
  32. if (knownNetworks != null)
  33. {
  34. foreach (var net in knownNetworks)
  35. {
  36. var parts = net.Split('/');
  37. if (parts.Length == 2 && IPAddress.TryParse(parts[0], out var networkIp) && int.TryParse(parts[1], out var prefix))
  38. {
  39. options.KnownIPNetworks.Add(new System.Net.IPNetwork(networkIp, prefix));
  40. }
  41. }
  42. }
  43. });
  44. }
  45. }