Restringir Endpoint .Net en Red Local

En .NET puedes restringir ciertos controladores o endpoints para que solo se consuman desde la red interna (intranet o LAN), mientras que otros sigan siendo accesibles desde Internet.

Hay varias formas de lograrlo según tu escenario, pero te explico las tres más usadas (de más simple a más robusta):


🔹 Opción 1: Validar la IP del cliente en los controladores

Puedes agregar un filtro global o atributo personalizado que valide si la IP del cliente pertenece a la red interna (por ejemplo, 192.168.x.x, 10.x.x.x, 172.16.x.x).

Ejemplo práctico:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Net;

public class InternalOnlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
        if (remoteIp == null)
        {
            context.Result = new StatusCodeResult(StatusCodes.Status403Forbidden);
            return;
        }

        // Rango privado típico: 192.168.0.0/16
        var internalRange = IPNetwork.Parse("192.168.0.0/16");

        if (!internalRange.Contains(remoteIp))
        {
            context.Result = new ContentResult
            {
                StatusCode = StatusCodes.Status403Forbidden,
                Content = "Acceso permitido solo desde la red interna."
            };
        }
    }
}

Luego, lo aplicas a controladores o endpoints específicos:

[ApiController]
[Route("api/[controller]")]
[InternalOnly] // 👈 solo accesible desde red interna
public class AdminInternalController : ControllerBase
{
    [HttpGet("status")]
    public IActionResult GetStatus() => Ok("Servicio interno funcionando");
}

Los demás controladores siguen funcionando normalmente desde Internet.


🔹 Opción 2: Usar un middleware de restricción por IP

Si tienes varios controladores internos, puedes aplicar la validación de IP en el pipeline antes de llegar al controlador.

app.Use(async (context, next) =>
{
    var ip = context.Connection.RemoteIpAddress;

    if (context.Request.Path.StartsWithSegments("/api/internal"))
    {
        var internalNetwork = IPNetwork.Parse("192.168.0.0/16");

        if (!internalNetwork.Contains(ip))
        {
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            await context.Response.WriteAsync("Acceso restringido a red interna");
            return;
        }
    }

    await next.Invoke();
});

Así, cualquier endpoint bajo /api/internal/... queda protegido.


🔹 Opción 3: Controlarlo a nivel de infraestructura (recomendado para producción)

Si tu servicio está detrás de Nginx, Traefik o un Load Balancer, puedes controlar el acceso directamente desde allí:

Ejemplo Nginx:

location /api/internal {
    allow 192.168.0.0/16;   # Red interna
    deny all;               # Denegar el resto
    proxy_pass http://localhost:5000;
}

location /api {
    proxy_pass http://localhost:5000;
}

De este modo, la API ni siquiera recibe peticiones externas a esos endpoints internos.


✅ Recomendación práctica

NivelMétodoCuándo usarlo
App (.NET)Atributo [InternalOnly] o MiddlewareRápido de implementar, útil si no controlas el proxy inverso
Infraestructura (Nginx, Firewall)allow/denyMás seguro y eficiente; ideal en producción
MixtoAmbosSeguridad por capas: app + proxy