Skip to content
Shiny.Net.HttpServer v1 - A lightweight feature rich HTTP Server - Tunnels, Websockets, AOT, ASPNET Featureset, & Works EVERYWHERE!Let me see!

IP Filtering

app.UseIpFilter(p => p.AllowLoopback().AllowPrivateNetworks());

That is the shape most device servers want: reachable from the LAN, not from anywhere else.

For named policies applied per endpoint:

builder.Services.AddIpFilter(o =>
{
o.AddPolicy("admin", p => p.AllowLoopback());
// No DefaultPolicy here — setting one applies to every request, including the 404s.
});
var app = builder.Build();
app.UseIpFilter();
app.OnGet("/admin/keys", ctx => …).RequireIpFilter("admin");
app.OnGet("/ping", ctx => …).AllowAnyIp();

On generated endpoints, [RequireIpFilter("admin")] and [AllowAnyIp] do the same as compile-time metadata.

Method Effect
Allow(params string[] ranges) CIDR ranges, or bare addresses
Deny(params string[] ranges)
AllowLoopback() 127.0.0.0/8 and ::1
AllowPrivateNetworks() The RFC 1918 ranges, link-local, and unique-local IPv6
AllowUnknownAddress(bool) Whether a request whose remote address is unknown passes
o.AddPolicy("partner", p => p
.Allow("203.0.113.0/24", "198.51.100.7")
.Deny("203.0.113.66")
);

The rules:

  • Deny beats allow, including a wider allow.
  • One allow entry turns a blacklist into a whitelist. A policy with any Allow in it refuses everything not listed.
  • An unknown remote address fails closed unless AllowUnknownAddress() says otherwise.

IpAddressRange masks host bits itself, so 10.0.0.5/8 is accepted and means 10.0.0.0/8 — rather than being rejected the way System.Net.IPNetwork does. IPv4-mapped IPv6 addresses are unmapped on both sides, so a dual-stack listener does not silently break every IPv4 rule.

Option Default
RejectionStatusCode 403
OnRejected null
o.OnRejected = (ctx, address) =>
{
logger.LogWarning("Blocked {Address}", address);
return ValueTask.CompletedTask;
};

UseIpFilter() is ordinary middleware and belongs early. A whitelist that only covered mapped routes would answer the whole internet’s 404s. Per-endpoint policies still work, because the middleware asks the router which endpoint the request would reach.