Giter VIP home page Giter VIP logo

phoenix_ddos's Introduction

PhoenixDDoS

High performance application-layer DDoS protection for Elixir Phoenix.

Hex Docs CI Status Hex Version Apache 2 License

Table of contents


Note You are currently on unreleased branch. Latest stable release documentation is here


Features

  • protection: ip safelist_ips - List of ip that bypass all checks
  • protection: ip blocklist_ips - List of ip that are always rejected
  • protection: PhoenixDDoS.IpRateLimit - rate limit per ip
  • protection: PhoenixDDoS.IpRateLimitPerRequestPath - rate limit per ip per path
  • protection: log flooding - in case of an attack, prevent application log to explode
  • engine: jail system - auto-blocklist ips that triggered a protection for a limited amount of time
  • monitoring: telemetry - provide events to your application from phoenix_ddos decisions
  • monitoring: sentry - if you use sentry, you can be notified when an ip has been put in jail
  • local tools: ddos youself - because it is fun !

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}},
    {PhoenixDDoS.IpRateLimitPerRequestPath,
     request_paths: [{:post, "/login"}], allowed: 5, period: {30, :seconds}}
  ]
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}}]
  1. 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}}]
  1. you can also give a phoenix-like path
    [{PhoenixDDoS.IpRateLimitPerRequestPath,
     request_paths: ["/admin/:id/dashboard"], allowed: 20, period: {1, :minute}}]
  1. you can also specify method
    [
      {PhoenixDDoS.IpRateLimitPerRequestPath,
     request_paths: [{:post, "/login"}, {:post, "/logout"}], allowed: 5, period: {1, :minute}},
      {PhoenixDDoS.IpRateLimitPerRequestPath,
     request_paths: [{:get, "/login"}], allowed: 100, period: {5, :minute}}
    ]
  1. multiple route consuming same quota
    [{PhoenixDDoS.IpRateLimitPerRequestPath,
     request_paths: ["/graphql", "/graphiql"], allowed: 20, shared: true, period: {1, :minute}}]
  1. 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

FAQ

Why would I need this compared to a system like cloudflare or a reverse proxy with a fail2ban ?

The best ddos protection is like any protection: you have to have multiple layers of protection, each layer having its own advantage or disadvantage. In that matter, to maximize protection you should use one system per layer.

Also we have to keep in mind that a lot of projects don't have the capability (running in a PaaS like heroku for instance) or the will to have all these systems in place. Since phoenix_ddos is a plug-and-play (pun intended) library with minimum configuration, it is a great value for a minimum of effort.

What is a multi-layer ddos protection and why this is important ?

phoenix_ddos is the application layer, running in the application itself. It advantage is that is knows the inside of the application and its limits and can act on the details, where a cloudflare or a ngnix fail2ban would manage most of the load, but the traffic that still access your application may still kill it, this is then the responsability of phoenix_ddos.

Example of a phoenix application cluster: e.g. 10 pods running each the same phoenix application:

Other layers will protect the entire cluster and phoenix_ddos will protect each phoenix application individually.

Since one phoenix application have its own limits, it is best to have a throttle at this layer.

If the cluster scale up or down (switching to 3 pods or 30 pods), other layers will never adapt their throttle values, but phoenix_ddos will scale its protection gracefully.

Comparaison with an home electrical installation:

In home installation, you have 2 layers of protection doing the exact same thing:

  • one differential switch protecting the house globally, with a small sensitivity, this will protect the house from burning if a bad short circuit happen
  • several differential switches in the electric switchboard, with high sensitivity, this will protect people from being badly injured in case of a shock. We can note that those switches are application specialized because they are chosen according to the load they have to protect, something the other layer can't manage since it has no idea of the house usage in detail.

Next in roadmap

  • [monitoring] 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

  • [feat] multi-node
  • [path] make a phoenix_ddos_pro with powerful features 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

phoenix_ddos's People

Contributors

m1ck431 avatar xward avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

egida arthurmmn

phoenix_ddos's Issues

List IPs currently in the jail?

Hi,

Thanks a lot for publishing this software as an open source package! We use it on transport.data.gouv.fr.

In etalab/transport-site#3659 we wanted to list IP addresses currently jailed. There isn't a method available to do this at the moment so we called internal APIs.

def ips_in_jail do
  # See https://github.com/xward/phoenix_ddos/blob/master/lib/phoenix_ddos/core/jail.ex
  {:ok, keys} = Cachex.keys(:phoenix_ddos_jail)
  keys |> Enum.map(&to_string/1) |> Enum.reject(&String.starts_with?(&1, "suspicious_"))
end

What do you think about adding this method? And how I did it? I can submit a PR.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.