ratelimiting.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. # Copyright 2014-2016 OpenMarket Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from typing import Dict
  15. from ._base import Config
  16. class RateLimitConfig:
  17. def __init__(
  18. self,
  19. config: Dict[str, float],
  20. defaults={"per_second": 0.17, "burst_count": 3.0},
  21. ):
  22. self.per_second = config.get("per_second", defaults["per_second"])
  23. self.burst_count = int(config.get("burst_count", defaults["burst_count"]))
  24. class FederationRateLimitConfig:
  25. _items_and_default = {
  26. "window_size": 1000,
  27. "sleep_limit": 10,
  28. "sleep_delay": 500,
  29. "reject_limit": 50,
  30. "concurrent": 3,
  31. }
  32. def __init__(self, **kwargs):
  33. for i in self._items_and_default.keys():
  34. setattr(self, i, kwargs.get(i) or self._items_and_default[i])
  35. class RatelimitConfig(Config):
  36. section = "ratelimiting"
  37. def read_config(self, config, **kwargs):
  38. # Load the new-style messages config if it exists. Otherwise fall back
  39. # to the old method.
  40. if "rc_message" in config:
  41. self.rc_message = RateLimitConfig(
  42. config["rc_message"], defaults={"per_second": 0.2, "burst_count": 10.0}
  43. )
  44. else:
  45. self.rc_message = RateLimitConfig(
  46. {
  47. "per_second": config.get("rc_messages_per_second", 0.2),
  48. "burst_count": config.get("rc_message_burst_count", 10.0),
  49. }
  50. )
  51. # Load the new-style federation config, if it exists. Otherwise, fall
  52. # back to the old method.
  53. if "rc_federation" in config:
  54. self.rc_federation = FederationRateLimitConfig(**config["rc_federation"])
  55. else:
  56. self.rc_federation = FederationRateLimitConfig(
  57. **{
  58. "window_size": config.get("federation_rc_window_size"),
  59. "sleep_limit": config.get("federation_rc_sleep_limit"),
  60. "sleep_delay": config.get("federation_rc_sleep_delay"),
  61. "reject_limit": config.get("federation_rc_reject_limit"),
  62. "concurrent": config.get("federation_rc_concurrent"),
  63. }
  64. )
  65. self.rc_registration = RateLimitConfig(config.get("rc_registration", {}))
  66. rc_login_config = config.get("rc_login", {})
  67. self.rc_login_address = RateLimitConfig(rc_login_config.get("address", {}))
  68. self.rc_login_account = RateLimitConfig(rc_login_config.get("account", {}))
  69. self.rc_login_failed_attempts = RateLimitConfig(
  70. rc_login_config.get("failed_attempts", {})
  71. )
  72. self.federation_rr_transactions_per_room_per_second = config.get(
  73. "federation_rr_transactions_per_room_per_second", 50
  74. )
  75. rc_admin_redaction = config.get("rc_admin_redaction")
  76. self.rc_admin_redaction = None
  77. if rc_admin_redaction:
  78. self.rc_admin_redaction = RateLimitConfig(rc_admin_redaction)
  79. self.rc_joins_local = RateLimitConfig(
  80. config.get("rc_joins", {}).get("local", {}),
  81. defaults={"per_second": 0.1, "burst_count": 3},
  82. )
  83. self.rc_joins_remote = RateLimitConfig(
  84. config.get("rc_joins", {}).get("remote", {}),
  85. defaults={"per_second": 0.01, "burst_count": 3},
  86. )
  87. # Ratelimit cross-user key requests:
  88. # * For local requests this is keyed by the sending device.
  89. # * For requests received over federation this is keyed by the origin.
  90. #
  91. # Note that this isn't exposed in the configuration as it is obscure.
  92. self.rc_key_requests = RateLimitConfig(
  93. config.get("rc_key_requests", {}),
  94. defaults={"per_second": 20, "burst_count": 100},
  95. )
  96. self.rc_3pid_validation = RateLimitConfig(
  97. config.get("rc_3pid_validation") or {},
  98. defaults={"per_second": 0.003, "burst_count": 5},
  99. )
  100. self.rc_invites_per_room = RateLimitConfig(
  101. config.get("rc_invites", {}).get("per_room", {}),
  102. defaults={"per_second": 0.3, "burst_count": 10},
  103. )
  104. self.rc_invites_per_user = RateLimitConfig(
  105. config.get("rc_invites", {}).get("per_user", {}),
  106. defaults={"per_second": 0.003, "burst_count": 5},
  107. )
  108. def generate_config_section(self, **kwargs):
  109. return """\
  110. ## Ratelimiting ##
  111. # Ratelimiting settings for client actions (registration, login, messaging).
  112. #
  113. # Each ratelimiting configuration is made of two parameters:
  114. # - per_second: number of requests a client can send per second.
  115. # - burst_count: number of requests a client can send before being throttled.
  116. #
  117. # Synapse currently uses the following configurations:
  118. # - one for messages that ratelimits sending based on the account the client
  119. # is using
  120. # - one for registration that ratelimits registration requests based on the
  121. # client's IP address.
  122. # - one for login that ratelimits login requests based on the client's IP
  123. # address.
  124. # - one for login that ratelimits login requests based on the account the
  125. # client is attempting to log into.
  126. # - one for login that ratelimits login requests based on the account the
  127. # client is attempting to log into, based on the amount of failed login
  128. # attempts for this account.
  129. # - one for ratelimiting redactions by room admins. If this is not explicitly
  130. # set then it uses the same ratelimiting as per rc_message. This is useful
  131. # to allow room admins to deal with abuse quickly.
  132. # - two for ratelimiting number of rooms a user can join, "local" for when
  133. # users are joining rooms the server is already in (this is cheap) vs
  134. # "remote" for when users are trying to join rooms not on the server (which
  135. # can be more expensive)
  136. # - one for ratelimiting how often a user or IP can attempt to validate a 3PID.
  137. # - two for ratelimiting how often invites can be sent in a room or to a
  138. # specific user.
  139. #
  140. # The defaults are as shown below.
  141. #
  142. #rc_message:
  143. # per_second: 0.2
  144. # burst_count: 10
  145. #
  146. #rc_registration:
  147. # per_second: 0.17
  148. # burst_count: 3
  149. #
  150. #rc_login:
  151. # address:
  152. # per_second: 0.17
  153. # burst_count: 3
  154. # account:
  155. # per_second: 0.17
  156. # burst_count: 3
  157. # failed_attempts:
  158. # per_second: 0.17
  159. # burst_count: 3
  160. #
  161. #rc_admin_redaction:
  162. # per_second: 1
  163. # burst_count: 50
  164. #
  165. #rc_joins:
  166. # local:
  167. # per_second: 0.1
  168. # burst_count: 3
  169. # remote:
  170. # per_second: 0.01
  171. # burst_count: 3
  172. #
  173. #rc_3pid_validation:
  174. # per_second: 0.003
  175. # burst_count: 5
  176. #
  177. #rc_invites:
  178. # per_room:
  179. # per_second: 0.3
  180. # burst_count: 10
  181. # per_user:
  182. # per_second: 0.003
  183. # burst_count: 5
  184. # Ratelimiting settings for incoming federation
  185. #
  186. # The rc_federation configuration is made up of the following settings:
  187. # - window_size: window size in milliseconds
  188. # - sleep_limit: number of federation requests from a single server in
  189. # a window before the server will delay processing the request.
  190. # - sleep_delay: duration in milliseconds to delay processing events
  191. # from remote servers by if they go over the sleep limit.
  192. # - reject_limit: maximum number of concurrent federation requests
  193. # allowed from a single server
  194. # - concurrent: number of federation requests to concurrently process
  195. # from a single server
  196. #
  197. # The defaults are as shown below.
  198. #
  199. #rc_federation:
  200. # window_size: 1000
  201. # sleep_limit: 10
  202. # sleep_delay: 500
  203. # reject_limit: 50
  204. # concurrent: 3
  205. # Target outgoing federation transaction frequency for sending read-receipts,
  206. # per-room.
  207. #
  208. # If we end up trying to send out more read-receipts, they will get buffered up
  209. # into fewer transactions.
  210. #
  211. #federation_rr_transactions_per_room_per_second: 50
  212. """