mirror of https://github.com/zulip/zulip.git
rate_limit: Add interface to override rate limiting rules.
This commit is contained in:
parent
7c4da60b53
commit
34a0139c2b
|
@ -275,6 +275,46 @@ strength allowed is controlled by two settings in
|
||||||
[smokescreen-setup]: deployment.md#customizing-the-outgoing-http-proxy
|
[smokescreen-setup]: deployment.md#customizing-the-outgoing-http-proxy
|
||||||
[proxy.enable_for_camo]: deployment.md#enable_for_camo
|
[proxy.enable_for_camo]: deployment.md#enable_for_camo
|
||||||
|
|
||||||
|
## Rate limiting
|
||||||
|
|
||||||
|
Zulip has built-in rate limiting of login attempts, all access to the
|
||||||
|
API, as well as certain other types of actions that may be involved in
|
||||||
|
abuse. For example, the email confirmation flow, by its nature, needs
|
||||||
|
to allow sending an email to an email address that isn't associated
|
||||||
|
with an existing Zulip account. Limiting the ability of users to
|
||||||
|
trigger such emails helps prevent bad actors from damaging the spam
|
||||||
|
reputation of a Zulip server by sending confirmation emails to random
|
||||||
|
email addresses.
|
||||||
|
|
||||||
|
The default rate limiting rules for a Zulip server will change as we improve
|
||||||
|
the product. A server administrator can browse the current rules using
|
||||||
|
`/home/zulip/deployments/current/scripts/get-django-setting
|
||||||
|
RATE_LIMITING_RULES`; or with comments by reading
|
||||||
|
`DEFAULT_RATE_LIMITING_RULES` in `zproject/default_settings.py`.
|
||||||
|
|
||||||
|
Server administrators can tweak rate limiting in the following ways in
|
||||||
|
`/etc/zulip/settings.py`:
|
||||||
|
|
||||||
|
- The `RATE_LIMITING` setting can be set to `False` to completely
|
||||||
|
disable all rate-limiting.
|
||||||
|
- The `RATE_LIMITING_RULES` setting can be used to override specific
|
||||||
|
rules. See the comment in the file for more specific details on how
|
||||||
|
to do it. After changing the setting, we recommend using
|
||||||
|
`/home/zulip/deployments/current/scripts/get-django-setting
|
||||||
|
RATE_LIMITING_RULES` to verify your changes. You can then restart
|
||||||
|
the Zulip server with `scripts/restart-server` to have the new
|
||||||
|
configuration take effect.
|
||||||
|
- The `RATE_LIMIT_TOR_TOGETHER` setting can be set to `True` to group all
|
||||||
|
known exit nodes of [TOR](https://www.torproject.org/) together for purposes
|
||||||
|
of IP address limiting. Since traffic from a client using TOR is distributed
|
||||||
|
across its exit nodes, without enabling this setting, TOR can otherwise be
|
||||||
|
used to avoid IP-based rate limiting. The updated list of TOR exit nodes
|
||||||
|
is refetched once an hour.
|
||||||
|
|
||||||
|
See also our [API documentation on rate limiting][rate-limit-api].
|
||||||
|
|
||||||
|
[rate-limit-api]: https://zulip.com/api/rest-error-handling#rate-limit-exceeded
|
||||||
|
|
||||||
## Final notes and security response
|
## Final notes and security response
|
||||||
|
|
||||||
If you find some aspect of Zulip that seems inconsistent with this
|
If you find some aspect of Zulip that seems inconsistent with this
|
||||||
|
|
|
@ -30,6 +30,7 @@ from .configured_settings import (
|
||||||
CUSTOM_HOME_NOT_LOGGED_IN,
|
CUSTOM_HOME_NOT_LOGGED_IN,
|
||||||
DEBUG,
|
DEBUG,
|
||||||
DEBUG_ERROR_REPORTING,
|
DEBUG_ERROR_REPORTING,
|
||||||
|
DEFAULT_RATE_LIMITING_RULES,
|
||||||
EMAIL_BACKEND,
|
EMAIL_BACKEND,
|
||||||
EMAIL_HOST,
|
EMAIL_HOST,
|
||||||
ERROR_REPORTING,
|
ERROR_REPORTING,
|
||||||
|
@ -42,6 +43,7 @@ from .configured_settings import (
|
||||||
LOCAL_UPLOADS_DIR,
|
LOCAL_UPLOADS_DIR,
|
||||||
MEMCACHED_LOCATION,
|
MEMCACHED_LOCATION,
|
||||||
MEMCACHED_USERNAME,
|
MEMCACHED_USERNAME,
|
||||||
|
RATE_LIMITING_RULES,
|
||||||
REALM_HOSTS,
|
REALM_HOSTS,
|
||||||
REGISTER_LINK_DISABLED,
|
REGISTER_LINK_DISABLED,
|
||||||
REMOTE_POSTGRES_HOST,
|
REMOTE_POSTGRES_HOST,
|
||||||
|
@ -358,34 +360,8 @@ CACHES: Dict[str, Dict[str, object]] = {
|
||||||
# REDIS-BASED RATE LIMITING CONFIGURATION
|
# REDIS-BASED RATE LIMITING CONFIGURATION
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
RATE_LIMITING_RULES = {
|
# Merge any local overrides with the default rules.
|
||||||
"api_by_user": [
|
RATE_LIMITING_RULES = {**DEFAULT_RATE_LIMITING_RULES, **RATE_LIMITING_RULES}
|
||||||
(60, 200), # 200 requests max every minute
|
|
||||||
],
|
|
||||||
"api_by_ip": [
|
|
||||||
(60, 100),
|
|
||||||
],
|
|
||||||
"api_by_remote_server": [
|
|
||||||
(60, 1000),
|
|
||||||
],
|
|
||||||
"authenticate_by_username": [
|
|
||||||
(1800, 5), # 5 failed login attempts within 30 minutes
|
|
||||||
],
|
|
||||||
"email_change_by_user": [
|
|
||||||
(3600, 2), # 2 per hour
|
|
||||||
(86400, 5), # 5 per day
|
|
||||||
],
|
|
||||||
"password_reset_form_by_email": [
|
|
||||||
(3600, 2), # 2 reset emails per hour
|
|
||||||
(86400, 5), # 5 per day
|
|
||||||
],
|
|
||||||
"sends_email_by_ip": [
|
|
||||||
(86400, 5),
|
|
||||||
],
|
|
||||||
"spectator_attachment_access_by_file": [
|
|
||||||
(86400, 1000), # 1000 per day per file
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
# List of domains that, when applied to a request in a Tornado process,
|
# List of domains that, when applied to a request in a Tornado process,
|
||||||
# will be handled with the separate in-memory rate limiting backend for Tornado,
|
# will be handled with the separate in-memory rate limiting backend for Tornado,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import os
|
import os
|
||||||
from email.headerregistry import Address
|
from email.headerregistry import Address
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from scripts.lib.zulip_tools import deport
|
from scripts.lib.zulip_tools import deport
|
||||||
from zproject.settings_types import JwtAuthKey, OIDCIdPConfigDict, SAMLIdPConfigDict
|
from zproject.settings_types import JwtAuthKey, OIDCIdPConfigDict, SAMLIdPConfigDict
|
||||||
|
@ -198,6 +198,39 @@ RATE_LIMIT_TOR_TOGETHER = False
|
||||||
SEND_LOGIN_EMAILS = True
|
SEND_LOGIN_EMAILS = True
|
||||||
EMBEDDED_BOTS_ENABLED = False
|
EMBEDDED_BOTS_ENABLED = False
|
||||||
|
|
||||||
|
DEFAULT_RATE_LIMITING_RULES = {
|
||||||
|
"api_by_user": [
|
||||||
|
(60, 200), # 200 requests max every minute
|
||||||
|
],
|
||||||
|
"api_by_ip": [
|
||||||
|
(60, 100),
|
||||||
|
],
|
||||||
|
"api_by_remote_server": [
|
||||||
|
(60, 1000),
|
||||||
|
],
|
||||||
|
"authenticate_by_username": [
|
||||||
|
(1800, 5), # 5 failed login attempts within 30 minutes
|
||||||
|
],
|
||||||
|
"email_change_by_user": [
|
||||||
|
(3600, 2), # 2 per hour
|
||||||
|
(86400, 5), # 5 per day
|
||||||
|
],
|
||||||
|
"password_reset_form_by_email": [
|
||||||
|
(3600, 2), # 2 reset emails per hour
|
||||||
|
(86400, 5), # 5 per day
|
||||||
|
],
|
||||||
|
"sends_email_by_ip": [
|
||||||
|
(86400, 5),
|
||||||
|
],
|
||||||
|
"spectator_attachment_access_by_file": [
|
||||||
|
(86400, 1000), # 1000 per day per file
|
||||||
|
],
|
||||||
|
}
|
||||||
|
# Rate limiting defaults can be individually overridden by adding
|
||||||
|
# entries in this object, which is merged with
|
||||||
|
# DEFAULT_RATE_LIMITING_RULES.
|
||||||
|
RATE_LIMITING_RULES: Dict[str, List[Tuple[int, int]]] = {}
|
||||||
|
|
||||||
# Two factor authentication is not yet implementation-complete
|
# Two factor authentication is not yet implementation-complete
|
||||||
TWO_FACTOR_AUTHENTICATION_ENABLED = False
|
TWO_FACTOR_AUTHENTICATION_ENABLED = False
|
||||||
|
|
||||||
|
|
|
@ -764,6 +764,24 @@ CAMO_URI = "/external_content/"
|
||||||
## Controls whether Zulip will rate-limit user requests.
|
## Controls whether Zulip will rate-limit user requests.
|
||||||
# RATE_LIMITING = True
|
# RATE_LIMITING = True
|
||||||
|
|
||||||
|
## Entries in this dictionary will override Zulip's default rate
|
||||||
|
## limits. Rules which are not explicitly overridden here
|
||||||
|
## will be as default. View the current rules using:
|
||||||
|
## /home/zulip/deployments/current/scripts/get-django-setting RATE_LIMITING_RULES
|
||||||
|
##
|
||||||
|
## The limits are tuples of a number of seconds and a number of
|
||||||
|
## requests allowed over that many seconds. If multiple tuples are
|
||||||
|
## given in a rule, a request breaching any of them will trigger a
|
||||||
|
## rate-limited response to the client. For example, to change the
|
||||||
|
## limits for total API requests by each user to be at most 100
|
||||||
|
## requests per minute, and at most 200 requests per hour, add:
|
||||||
|
## "api_by_user": [(60, 100), (3600, 200)],
|
||||||
|
# RATE_LIMITING_RULES = {
|
||||||
|
# "api_by_ip": [
|
||||||
|
# (60, 100),
|
||||||
|
# ],
|
||||||
|
# }
|
||||||
|
|
||||||
## Fetch TOR exit node list every hour, and group all TOR exit nodes
|
## Fetch TOR exit node list every hour, and group all TOR exit nodes
|
||||||
## together into one bucket when applying rate-limiting.
|
## together into one bucket when applying rate-limiting.
|
||||||
# RATE_LIMIT_TOR_TOGETHER = False
|
# RATE_LIMIT_TOR_TOGETHER = False
|
||||||
|
|
Loading…
Reference in New Issue