PhoenixDDoS
High performance application-layer DDoS protection for Elixir Phoenix.
Table of contents
Usage Installation Configuration
How it works (you defined rules and list, it can put in jail or just block if it reach any threshold)
Features
Monitoring Telemetry events (@see module PhoenixDDoS.Telemetry) Notification to sentry
Local tests DDoS youself using siege (mix phoenix_ddos.attack_myself)
Benchmarks
Community Next in roadmap
Features
protection: ip safelist_ips
protection: ip blocklist_ips
protection: PhoenixDDoS.IpRateLimit
protection: PhoenixDDoS.IpRateLimitPerRequestPath
protection: log flooding
engine: jail system
monitoring: telemetry monitoring: sentry
local tools: ddos youself testing
Usage
phoenix_ddos is a high perContact / Supportformance application-layer DDoS protection for Elixir Phoenix.
Installation
-
Add
:phoenix_ddosto your list of dependencies inmix.exs:
def deps do
[
{:phoenix_ddos, "~> 0.7"},
# Highly recommended, this will makes sure we get the correct remote_ip
{:remote_ip, "~> 1.1"}
]
end-
Add the
PhoenixDDoSplug 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
# ...
endConfiguration
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 | |
| 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 |
Examples with 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 only be throttle to 500 per minute
[{PhoenixDDoS.IpRateLimit, allowed: 500, period: {1, :minute}, jail_time: nil}]
Examples with PhoenixDDoS.IpRateLimitPerRequestPath
single route
[{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 equivalant 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
- ip blocklist/safelist with mask/subnet
- log central to avoid log spam and provide aggregated report
- more performances