ArthaTech.IpGuard 1.0.0

dotnet add package ArthaTech.IpGuard --version 1.0.0
                    
NuGet\Install-Package ArthaTech.IpGuard -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ArthaTech.IpGuard" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ArthaTech.IpGuard" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ArthaTech.IpGuard" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ArthaTech.IpGuard --version 1.0.0
                    
#r "nuget: ArthaTech.IpGuard, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ArthaTech.IpGuard@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ArthaTech.IpGuard&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ArthaTech.IpGuard&version=1.0.0
                    
Install as a Cake Tool

ArthaTech.IpGuard

NuGet NuGet Downloads License: MIT .NET

ASP.NET Core middleware and service for IP-based access control using the IPinfo API.

Features at a glance:

  • 🌍 Geo-location lookup (country, city, region, timezone, ASN)
  • 🔒 VPN / Proxy / Tor / Hosting detection (requires IPinfo Privacy addon)
  • 🚫 Configurable restricted country list
  • ✅ IP whitelist
  • ⚡ In-memory caching (configurable TTL)
  • 🛡️ Fail-open design — allows traffic if IPinfo is unreachable
  • 🔌 Works with any ASP.NET Core 6 / 7 / 8 Web API

Installation

dotnet add package ArthaTech.IpGuard

Or via the NuGet Package Manager:

PM> Install-Package ArthaTech.IpGuard

Quick Start

1. Get an IPinfo Token

Sign up at ipinfo.io and copy your API token from the dashboard. Free plan includes 50,000 lookups/month and geo-location data. VPN/Proxy/Tor detection requires the Privacy Detection add-on (paid).


2. Register Services (Program.cs)

Option A — Configuration delegate (code-first):

using IpGuard.Extensions;

builder.Services.AddIpGuard(options =>
{
    options.ApiToken            = "your_ipinfo_token_here";
    options.RestrictedCountries = ["KP", "IR", "CU", "SY"];  // ISO 3166-1 alpha-2
    options.BlockVpn            = true;
    options.BlockProxy          = true;
    options.BlockTor            = true;
});

Option B — From appsettings.json (recommended for production):

builder.Services.AddIpGuard(builder.Configuration);
{
  "IpGuard": {
    "ApiToken": "your_ipinfo_token_here",
    "RestrictedCountries": ["KP", "IR", "CU"],
    "BlockVpn": true,
    "BlockProxy": true,
    "BlockTor": true,
    "BlockHosting": false,
    "WhitelistedIps": ["127.0.0.1", "10.0.0.5"],
    "CacheDurationMinutes": 30,
    "BlockedStatusCode": 403,
    "BlockedMessage": "Access denied from your region or network.",
    "LogBlocked": true,
    "Enabled": true
  }
}

Option B2 — From a custom config section:

builder.Services.AddIpGuard(builder.Configuration.GetSection("Security:IpGuard"));

3. Add Middleware (Program.cs)

app.UseRouting();
app.UseIpGuard();          // ← Place AFTER UseRouting, BEFORE UseAuthentication
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.Run();

That's it. Every request is now checked against your configured rules.


Configuration Reference

Property Type Default Description
ApiToken string "" Required. Your IPinfo API token.
RestrictedCountries List<string> [] ISO 3166-1 alpha-2 codes to block (e.g. ["KP","IR"]).
BlockVpn bool false Block VPN connections. Requires Privacy addon.
BlockProxy bool false Block proxy connections. Requires Privacy addon.
BlockTor bool false Block Tor exit nodes. Requires Privacy addon.
BlockHosting bool false Block datacenter/hosting IPs. Requires Privacy addon.
WhitelistedIps List<string> [] IPs that always bypass all checks.
CacheDurationMinutes int 30 How long to cache each IP result.
BlockedStatusCode int 403 HTTP status code returned when blocked.
BlockedMessage string "Access denied..." Message body when blocked.
Enabled bool true Set false to disable all checks (e.g. local dev).
LogBlocked bool true Log blocked requests at Warning level.
RealIpHeaders List<string> ["CF-Connecting-IP","X-Forwarded-For","X-Real-IP"] Headers to read client IP from (in priority order).
IpInfoBaseUrl string "https://ipinfo.io" Override for enterprise / self-hosted IPinfo.
ApiTimeoutSeconds int 5 Timeout for IPinfo API calls.

Blocked Response Format

When an IP is blocked, the middleware returns:

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8

{
  "error": "Access Denied",
  "message": "Access denied from your region or network.",
  "reason": "Country not permitted: KP",
  "country": "KP",
  "ip": "175.45.176.0"
}

Reading IP Info in Controllers

The middleware attaches the result to HttpContext.Items for use in downstream code:

[ApiController]
[Route("api/[controller]")]
public class OrderController : ControllerBase
{
    [HttpPost]
    public IActionResult CreateOrder([FromBody] OrderRequest req)
    {
        var ipResult = HttpContext.Items["IpGuardResult"] as IpCheckResult;

        if (ipResult != null)
        {
            Console.WriteLine($"Request from: {ipResult.Country} / {ipResult.City}");
            Console.WriteLine($"IsVpn: {ipResult.IsVpn}, IsTor: {ipResult.IsTor}");
            Console.WriteLine($"Org: {ipResult.Org}");
        }

        // ... rest of your logic
        return Ok();
    }
}

IpCheckResult Properties

Property Type Description
IpAddress string The resolved client IP
IsAllowed bool Whether the request passed all checks
BlockReason string? Human-readable reason for blocking (null if allowed)
Country string ISO 3166-1 alpha-2 code (e.g. "US")
City string City name
Region string Region / state
Timezone string? IANA timezone (e.g. "America/New_York")
Org string? ASN + ISP (e.g. "AS15169 Google LLC")
IsVpn bool VPN detected
IsProxy bool Proxy detected
IsTor bool Tor exit node
IsRelay bool iCloud Private Relay or similar
IsHosting bool Datacenter / hosting IP
IsBogon bool Special/reserved IP (loopback, private, etc.)
GeoInfo IpInfoResponse? Raw geo data from IPinfo
PrivacyInfo IpPrivacyResponse? Raw privacy data from IPinfo

Using the Service Directly

For manual lookups outside the middleware (e.g. in a background job or controller action):

[ApiController]
[Route("api/[controller]")]
public class CheckController : ControllerBase
{
    private readonly IIpGuardService _ipGuard;

    public CheckController(IIpGuardService ipGuard) => _ipGuard = ipGuard;

    [HttpGet("ip/{ip}")]
    public async Task<IActionResult> CheckIp(string ip)
    {
        var result = await _ipGuard.CheckIpAsync(ip);
        return Ok(result);
    }

    [HttpGet("geo/{ip}")]
    public async Task<IActionResult> GetGeo(string ip)
    {
        var geo = await _ipGuard.GetGeoInfoAsync(ip);
        return geo == null ? NotFound() : Ok(geo);
    }

    [HttpGet("privacy/{ip}")]
    public async Task<IActionResult> GetPrivacy(string ip)
    {
        var privacy = await _ipGuard.GetPrivacyInfoAsync(ip);
        return privacy == null ? NotFound() : Ok(privacy);
    }

    [HttpDelete("cache/{ip}")]
    public IActionResult ClearCache(string ip)
    {
        _ipGuard.InvalidateCache(ip);
        return NoContent();
    }
}

Reverse Proxy / Cloudflare Setup

If your app runs behind Cloudflare, nginx, or a load balancer, configure the real IP headers:

{
  "IpGuard": {
    "RealIpHeaders": ["CF-Connecting-IP", "X-Forwarded-For", "X-Real-IP"]
  }
}

Important: Only trust these headers from your own proxy. Clients can forge them. Use ASP.NET Core's ForwardedHeaders middleware to validate the proxy chain first.

// Program.cs — Add BEFORE UseIpGuard
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseIpGuard();

Combining with Cloudflare Country Blocking

For maximum security, use Cloudflare WAF (edge layer) + IpGuard (application layer):

Layer Tool Blocks
Edge (CDN) Cloudflare WAF → Firewall Rules → Country High-level country blocks before hitting your server
Application IpGuard VPN/proxy bypass of Cloudflare, fine-grained control

Disabling in Development

// appsettings.Development.json
{
  "IpGuard": {
    "Enabled": false
  }
}

Or with environment-specific configuration:

builder.Services.AddIpGuard(options =>
{
    options.ApiToken = builder.Configuration["IpGuard:ApiToken"]!;
    options.Enabled  = !builder.Environment.IsDevelopment();
    options.RestrictedCountries = ["KP", "IR", "CU"];
    options.BlockVpn = true;
});

IPinfo Plan Comparison

Feature Free Basic Standard Business
Lookups/month 50,000 150,000 500,000 3,000,000
Geo-location
VPN/Proxy/Tor detection
Tor detection

Sign up at ipinfo.io/pricing.


Publishing to NuGet

First time setup

  1. Create a NuGet account at nuget.org
  2. Generate an API key: Account → API Keys → Create

Pack and publish

# Build in Release mode
dotnet build -c Release

# Create the .nupkg
dotnet pack -c Release -o ./nupkg

# Publish to NuGet.org
dotnet nuget push ./nupkg/ArthaTech.IpGuard.1.0.0.nupkg \
  --api-key YOUR_NUGET_API_KEY \
  --source https://api.nuget.org/v3/index.json

Publish to a private feed (Azure Artifacts / GitHub Packages)

# Azure Artifacts
dotnet nuget push ./nupkg/*.nupkg \
  --api-key az \
  --source https://pkgs.dev.azure.com/{org}/{feed}/nuget/v3/index.json

# GitHub Packages
dotnet nuget push ./nupkg/*.nupkg \
  --api-key YOUR_GITHUB_TOKEN \
  --source https://nuget.pkg.github.com/{owner}/index.json

License

MIT © 2025 ArthaTech

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 123 3/9/2026

v1.0.0 — Initial release.
     - IPinfo geo-location API integration
     - VPN, proxy, Tor, and hosting detection (requires IPinfo Privacy addon)
     - Configurable restricted country list (ISO 3166-1 alpha-2)
     - IP whitelist support
     - In-memory result caching with configurable TTL
     - Real IP resolution from X-Forwarded-For / CF-Connecting-IP / X-Real-IP
     - Fail-open design: allows traffic if IPinfo is unreachable
     - IpCheckResult available in HttpContext.Items for downstream use