Allow disable API rate limit

pull/6908/head
Viktor Baranov 2 years ago
parent 0ab56f5bcc
commit 1742a02453
  1. 1
      .github/workflows/config.yml
  2. 1
      CHANGELOG.md
  3. 44
      apps/block_scout_web/lib/block_scout_web/views/access_helpers.ex
  4. 1
      config/runtime.exs
  5. 1
      docker-compose/envs/common-blockscout.env
  6. 3
      docker/Makefile

@ -579,6 +579,7 @@ jobs:
ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox" ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox"
ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox"
CHAIN_ID: "77" CHAIN_ID: "77"
API_RATE_LIMIT_DISABLED: "true"
ADMIN_PANEL_ENABLED: "true" ADMIN_PANEL_ENABLED: "true"
ACCOUNT_ENABLED: "true" ACCOUNT_ENABLED: "true"
ACCOUNT_REDIS_URL: "redis://localhost:6379" ACCOUNT_REDIS_URL: "redis://localhost:6379"

@ -5,6 +5,7 @@
### Features ### Features
- [#6897](https://github.com/blockscout/blockscout/pull/6897) - Support basic auth in JSON RPC endpoint - [#6897](https://github.com/blockscout/blockscout/pull/6897) - Support basic auth in JSON RPC endpoint
- [#6908](https://github.com/blockscout/blockscout/pull/6908) - Allow disable API rate limit
### Fixes ### Fixes

@ -48,7 +48,7 @@ defmodule BlockScoutWeb.AccessHelpers do
end end
def check_rate_limit(conn) do def check_rate_limit(conn) do
if Mix.env() == :test do if Application.get_env(:block_scout_web, :api_rate_limit)[:disabled] == true do
:ok :ok
else else
global_api_rate_limit = Application.get_env(:block_scout_web, :api_rate_limit)[:global_limit] global_api_rate_limit = Application.get_env(:block_scout_web, :api_rate_limit)[:global_limit]
@ -65,15 +65,15 @@ defmodule BlockScoutWeb.AccessHelpers do
cond do cond do
check_api_key(conn) && get_api_key(conn) == static_api_key -> check_api_key(conn) && get_api_key(conn) == static_api_key ->
rate_limit_by_key(static_api_key, api_rate_limit_by_key) rate_limit_by_param(static_api_key, api_rate_limit_by_key)
check_api_key(conn) && !is_nil(plan) -> check_api_key(conn) && !is_nil(plan) ->
conn conn
|> get_api_key() |> get_api_key()
|> rate_limit_by_key(plan.max_req_per_second) |> rate_limit_by_param(plan.max_req_per_second)
Enum.member?(api_rate_limit_whitelisted_ips(), ip_string) -> Enum.member?(api_rate_limit_whitelisted_ips(), ip_string) ->
rate_limit_by_ip(ip_string, api_rate_limit_by_ip) rate_limit(ip_string, api_rate_limit_by_ip)
true -> true ->
global_rate_limit(global_api_rate_limit) global_rate_limit(global_api_rate_limit)
@ -81,13 +81,9 @@ defmodule BlockScoutWeb.AccessHelpers do
end end
end end
defp check_api_key(conn) do defp check_api_key(conn), do: conn.query_params && Map.has_key?(conn.query_params, "apikey")
conn.query_params && Map.has_key?(conn.query_params, "apikey")
end
defp get_api_key(conn) do defp get_api_key(conn), do: Map.get(conn.query_params, "apikey")
Map.get(conn.query_params, "apikey")
end
defp get_plan(query_params) do defp get_plan(query_params) do
with true <- query_params && Map.has_key?(query_params, "apikey"), with true <- query_params && Map.has_key?(query_params, "apikey"),
@ -101,28 +97,16 @@ defmodule BlockScoutWeb.AccessHelpers do
end end
end end
defp rate_limit_by_key(api_key, api_rate_limit_by_key) do defp rate_limit_by_param(key, value) do
case Hammer.check_rate("api-#{api_key}", 1_000, api_rate_limit_by_key) do rate_limit("api-#{key}", value)
{:allow, _count} ->
:ok
{:deny, _limit} ->
:rate_limit_reached
end
end end
defp rate_limit_by_ip(ip_string, api_rate_limit_by_ip) do defp global_rate_limit(global_api_rate_limit) do
case Hammer.check_rate("api-#{ip_string}", 1_000, api_rate_limit_by_ip) do rate_limit("api", global_api_rate_limit)
{:allow, _count} ->
:ok
{:deny, _limit} ->
:rate_limit_reached
end
end end
defp global_rate_limit(global_api_rate_limit) do defp rate_limit(key, value) do
case Hammer.check_rate("api", 1_000, global_api_rate_limit) do case Hammer.check_rate(key, 1_000, value) do
{:allow, _count} -> {:allow, _count} ->
:ok :ok
@ -131,9 +115,7 @@ defmodule BlockScoutWeb.AccessHelpers do
end end
end end
defp get_restricted_key(%Phoenix.Socket{}) do defp get_restricted_key(%Phoenix.Socket{}), do: nil
nil
end
defp get_restricted_key(conn) do defp get_restricted_key(conn) do
conn_with_params = Conn.fetch_query_params(conn) conn_with_params = Conn.fetch_query_params(conn)

@ -136,6 +136,7 @@ api_rate_limit_by_ip_value =
end end
config :block_scout_web, :api_rate_limit, config :block_scout_web, :api_rate_limit,
disabled: System.get_env("API_RATE_LIMIT_DISABLED", "false") == "true",
global_limit: global_api_rate_limit_value, global_limit: global_api_rate_limit_value,
limit_by_key: api_rate_limit_by_key_value, limit_by_key: api_rate_limit_by_key_value,
limit_by_ip: api_rate_limit_by_ip_value, limit_by_ip: api_rate_limit_by_ip_value,

@ -135,6 +135,7 @@ MAX_STRING_LENGTH_WITHOUT_TRIMMING=2040
RE_CAPTCHA_SECRET_KEY= RE_CAPTCHA_SECRET_KEY=
RE_CAPTCHA_CLIENT_KEY= RE_CAPTCHA_CLIENT_KEY=
JSON_RPC= JSON_RPC=
#API_RATE_LIMIT_DISABLED=true
API_RATE_LIMIT=50 API_RATE_LIMIT=50
API_RATE_LIMIT_BY_KEY=50 API_RATE_LIMIT_BY_KEY=50
API_RATE_LIMIT_BY_IP=50 API_RATE_LIMIT_BY_IP=50

@ -373,6 +373,9 @@ endif
ifdef API_RATE_LIMIT_WHITELISTED_IPS ifdef API_RATE_LIMIT_WHITELISTED_IPS
BLOCKSCOUT_CONTAINER_PARAMS += -e 'API_RATE_LIMIT_WHITELISTED_IPS=$(API_RATE_LIMIT_WHITELISTED_IPS)' BLOCKSCOUT_CONTAINER_PARAMS += -e 'API_RATE_LIMIT_WHITELISTED_IPS=$(API_RATE_LIMIT_WHITELISTED_IPS)'
endif endif
ifdef API_RATE_LIMIT_DISABLED
BLOCKSCOUT_CONTAINER_PARAMS += -e 'API_RATE_LIMIT_DISABLED=$(API_RATE_LIMIT_DISABLED)'
endif
ifdef TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES ifdef TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES
BLOCKSCOUT_CONTAINER_PARAMS += -e 'TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES=$(TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES)' BLOCKSCOUT_CONTAINER_PARAMS += -e 'TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES=$(TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES)'
endif endif

Loading…
Cancel
Save