Rate limit requests by IP
Summary: Fixes T3923. On `secure.phabricator.com`, we occasionally get slowed to a crawl when someone runs a security scanner against us, or 5 search bots decide to simultaneously index every line of every file in Diffusion. Every time a user makes a request, give their IP address some points. If they get too many points in 5 minutes, start blocking their requests automatically for a while. We give fewer points for logged in requests. We could futher refine this (more points for a 404, more points for a really slow page, etc.) but let's start simply. Also, provide a mechanism for configuring this, and configuring the LB environment stuff at the same time (this comes up rarely, but we don't have a good answer right now). Test Plan: Used `ab` and reloading over and over again to hit rate limits. Read documentation. Reviewers: btrahan Reviewed By: btrahan Subscribers: chad, epriestley Maniphest Tasks: T3923 Differential Revision: https://secure.phabricator.com/D8713
This commit is contained in:
@@ -197,6 +197,9 @@ Continue by:
|
||||
@{article:Configuring Accounts and Registration}; or
|
||||
- understanding advanced configuration topics with
|
||||
@{article:Configuration User Guide: Advanced Configuration}; or
|
||||
- configuring a preamble script to set up the environment properly behind a
|
||||
load balancer, or adjust rate limiting with
|
||||
@{article:Configuring a Preamble Script}; or
|
||||
- configuring where uploaded files and attachments will be stored with
|
||||
@{article:Configuring File Storage}; or
|
||||
- configuring Phabricator so it can send mail with
|
||||
|
||||
114
src/docs/user/configuration/configuring_preamble.diviner
Normal file
114
src/docs/user/configuration/configuring_preamble.diviner
Normal file
@@ -0,0 +1,114 @@
|
||||
@title Configuring a Preamble Script
|
||||
@group config
|
||||
|
||||
Adjust environmental settings (SSL, remote IP, rate limiting) using a preamble
|
||||
script.
|
||||
|
||||
= Overview =
|
||||
|
||||
If Phabricator is deployed in an environment where HTTP headers behave oddly
|
||||
(usually, because it is behind a load balancer), it may not be able to detect
|
||||
some environmental features (like the client's IP, or the presence of SSL)
|
||||
correctly.
|
||||
|
||||
You can use a special preamble script to make arbitrary adjustments to the
|
||||
environment and some parts of Phabricator's configuration in order to fix these
|
||||
problems and set up the environment which Phabricator expects.
|
||||
|
||||
NOTE: This is an advanced feature. Most installs should not need to configure
|
||||
a preamble script.
|
||||
|
||||
= Creating a Preamble Script =
|
||||
|
||||
To create a preamble script, write a file to:
|
||||
|
||||
phabricator/support/preamble.php
|
||||
|
||||
(This file is in Phabricator's `.gitignore`, so you do not need to worry about
|
||||
colliding with `git` or interacting with updates.)
|
||||
|
||||
This file should be a valid PHP script. If you aren't very familiar with PHP,
|
||||
you can check for syntax errors with `php -l`:
|
||||
|
||||
phabricator/ $ php -l support/preamble.php
|
||||
No syntax errors detected in support/preamble.php
|
||||
|
||||
If present, this script will be executed at the very beginning of each web
|
||||
request, allowing you to adjust the environment. For common adjustments and
|
||||
examples, see the next sections.
|
||||
|
||||
= Adjusting Client IPs =
|
||||
|
||||
If your install is behind a load balancer, Phabricator may incorrectly detect
|
||||
all requests as originating from the load balancer, rather than from the correct
|
||||
client IPs. If this is the case and some other header (like `X-Forwarded-For`)
|
||||
is known to be trustworthy, you can overwrite the `REMOTE_ADDR` setting so
|
||||
Phabricator can figure out the client IP correctly:
|
||||
|
||||
```
|
||||
name=Overwrite REMOTE_ADDR with X-Forwarded-For
|
||||
<?php
|
||||
|
||||
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
```
|
||||
|
||||
You should do this //only// if the `X-Forwarded-For` header is always
|
||||
trustworthy. In particular, if users can make requests to the web server
|
||||
directly, they can provide an arbitrary `X-Forwarded-For` header, and thereby
|
||||
spoof an arbitrary client IP.
|
||||
|
||||
= Adjusting SSL =
|
||||
|
||||
If your install is behind an SSL terminating load balancer, Phabricator may
|
||||
detect requests as HTTP when the client sees them as HTTPS. This can cause
|
||||
Phabricator to generate links with the wrong protocol, issue cookies without
|
||||
the SSL-only flag, or reject requests outright.
|
||||
|
||||
To fix this, you can set `$_SERVER['HTTPS']` explicitly:
|
||||
|
||||
```
|
||||
name=Explicitly Configure SSL Availability
|
||||
<?php
|
||||
|
||||
$_SERVER['HTTPS'] = true;
|
||||
```
|
||||
|
||||
You can also set this value to `false` to explicitly tell Phabricator that a
|
||||
request is not an SSL request.
|
||||
|
||||
= Adjusting Rate Limiting =
|
||||
|
||||
Phabricator performs coarse, IP-based rate limiting by default. In most
|
||||
situations the default settings should be reasonable: they are set fairly high,
|
||||
and intended to prevent only significantly abusive behavior.
|
||||
|
||||
However, if legitimate traffic is being rate limited (or you want to make the
|
||||
limits more strict) you can adjust the limits in the preamble script.
|
||||
|
||||
```
|
||||
name=Adjust Rate Limiting Behavior
|
||||
<?php
|
||||
|
||||
// The default is 1000, so a value of 2000 increases the limit by a factor
|
||||
// of 2: users will be able to make twice as many requests before being
|
||||
// rate limited.
|
||||
|
||||
// You can set the limit to 0 to disable rate limiting.
|
||||
|
||||
PhabricatorStartup::setMaximumRate(2000);
|
||||
```
|
||||
|
||||
By examining `$_SERVER['REMOTE_ADDR']` or similar parameters, you could also
|
||||
adjust the rate limit dynamically: for example, remove it for requests from an
|
||||
internal network, but impose a strict limit for external requests.
|
||||
|
||||
Rate limiting needs to be configured in this way in order to make it as cheap as
|
||||
possible to activate after a client is rate limited. The limiting checks execute
|
||||
before any libraries or configuration are loaded, and can emit a response within
|
||||
a few milliseconds.
|
||||
|
||||
= Next Steps =
|
||||
|
||||
Continue by:
|
||||
|
||||
- returning to the @{article:Configuration Guide}.
|
||||
Reference in New Issue
Block a user