@PJUllrich and I have built our first Pro library, Phx2Ban! Phx2Ban is a web application firewall that you can install in your Phoenix applications in less time than it takes to brew a cup of . If you don’t believe me watch Peter install Phx2Ban in a Phoenix application with just a few minutes:
Phx2Ban can be used as an alternative to web application firewalls such as fail2ban without having to install anything on your host or add anything to your container given that it is an Elixir library. Since it lives within your application, Phx2Ban also comes with a Phoenix LiveDashboard plugin where you can see metrics collected by Phx2Ban as well as manage the block list (in case you need to unblock an IP address):
This built in dashboard will allow you to see how many unique IP addresses have accessed your service, how many requests were blocked and how many valid requests were allowed to proceed. Here is a snapshot of the firewall at work when my business was getting hit with bot requests in the middle of the night:
We have a lot of additional features planned for this Pro library and we will be rolling those out in the weeks to come! Since this is in early launch, Phx2Ban will be available for a one time fee of $99 (discounted by $50 while we are still in the active development phase).
Peter an I appreciate the support and we look forward to building additional Pro libraries tailored to bootstrapped business owners!
Is the requests data and blocked IPs stored somewhere, or just in memory? I’m asking because I use Heroku and they reset the dynos daily, will the blocked IPs be wiped out in this case?
From my side I would say that banning by IP is a little too “old school” do you provide more advanced options for banning? For example I don’t have a public IP from my residential ISP (they bunch up clients from the same zone to cut costs), so it would be very unfortunate to ban a bunch of users.
At the moment the block list only lives in memory, but that is definitely on the roadmap! We’re working on a couple of other features at the moment (namely support for stateful rules and the ability to download and use crowd sourced block lists of known malicious IPs). Our plan is to use Postgres both for persisting blocklist state and for replicating the blocklist across nodes when native clustering is not an option. In other words…coming soon!
Good question! As of right now we don’t have any way to distinguish one user from another if the requests are coming from the same IP address. Perhaps in the future we could provide a blocklist hook that would allow some requests to pass through even if the IP is on the block list. Something like the following scenario: An IP address is blocked for an apartment complex, but users with valid session cookies will still be allowed to proceed while everyone else is blocked for the duration of the blocklist timeout.
Unfortunately, as soon as you start securing your application this is an inescapable reality:
That being said, we think we have struck a good balance with Phx2Ban given that @PJUllrich and I both use it in our SaaS businesses that we run with positive results.
This is awesome! This is basically what I need right now, except I need to have some centralized Redis / Postgres store. I am using Hammer with the Redis backend at the moment for this and it has already blocked the Google Kubernetes Routers on two occasions
Does it also have things like partial degratation? Like setting a “fishy” flag in the conn, so you can show things like captchas?
Happy to hear that our roadmap is on the right track to supporting your day to day needs!
As for dealing with partial degradation, we don’t expose that data at the moment, but I’ll add that to our todo list as it is a single lookup in ETS and would definitely support the use case for having special logic when you suspect something is fishy.
This is more or less how Wikipedia handles their abuse filter. Of course, it’s easier for them, because they know how their authentication works. In case of a library, it’s often not so obvious. Basically you’ll need an ability to tell Phx2Ban how to check that a user is authenticated.
@PJUllrich and I have been fairly busy with Phx2Ban since its initial release and we’ve gone though and added a bunch of features that were requested by users!
The biggest announcement in these last couple releases is the ability to pull down a serialized Cuckoo filter from ezsuite.dev that has IP addresses from the public block list https://www.abuseipdb.com/.
We have some other very cool features in the works so stay tuned!
Here is the full changelog from the last two releases with the latest version being 0.2.1:
[0.2.1] - 2024-11-29
Fixed
Fixes a FunctionClauseError in the KnownMaliciousIP rule when an IPv6 address was checked.
Bumped the dependency phoenix_live_dashboard to at least 0.8.0 because versions below that were missing some functions we use in the LiveDashboardPlugin and that lead to compilation errors. (See #2)
[0.2.0] - 2024-11-28
Added
New Rule KnownMaliciousIP. Fetches a public blocklist of ~85k known malicious IPs tracked by AbuseIPDB from ezsuite.dev and blocks requests originating from these IPs.
Phx2Ban.manually_block_ip_address/1 function will manually add an IP address to the block list…
Phx2Ban.ip_address_status/1 function will return the current status of an IP address.
Config option allow_list. Accepts a list of IP addresses as strings so that you can avoid analyzing/blocking traffic from certain trusted IP addresses.
Config option enabled for enabling/disabling the firewall. Can be triggered through the LiveDashboard plugin or manually through Phx2Ban.FirewallConfig.put!(:enabled, true|false).
Config option ignore_routes. Accepts a list of routes as string or regex that Phx2ban should ignore. Any requests to these routes are excluded from analysis and will never get blocked.