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 Bundle Laravel Package

m6web/firewall-bundle

Symfony bundle that adds a simple IP-based firewall to your app. Define whitelists of allowed addresses per path or host and return a custom response to blocked requests, keeping staging, admin, or private areas locked down with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Treat this as a Symfony bundle, not a Laravel package. There is no service provider, no Laravel middleware, and no Composer auto-discovery for Laravel. A Laravel developer can only borrow the concept or run it inside a Symfony service.
  • v3.0.0 is the current release and it is a major bump — the first in years. The only release note published is a pointer to PR #23, so read that PR and the repo's CHANGELOG/UPGRADE notes before touching an existing install. A major version on a long-quiet bundle almost always means raised PHP/Symfony minimums, renamed or removed config keys, and changed listener wiring.
  • Install only if you are maintaining a Symfony application (2/3/4 on the 2.x line; check whether v3 actually raised the floor before assuming v3 works on your Symfony version): composer require m6web/firewall-bundle. If you are on an older Symfony and cannot migrate, pin explicitly to ^2 rather than floating.
  • Register the bundle the Symfony way (AppKernel::registerBundles() or config/bundles.php on Symfony 4+), then import its configuration under the bundle's root key. The README is the first place to look; the exact config schema is small and lives there. After upgrading to v3, diff your config against the README — do not assume key names survived the major bump.
  • The core idea is straightforward and unchanged: define named rules that combine IP lists/ranges with request path patterns and decide whether to allow or deny. Typical first use case is protecting /admin, staging environments, or a maintenance window by allow-listing office/VPN IPs.
  • For a Laravel codebase, the practical first step is still to reimplement the same behavior as middleware rather than trying to wire the bundle in. A BlockIp / AllowIp middleware reading config/firewall.php gives you the same day-to-day capability with first-class Laravel support — and v3 being a Symfony-facing major release does not change that.

Implementation Patterns

  • Rule-per-concern configuration. Keep separate named rules for admin allow-listing, global deny-listing, and environment-specific exceptions (e.g. allow 127.0.0.1 in dev). Avoid one giant list; it becomes impossible to audit. This also makes a v3 config migration tractable, because you can diff rule by rule.
  • Order matters. IP filtering should run early in the request lifecycle, before authentication and routing-heavy listeners. In Symfony this means a kernel request listener with a high priority; in a Laravel port, a global middleware registered near the top of the stack. Re-verify the listener class name and priority after upgrading to v3 — that is a classic thing to rename in a major.
  • Combine, don’t replace, authorization. Use the firewall for coarse network gating and leave role/permission checks to Symfony’s access_control (or Laravel’s Gate/can middleware). The bundle is not an authentication or authorization system.
  • Environment-scoped config. Put permissive rules in config_dev/.env and strict rules in production. Local development should never be blocked by a production allow-list.
  • Response behavior as configuration. Decide up front whether blocked requests get a 403, a 404 (to avoid leaking that a path exists), or a redirect. Make this consistent across rules and test it. If v3 changed the default denial response, that is a silent behavior change for your users — assert it in a test.
  • CIDR and range support. Prefer CIDR notation for subnets and keep plain IPs for single hosts. Centralize parsing so IPv4 and IPv6 are handled by the same code path.
  • Laravel middleware sketch:
// app/Http/Middleware/Firewall.php
public function handle($request, Closure $next)
{
    $ip = $request->ip();
    foreach (config('firewall.rules', []) as $rule) {
        if (! $this->matchesPath($request, $rule['paths'] ?? [])) {
            continue;
        }
        if ($this->inList($ip, $rule['deny'] ?? [])) {
            abort($rule['status'] ?? 403);
        }
        if (! empty($rule['allow']) && ! $this->inList($ip, $rule['allow'])) {
            abort($rule['status'] ?? 403);
        }
    }
    return $next($request);
}
  • Test with explicit client IPs. Feature tests should set REMOTE_ADDR (and X-Forwarded-For where relevant) and assert status codes for allowed and denied cases. Include at least one IPv6 case. Run this suite before and after any v3 upgrade; it is the cheapest regression net you have for a bundle with thin release notes.
  • Logging as a first-class pattern. Log blocked IPs, matched rule name, and path at warning level. This is the fastest way to diagnose “why can’t I reach staging?” — and the fastest way to prove a post-upgrade rule is or isn’t matching.

Gotchas and Tips

  • Dormant project with a surprise major. The bundle sat at a 2019 release for years and the repo was archived; v3.0.0 means activity resumed (at least for one PR). Do not infer broad maintenance from a single release: check the archive status, open issue count, and whether CI runs against the Symfony versions you actually use. Treat adoption as a deliberate risk with a removal plan.
  • Release notes are a PR link, not notes. There is no migration document in the release itself. Before upgrading, read PR #23 end to end and check for: minimum PHP bump, Symfony version constraint changes, removed/renamed config keys, listener class or service ID changes, and altered default response codes. If any of that is unclear, pin ^2 and stay put.
  • Symfony/Laravel impedance mismatch. There is still no Laravel integration. Don’t expect auto-discovery, facades, or php artisan vendor:publish. Porting the concept is almost always cheaper than bridging the bundle, and a v3 major gives you no additional reason to bridge.
  • Proxy and load balancer IPs. REMOTE_ADDR will be your proxy, not the client. Configure trusted proxies correctly (Symfony TrustedProxies, Laravel TrustProxies middleware) before trusting any forwarded header. Never read X-Forwarded-For blindly — it is spoofable.
  • IPv6 and CIDR edge cases. String comparison on IPs fails for compressed IPv6 and for ranges. Use a proper matcher (e.g. Symfony’s IpUtils::checkIp) rather than in_array. If v3 rewrote matching, re-run your IPv6 tests specifically — that is exactly the code a refactor touches.
  • Listener priority surprises. If another listener short-circuits the request (maintenance mode, auth), your firewall may never run. Verify ordering with the Symfony profiler / event dispatcher debug commands, and re-verify after upgrading.
  • Config cache staleness. After changing firewall rules — or after a v3 upgrade that changes the config tree — clear the config cache (bin/console cache:clear; in Laravel, php artisan config:clear). Stale cached config is a common “my rule isn’t applied” cause, and it is especially likely mid-upgrade when the schema changed underneath you.
  • Response type quirks. Mixing redirects and status codes across rules creates confusing UX and brittle tests. Standardize on one denial response per environment.
  • Extension points are limited. The bundle is small; if you need custom matching logic, expect to fork or write your own listener/middleware. In Laravel, the middleware handle method plus a small CIDR helper is effectively the whole extension surface — keep it in one class and cover it with tests.
  • Debugging checklist: confirm the bundle is registered, confirm config is loaded (debug:config or config('firewall')), confirm the client IP resolution path, then confirm listener/middleware ordering. After a major bump, add a fifth step: confirm your config keys still exist in the v3 schema. Most failures are one of those five.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons