PhoenixDDOS

Application-layer DDOS protection for phoenix.

Hex Docs CI Status Hex Version Apache 2 License

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

  1. 500 per minute max, if triggered ip will be in jail for 15 minutes
[{PhoenixDDOS.IpRateLimit, allowed: 500, period: {1, :minute}}]
  1. disable jail, ip will only be throttle to 500 per minute
[{PhoenixDDOS.IpRateLimit, allowed: 500, period: {1, :minute}, jail_time: nil}]

Examples PhoenixDDOS.IpRateLimitPerRequestPath

  1. single route
[{PhoenixDDOS.IpRateLimitPerRequestPath,
request_paths: ["/graphql"], allowed: 20, period: {1, :minute}}]
  1. multiple route consumming same quota
[{PhoenixDDOS.IpRateLimitPerRequestPath,
request_paths: ["/graphql", "/graphiql"], allowed: 20, shared: true, period: {1, :minute}}]
  1. multiple route consumming independant quota
[{PhoenixDDOS.IpRateLimitPerRequestPath,
request_paths: ["/graphql", "/graphiql"], allowed: 20, period: {1, :minute}}]
  1. 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