Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Firewall Laravel Package

pratik-dabhi/laravel-firewall

Laravel firewall middleware for blocking abusive traffic by IP rules such as allow/deny lists and access restrictions. Helps protect routes and applications from unwanted requests with simple configuration and integration into a Laravel app.

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation

    composer require pratik-dabhi/laravel-firewall
    php artisan vendor:publish --provider="PratikDabhi\Firewall\FirewallServiceProvider" --tag="config"
    
    • Publishes the default config (config/firewall.php) with sensible defaults.
  2. Basic Configuration Edit config/firewall.php to define:

    • IP Rules: Allow/block specific IPs or CIDR ranges.
      'rules' => [
          'allow' => ['192.168.1.1', '10.0.0.0/8'],
          'deny' => ['1.2.3.4', '172.16.0.0/12'],
      ],
      
    • GeoIP Blocking: Enable via geoip.enabled = true and configure MaxMind DB paths.
    • Rate Limiting: Define rules under rate_limits (e.g., max_attempts: 100, decay_minutes: 1).
  3. First Use Case: Block an IP

    use PratikDabhi\Firewall\Facades\Firewall;
    
    // Block a single IP
    Firewall::deny('1.2.3.4');
    
    // Check if an IP is allowed
    if (Firewall::isAllowed(request()->ip())) {
        // Proceed
    } else {
        abort(403, 'Access denied.');
    }
    

Implementation Patterns

Core Workflows

  1. Middleware Integration Use the provided middleware to auto-block requests:

    // In Kernel.php
    protected $middleware = [
        \PratikDabhi\Firewall\Middleware\Firewall::class,
    ];
    
    • Automatically checks IP/CIDR/GeoIP rules and rate limits on every request.
  2. Dynamic Rule Management

    • Runtime Updates: Modify rules dynamically (e.g., via admin panel):
      Firewall::allow('192.168.1.100'); // Whitelist an IP
      Firewall::denyCidr('172.16.0.0/16'); // Block a subnet
      
    • Cache Rules: Enable cache_rules = true in config to avoid reloading rules on every request.
  3. GeoIP Blocking

    • Requires MaxMind GeoLite2 database (download from MaxMind).
    • Configure paths in config/firewall.php:
      'geoip' => [
          'enabled' => true,
          'database_path' => database_path('GeoLite2-Country.mmdb'),
          'blocked_countries' => ['RU', 'CN'], // ISO country codes
      ],
      
    • Note: GeoIP checks are not cached by default for accuracy.
  4. Rate Limiting

    • Define rules in config/firewall.php:
      'rate_limits' => [
          'api' => [
              'max_attempts' => 60,
              'decay_minutes' => 1,
          ],
          'admin' => [
              'max_attempts' => 10,
              'decay_minutes' => 5,
          ],
      ],
      
    • Apply to routes/middleware:
      Route::middleware(['firewall.rate_limit:api'])->group(function () {
          // Rate-limited routes
      });
      
  5. Attack Logging

    • Log blocked attempts to storage/logs/firewall.log (enabled by default).
    • Customize log format in config:
      'logging' => [
          'enabled' => true,
          'log_blocked_attempts' => true,
          'log_allowed_attempts' => false,
      ],
      

Integration Tips

  • Laravel Scout: Combine with Scout for IP-based search filtering.
  • Laravel Horizon: Monitor blocked IPs in real-time via Horizon jobs.
  • API Gateways: Use the package in a gateway (e.g., Laravel Octane) to offload firewall logic.
  • Cloudflare/IPv6: Ensure CIDR rules account for IPv6 (e.g., 2001:db8::/32).

Gotchas and Tips

Pitfalls

  1. GeoIP Database Updates

    • MaxMind databases expire. Set up a cron job to update them:
      # Example: Download and replace the DB monthly
      wget -O database_path/GeoLite2-Country.mmdb https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key=YOUR_KEY&suffix=tar.gz
      tar -xzf GeoLite2-Country.tar.gz -C database_path
      
    • Tip: Use spatie/laravel-geoip for easier GeoIP management if needed.
  2. Rate Limiting Scope

    • Rate limits are IP-based by default. For user-specific limits, extend the package:
      // Override the rate limiter in a service provider
      Firewall::extend('user_rate_limit', function ($request) {
          return RateLimiter::for('user_' . $request->user()->id)->...
      });
      
  3. CIDR Parsing Errors

    • Invalid CIDR ranges (e.g., 192.168.1) will throw exceptions. Validate inputs:
      use PratikDabhi\Firewall\Support\Cidr;
      
      if (!Cidr::isValid('192.168.1')) {
          throw new \InvalidArgumentException('Invalid CIDR');
      }
      
  4. Performance with Large Rule Sets

    • Disable caching (cache_rules = false) if rules change frequently.
    • For high-traffic apps, consider pre-compiling rules into a serialized format.
  5. IP Spoofing

    • The package trusts request()->ip(). For proxied environments (e.g., Cloudflare), use:
      $ip = request()->ip() ?? request()->header('CF-Connecting-IP');
      
  6. Logging Overhead

    • Disabling logs (log_blocked_attempts = false) reduces I/O but loses audit trails.

Debugging

  1. Check Firewall Status

    // Dump rules for debugging
    dd(Firewall::getRules());
    
    // Check if an IP is blocked
    dd(Firewall::isAllowed('1.2.3.4')); // Returns bool
    
  2. Rate Limit Debugging

    • Inspect attempts:
      $attempts = Firewall::getRateLimitAttempts('api', request()->ip());
      dd($attempts);
      
  3. GeoIP Debugging

    • Test country detection:
      use PratikDabhi\Firewall\Facades\GeoIp;
      
      dd(GeoIp::getCountryCode('8.8.8.8')); // Should return 'US'
      

Extension Points

  1. Custom Rule Providers

    • Implement PratikDabhi\Firewall\Contracts\RuleProvider to fetch rules from a database:
      class DatabaseRuleProvider implements RuleProvider {
          public function getAllowRules() { ... }
          public function getDenyRules() { ... }
      }
      
    • Bind in a service provider:
      Firewall::setRuleProvider(new DatabaseRuleProvider());
      
  2. Custom Rate Limit Strategies

    • Extend the rate limiter:
      Firewall::extend('sliding_window', function () {
          return new SlidingWindowLimiter();
      });
      
  3. Event Listeners

    • Listen for blocked/allowed events:
      Firewall::blocked(function ($request, $reason) {
          // Log or notify admins
      });
      
  4. HTTP Responses

    • Customize block responses:
      Firewall::setBlockResponse(function ($request, $reason) {
          return response()->json(['error' => 'Blocked'], 403);
      });
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor