View Source PhoenixDDoS (PhoenixDDoS v1.1.2)
phoenix_ddos
is a high performance application-layer DDoS protection for Elixir Phoenix.
Installation
- Add
:phoenix_ddos
to your list of dependencies inmix.exs
:
def deps do
[
{:phoenix_ddos, "~> 1.1"},
# Highly recommended, this will makes sure we get the correct remote_ip
{:remote_ip, "~> 1.1"}
]
end
- Add the
PhoenixDDoS
plug to your app's Endpoint, after the excellent RemoteIp plug (optional but highly recommended !).
defmodule MyApp.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app
# put as high in the order as possible
plug RemoteIp
plug PhoenixDDoS
# ...
end
Configuration
config :phoenix_ddos,
safelist_ips: ["1.2.3.4", "5.6.7.0"],
blocklist_ips: ["11.12.13.0"],
protections: [
# ip rate limit
{PhoenixDDoS.IpRateLimit, allowed: 500, period: {2, :minutes}},
{PhoenixDDoS.IpRateLimit, allowed: 10_000, period: {1, :hour}},
# ip rate limit on specific request_path
{PhoenixDDoS.IpRateLimitPerRequestPath,
request_paths: ["/graphql"], allowed: 20, period: {1, :minute}}
]
Type | Option | Default | Description |
---|---|---|---|
bool | enabled | true | set false to disable |
int | jail_time (minutes) | 15 | time an ip is fully blocked if caught by a protection. set nil to disable thus blocking instead |
bool | raise_on_reject | false | raise when we reject a connexion instead of returning an http code error |
int | http_code_on_reject | 429 | http code returned when we reject a connexion |
list | protections | @see Protections examples | |
list | safelist_ips | bypass all protections ips | |
list | blocklist_ips | always blocked ips | |
bool | on_jail_alert_to_sentry | false | notify slack when an ip get jailed |
The configuration is per node you run, rate_limits are not shared (yet), but it gives you the best performance in case of an attack.
Examples with protection PhoenixDDoS.IpRateLimit
500 per minute max, if triggered ip will be in jail for 15 minutes
[{PhoenixDDoS.IpRateLimit, allowed: 500, period: {1, :minute}}]
disable jail, ip will be throttle to 500 per minute
[{PhoenixDDoS.IpRateLimit, allowed: 500, period: {1, :minute}, jail_time: nil}]
Examples with protection PhoenixDDoS.IpRateLimitPerRequestPath
single route /graphql with a 20 per minute max, if triggered ip will be in jail for 15 minutes
[{PhoenixDDoS.IpRateLimitPerRequestPath, request_paths: ["/graphql"], allowed: 20, period: {1, :minute}}]
you can also give a phoenix-like path
[{PhoenixDDoS.IpRateLimitPerRequestPath, request_paths: ["/admin/:id/dashboard"], allowed: 20, period: {1, :minute}}]
multiple route consumming same quota
[{PhoenixDDoS.IpRateLimitPerRequestPath, request_paths: ["/graphql", "/graphiql"], allowed: 20, shared: true, period: {1, :minute}}]
multiple route consumming independant quota
[{PhoenixDDoS.IpRateLimitPerRequestPath, request_paths: ["/graphql", "/graphiql"], allowed: 20, period: {1, :minute}}]
is equivalent to:
[
{PhoenixDDoS.IpRateLimitPerRequestPath,
request_paths: ["/graphql"], allowed: 20, period: {1, :minute}},
{PhoenixDDoS.IpRateLimitPerRequestPath,
request_paths: ["/graphiql"], allowed: 20, period: {1, :minute}}
]
Community
Slack: join elixir-lang and join channel #phoenix_ddos
Next in roadmap
- [perf] generate blocklist/allow pre-compute list module instead of make an
ip in blocklist
test - [monitoring/config] observe tooling, to be able to observe what volume is normal traffic and craft a configuration accordingly
- [feat] ip blocklist/safelist with mask/subnet
- [feat] log central genserver to avoid log spam and create possibility provide aggregated report
- [feat] out of jail system: an attacker ip would go out of jail and will make some damage again before being put in jail, prevent that
Later in roadmap
- [chore] go away from cachex
- [feat] multi-node
- [path] make a phoenix_ddos_pro with powerful feature for companies ? The oban model might be a good path to take !
Contributing
Create issues on github for any bug or issue.
To contribute on the code, please clone and use following tools:
run tests
mix test
run release code validation
mix ci