Problem/Motivation

Rewrite IP allowlist using a settings.php setting (ban.allowlist) service instead of the current 1.1.x-dev approach using config, which degrades performance too much in middleware. See #3578480: Worth caching allowed IP list in middleware? for details.

Also note @berdir's comment:

I'm fine with something settings or container parameter based.

Unsure when it should apply, on check or on ban, or or both. *If* the cost of checking the IP is near-zero (like settings.php), then there's even a performance improvement possible thanks to this, as the query doesn't need to run (as a follow-ip, it might be worth exploring to make either the ban ip manager in the middleware or the database connection in the ban ip manager a closure. Unfortunately, Drupal already opens the database connection when you inject the service and with this, there's a scenario where no query happens)

And yes, once such a setting exists, other modules could support it and don't block those IP's in the first place.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Issue fork ban-3582177

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

anybody created an issue. See original summary.

anybody’s picture

anybody’s picture

Issue summary: View changes
berdir’s picture

Just to give a practical example why performance of the ban middleware matters, specifically also on blocked responses:

A few days ago, for two hours, one of our websites registered a 10x increase in requests, 90% of those were from IP's that perimeter automatically blocked, so they were all ~10ms responses. About 50% of the requests of the whole day, enough that the median response time for the whole day dropped to 11ms. This barely registered on the server resource usage because ban responses are so fast compared to regular responses, and it's important that it remains this way.

This was still on D10, but if you look at the page cache response comparison on https://www.md-systems.ch/en/blog/2025-12-16/performance-improvements-dr... (ban is similar), but on 11.2, this would have resulted in twice as much CPU being used (which is still much faster than if they would not have been blocked).

anybody’s picture

Thanks for the enlightening insights @berdir! I totally agree and we'll probably implement this today :)

grevil made their first commit to this issue’s fork.

grevil’s picture

Assigned: grevil » Unassigned
Status: Active » Needs review

All done, please review!

One more thing @berdir, @anybody thought about using a simple ban service, which wraps around the "Settings::get('ban_allowlist', []);", so other modules can simply use this service instead off relying on "Settings::get('ban_allowlist', []);" directly. Do you think that'd make sense? It would be again another (although really lighweight) service which needs to be injected in the Middleware.

anybody’s picture

Thanks @grevil! Nice! I left a bunch of comments. Would be great if @berdir could also check if anything else needs to be addressed or sign this off before merge.

berdir’s picture

> Do you think that'd make sense? It would be again another (although really lighweight) service which needs to be injected in the Middleware.

I think the overhead of one extra class/service with no dependencies is minimal. Someone could implement a more complex/dynamic allowlist-provider then if they're willing to live with the possibly slower performance.

It would make BC more complicated though, you'd then switch the passed argument with something else, would need to be optional and without type. Also makes further changes a bit more complicated. Right now only the drush ban commands seems to respect the allow list and not the UI, that seems pretty inconsistent, this might make more sense within the BanIpManger? With a setting, you can just move the code, with DI, you again need to remove and add the service in a different place. Your call if that is worth it.

grevil’s picture

Alright, all done!

anybody’s picture

Title: Rewrite IP allowlist using a settings.php setting (ban.allowlist) service » Rewrite IP allowlist using a settings.php setting
Related issues: +#3582759: Add a ban.allowlist service

I created #3582759: Add a ban.allowlist service as follow-up to be done whenever someone needs it. YAGNI until then ;)

Will review this finally now and merge it then for a beta2 release today, if @berdir is fine with that.

anybody’s picture

Status: Needs review » Needs work

Left two final comments. RTBC once fixed.

https://www.drupal.org/docs/8/understanding-drupal-version-numbers/what-... says:

Beta: ... and if absolutely necessary, the API or database schema could change (to fix a critical bug)

so I think the parameter removal is acceptable this way with ~20 installations. Next time we should leave breaking changes in alpha for longer in such a widely used module.

anybody’s picture

Status: Needs work » Reviewed & tested by the community

Finally added some more IPv6 tests and mixed tests, if they go green we can merge this finally and should be really well covered :)

grevil’s picture

Status: Reviewed & tested by the community » Fixed

Fixed the phpcs issues and made the pipeline failure a bit more strict. Merging!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • grevil committed e47696f5 on 1.1.x
    feat: #3582177 Rewrite IP allowlist using a settings.php setting (ban....
anybody’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.