PhoenixDDOS
Application-layer DDOS protection for phoenix.
Installation
Add :phoenix_ddos to your list of dependencies in mix.exs:
def deps do
[
{:phoenix_ddos, "~> 0.7"},
# Highly recommended, this will makes sure we get the correct remote_ip in Conn
{:remote_ip, "~> 1.1"}
]
end
Usage
Add the PhoenixDDOS plug to your app's plug pipeline, along with the excellent RemoteIp (optional but highly recommended !).
defmodule MyApp.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app
# ...
plug RemoteIp
plug PhoenixDDOS
# ...
end
Configuration
config :phoenix_ddos,
protections: [
# ip rate limit
{PhoenixDDOS.IpRateLimit, allowed: 500, period: {1, :minute}},
# ip rate limit on specific request_path
{PhoenixDDOS.IpRateLimitPerRequestPath,
request_paths: ["/graphql"], allowed: 20, period: {1, :minute}}
]
| Option | Default | Description |
|---|---|---|
enabled |
true (@compil) | set to false to disable |
jail_time |
15 (@compil) | time an ip is fully blocked if caught by a protection. set nil to disable |
raise_on_reject |
false | raise when we reject a connexion instead of returning an http code error |
http_code_on_reject |
429 | http code returned when we reject a connexion |
protections |
mandatory | @see protections configuration |
Motivation
Add layer of protection within your phoenix application. Multi-layered DDoS protection is the best protection !
you don't always have access to a ddos protection in between internet and your phoenix application You want advance ddos feature you can't have outside an applicative environment
Protections configuration
Ip jail
All protections that trigger a deny of an ip will push said ip into jail.
Jail default duration is 5min, configurable.
You can also configure this time per protection, set jail_time to nil to disable.
Examples 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 PhoenixDDOS.IpRateLimitPerRequestPath
- single route
[{PhoenixDDOS.IpRateLimitPerRequestPath,
request_paths: ["/graphql"], 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}}
]
period syntax example
- period: {30, :second}
- period: {1, :minute}
- period: {2, :minute}
- period: {1, :hour}
- period: {1, :day}