PhoenixDDoS

High performance application-layer DDoS protection for Elixir Phoenix.

Hex DocsCI StatusHex VersionApache 2 License

Table of contents

Features

Usage

phoenix_ddos is a high performance application-layer DDoS protection for Elixir Phoenix.

Installation

  1. Add :phoenix_ddos to your list of dependencies in mix.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
  1. 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, headers: ["x-forwarded-for"]
  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 {15, minutes} 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

  1. 500 per minute max, if triggered ip will be in jail for 15 minutes

    [{PhoenixDDoS.IpRateLimit, allowed: 500, period: {1, :minute}}]
  2. 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

  1. 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}}]
  2. you can also give a phoenix-like path

     [{PhoenixDDoS.IpRateLimitPerRequestPath,
      request_paths: ["/admin/:id/dashboard"], allowed: 20, period: {1, :minute}}]
  3. multiple route consuming same quota

     [{PhoenixDDoS.IpRateLimitPerRequestPath,
      request_paths: ["/graphql", "/graphiql"], allowed: 20, shared: true, period: {1, :minute}}]
  4. multiple route consuming independent 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

Later in roadmap

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