Weave 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

Firewall Laravel Package

m6web/firewall

A Symfony bundle that adds a configurable application-level firewall to PHP apps. Define rules to block malicious requests by IP, user agent, or custom conditions, with logging and ban handling to help protect your application from abuse.

Deep Wiki
Context7

Getting Started

m6web/firewall is a small, framework-agnostic library that maps client IP addresses (single IPs, CIDR blocks, and ranges) to named roles. It is archived and deprecated — the last release was October 2019 — so treat it as a legacy dependency to evaluate, not a default choice. Pin an exact version in composer.json, and do not expect PHP 8.4 or modern security fixes.

Minimal steps:

  1. Install and pin:
    composer require m6web/firewall:^1.0
    
  2. Read the Firewall class first — that is the whole package. The flow is: define IP rules → set the client IP → resolve a role. Everything else is value objects around IP/CIDR parsing.
  3. First use case: distinguish trusted internal traffic from public traffic at the edge of a request.
use M6Web\Component\Firewall\Firewall;

$firewall = new Firewall();
$firewall->setIpRules([
    '10.0.0.0/8'      => 'internal',
    '192.168.1.0/24'  => 'internal',
    '203.0.113.10'    => 'office',
]);
$firewall->setDefaultRole('public');
$firewall->setIp($request->ip());

$role = $firewall->getRole(); // "internal", "office", or "public"

In Laravel there is no service provider, facade, or auto-discovery. You either instantiate it inside a middleware or bind a configured instance in a custom ServiceProvider.

Implementation Patterns

Wrap it in middleware. This is how you use it day-to-day instead of calling it from controllers:

class ResolveIpRole
{
    public function handle(Request $request, Closure $next)
    {
        $firewall = app(Firewall::class);
        $firewall->setIp($request->ip());
        $request->attributes->set('ip_role', $firewall->getRole());

        return $next($request);
    }
}

Bind a configured instance in a provider so rules live in config/firewall.php:

$this->app->singleton(Firewall::class, function () {
    $firewall = new Firewall();
    $firewall->setIpRules(config('firewall.rules', []));
    $firewall->setDefaultRole(config('firewall.default_role', 'public'));
    return $firewall;
});

Keep the config file free of env() calls so config:cache behaves correctly; use plain arrays there and read env values in the config file only.

Gate admin panels by role. Rather than scattering in_array($ip, ...) checks, expose the resolved role to Laravel's authorization layer:

Gate::define('access-admin', fn (User $user) =>
    in_array(request()->attributes->get('ip_role'), ['internal', 'office'], true)
);

Protect operational routes. Apply the middleware to /telescope, /horizon, health endpoints, and feature-flagged routes. This is the package's strongest fit: a declarative allowlist that is easier to audit than inline conditionals.

Combine with auth, not instead of it. IP role is a coarse signal. Use it as an additional condition on top of authentication, never as the sole check for sensitive actions.

Test the role mapping in isolation. The library is pure PHP, so unit-test rule resolution directly without booting Laravel:

$firewall = (new Firewall())->setIpRules(['10.0.0.0/8' => 'internal'])
    ->setDefaultRole('public')
    ->setIp('10.1.2.3');
$this->assertSame('internal', $firewall->getRole());

Include boundary cases: /32, /0, IPv6, and addresses that are one octet outside a CIDR.

Gotchas and Tips

  • Deprecated and archived. No security patches, no PHP 8 compatibility guarantees, and no maintenance. For new work, prefer Symfony\Component\HttpFoundation\IpUtils::checkIp() (already a transitive dependency) or a maintained Laravel package. Audit the source before shipping.
  • Proxy IPs are the classic failure. $request->ip() returns the socket IP unless TrustProxies is configured. Behind a load balancer every client resolves to the balancer. Fix TrustProxies first; do not manually trust X-Forwarded-For, since clients can spoof it.
  • Rule ordering and defaults. Resolution semantics matter: overlapping CIDR blocks and the default role can produce a surprising result. Test overlapping rules explicitly rather than assuming first-match or most-specific-match behavior — verify against the class source.
  • CIDR parsing quirks. IPv4-mapped IPv6 addresses (::ffff:10.0.0.1), IPv6 CIDRs, and leading/trailing whitespace in rules are common sources of silent mismatches. Normalize client IPs and test IPv6 if you enable it.
  • No Laravel integration means no config cache hooks. If you instantiate lazily via a facade or helper, rules can be rebuilt on every request. Bind a singleton or build it once in middleware.
  • Return values are role strings, not booleans. Do not write if ($firewall->getRole()) — the default role is truthy and will make everything pass. Compare against an explicit allowlist.
  • Exception behavior. Invalid rule input may throw rather than ignore. Validate config in a provider boot or via a config test to fail fast at deploy time.
  • Logging and debugging. Log the resolved role and the raw client IP at debug level in non-production. When access is denied unexpectedly, the two suspects are always the proxy configuration and rule overlap.
  • Extension points are thin. You can subclass or wrap the Firewall class if you need custom parsing, but the small surface area means any customization you need (database-backed rules, per-tenant allowlists) is better implemented in your own middleware with the library used only for CIDR matching.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource