Disable rate limiter for socket/localhost (unless RemoteIp is enabled)

This commit is contained in:
Maxim Filippov 2019-12-13 19:00:26 +03:00
parent fd697cf209
commit eb11c60289
4 changed files with 67 additions and 7 deletions

View File

@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Deprecated `User.Info` embedded schema (fields moved to `User`) - Deprecated `User.Info` embedded schema (fields moved to `User`)
- Store status data inside Flag activity - Store status data inside Flag activity
- Deprecated (reorganized as `UserRelationship` entity) User fields with user AP IDs (`blocks`, `mutes`, `muted_reblogs`, `muted_notifications`, `subscribers`). - Deprecated (reorganized as `UserRelationship` entity) User fields with user AP IDs (`blocks`, `mutes`, `muted_reblogs`, `muted_notifications`, `subscribers`).
- Rate limiter is now disabled for localhost/socket (unless remoteip plug is enabled)
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>

View File

@ -67,6 +67,8 @@ defmodule Pleroma.Plugs.RateLimiter do
alias Pleroma.Plugs.RateLimiter.LimiterSupervisor alias Pleroma.Plugs.RateLimiter.LimiterSupervisor
alias Pleroma.User alias Pleroma.User
require Logger
def init(opts) do def init(opts) do
limiter_name = Keyword.get(opts, :name) limiter_name = Keyword.get(opts, :name)
@ -89,18 +91,39 @@ def init(opts) do
def call(conn, nil), do: conn def call(conn, nil), do: conn
def call(conn, settings) do def call(conn, settings) do
settings case disabled?() do
|> incorporate_conn_info(conn) true ->
|> check_rate() if Pleroma.Config.get(:env) == :prod,
|> case do do: Logger.warn("Rate limiter is disabled for localhost/socket")
{:ok, _count} ->
conn conn
{:error, _count} -> false ->
render_throttled_error(conn) settings
|> incorporate_conn_info(conn)
|> check_rate()
|> case do
{:ok, _count} ->
conn
{:error, _count} ->
render_throttled_error(conn)
end
end end
end end
def disabled? do
localhost_or_socket =
Pleroma.Config.get([Pleroma.Web.Endpoint, :http, :ip])
|> Tuple.to_list()
|> Enum.join(".")
|> String.match?(~r/^local|^127.0.0.1/)
remote_ip_disabled = not Pleroma.Config.get([Pleroma.Plugs.RemoteIp, :enabled])
localhost_or_socket and remote_ip_disabled
end
def inspect_bucket(conn, name_root, settings) do def inspect_bucket(conn, name_root, settings) do
settings = settings =
settings settings

View File

@ -16,6 +16,7 @@ defmodule Pleroma.Plugs.RateLimiterTest do
test "config is required for plug to work" do test "config is required for plug to work" do
limiter_name = :test_init limiter_name = :test_init
Pleroma.Config.put([:rate_limit, limiter_name], {1, 1}) Pleroma.Config.put([:rate_limit, limiter_name], {1, 1})
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
assert %{limits: {1, 1}, name: :test_init, opts: [name: :test_init]} == assert %{limits: {1, 1}, name: :test_init, opts: [name: :test_init]} ==
RateLimiter.init(name: limiter_name) RateLimiter.init(name: limiter_name)
@ -23,11 +24,39 @@ test "config is required for plug to work" do
assert nil == RateLimiter.init(name: :foo) assert nil == RateLimiter.init(name: :foo)
end end
test "it is disabled for localhost" do
limiter_name = :test_init
Pleroma.Config.put([:rate_limit, limiter_name], {1, 1})
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {127, 0, 0, 1})
Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], false)
assert RateLimiter.disabled?() == true
end
test "it is disabled for socket" do
limiter_name = :test_init
Pleroma.Config.put([:rate_limit, limiter_name], {1, 1})
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {:local, "/path/to/pleroma.sock"})
Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], false)
assert RateLimiter.disabled?() == true
end
test "it is enabled for socket when remote ip is enabled" do
limiter_name = :test_init
Pleroma.Config.put([:rate_limit, limiter_name], {1, 1})
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {:local, "/path/to/pleroma.sock"})
Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], true)
assert RateLimiter.disabled?() == false
end
test "it restricts based on config values" do test "it restricts based on config values" do
limiter_name = :test_opts limiter_name = :test_opts
scale = 80 scale = 80
limit = 5 limit = 5
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
Pleroma.Config.put([:rate_limit, limiter_name], {scale, limit}) Pleroma.Config.put([:rate_limit, limiter_name], {scale, limit})
opts = RateLimiter.init(name: limiter_name) opts = RateLimiter.init(name: limiter_name)
@ -61,6 +90,7 @@ test "`bucket_name` option overrides default bucket name" do
limiter_name = :test_bucket_name limiter_name = :test_bucket_name
Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5}) Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
base_bucket_name = "#{limiter_name}:group1" base_bucket_name = "#{limiter_name}:group1"
opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name) opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name)
@ -75,6 +105,7 @@ test "`bucket_name` option overrides default bucket name" do
test "`params` option allows different queries to be tracked independently" do test "`params` option allows different queries to be tracked independently" do
limiter_name = :test_params limiter_name = :test_params
Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5}) Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
opts = RateLimiter.init(name: limiter_name, params: ["id"]) opts = RateLimiter.init(name: limiter_name, params: ["id"])
@ -90,6 +121,7 @@ test "`params` option allows different queries to be tracked independently" do
test "it supports combination of options modifying bucket name" do test "it supports combination of options modifying bucket name" do
limiter_name = :test_options_combo limiter_name = :test_options_combo
Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5}) Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
base_bucket_name = "#{limiter_name}:group1" base_bucket_name = "#{limiter_name}:group1"
opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name, params: ["id"]) opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name, params: ["id"])
@ -109,6 +141,7 @@ test "it supports combination of options modifying bucket name" do
test "are restricted based on remote IP" do test "are restricted based on remote IP" do
limiter_name = :test_unauthenticated limiter_name = :test_unauthenticated
Pleroma.Config.put([:rate_limit, limiter_name], [{1000, 5}, {1, 10}]) Pleroma.Config.put([:rate_limit, limiter_name], [{1000, 5}, {1, 10}])
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
opts = RateLimiter.init(name: limiter_name) opts = RateLimiter.init(name: limiter_name)
@ -147,6 +180,7 @@ test "can have limits seperate from unauthenticated connections" do
scale = 1000 scale = 1000
limit = 5 limit = 5
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
Pleroma.Config.put([:rate_limit, limiter_name], [{1, 10}, {scale, limit}]) Pleroma.Config.put([:rate_limit, limiter_name], [{1, 10}, {scale, limit}])
opts = RateLimiter.init(name: limiter_name) opts = RateLimiter.init(name: limiter_name)
@ -179,6 +213,7 @@ test "can have limits seperate from unauthenticated connections" do
test "diffrerent users are counted independently" do test "diffrerent users are counted independently" do
limiter_name = :test_authenticated limiter_name = :test_authenticated
Pleroma.Config.put([:rate_limit, limiter_name], [{1, 10}, {1000, 5}]) Pleroma.Config.put([:rate_limit, limiter_name], [{1, 10}, {1000, 5}])
Pleroma.Config.put([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
opts = RateLimiter.init(name: limiter_name) opts = RateLimiter.init(name: limiter_name)

View File

@ -766,6 +766,7 @@ test "returns error when user already registred", %{conn: conn, valid_params: va
end end
test "rate limit", %{conn: conn} do test "rate limit", %{conn: conn} do
Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], true)
app_token = insert(:oauth_token, user: nil) app_token = insert(:oauth_token, user: nil)
conn = conn =