Skip to content

Commit 4d0935b

Browse files
author
epriestley
committedApr 9, 2014
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
1 parent 597c6c0 commit 4d0935b

File tree

5 files changed

+398
-1
lines changed

5 files changed

+398
-1
lines changed
 

‎.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
# User-accessible hook for adhoc debugging scripts
3434
/support/debug.php
3535

36+
# User-accessible hook for adhoc startup code
37+
/support/preamble.php
38+
3639
# Users can link binaries here
3740
/support/bin/*
3841

‎src/docs/user/configuration/configuration_guide.diviner

+3
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ Continue by:
197197
@{article:Configuring Accounts and Registration}; or
198198
- understanding advanced configuration topics with
199199
@{article:Configuration User Guide: Advanced Configuration}; or
200+
- configuring a preamble script to set up the environment properly behind a
201+
load balancer, or adjust rate limiting with
202+
@{article:Configuring a Preamble Script}; or
200203
- configuring where uploaded files and attachments will be stored with
201204
@{article:Configuring File Storage}; or
202205
- configuring Phabricator so it can send mail with
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
@title Configuring a Preamble Script
2+
@group config
3+
4+
Adjust environmental settings (SSL, remote IP, rate limiting) using a preamble
5+
script.
6+
7+
= Overview =
8+
9+
If Phabricator is deployed in an environment where HTTP headers behave oddly
10+
(usually, because it is behind a load balancer), it may not be able to detect
11+
some environmental features (like the client's IP, or the presence of SSL)
12+
correctly.
13+
14+
You can use a special preamble script to make arbitrary adjustments to the
15+
environment and some parts of Phabricator's configuration in order to fix these
16+
problems and set up the environment which Phabricator expects.
17+
18+
NOTE: This is an advanced feature. Most installs should not need to configure
19+
a preamble script.
20+
21+
= Creating a Preamble Script =
22+
23+
To create a preamble script, write a file to:
24+
25+
phabricator/support/preamble.php
26+
27+
(This file is in Phabricator's `.gitignore`, so you do not need to worry about
28+
colliding with `git` or interacting with updates.)
29+
30+
This file should be a valid PHP script. If you aren't very familiar with PHP,
31+
you can check for syntax errors with `php -l`:
32+
33+
phabricator/ $ php -l support/preamble.php
34+
No syntax errors detected in support/preamble.php
35+
36+
If present, this script will be executed at the very beginning of each web
37+
request, allowing you to adjust the environment. For common adjustments and
38+
examples, see the next sections.
39+
40+
= Adjusting Client IPs =
41+
42+
If your install is behind a load balancer, Phabricator may incorrectly detect
43+
all requests as originating from the load balancer, rather than from the correct
44+
client IPs. If this is the case and some other header (like `X-Forwarded-For`)
45+
is known to be trustworthy, you can overwrite the `REMOTE_ADDR` setting so
46+
Phabricator can figure out the client IP correctly:
47+
48+
```
49+
name=Overwrite REMOTE_ADDR with X-Forwarded-For
50+
<?php
51+
52+
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
53+
```
54+
55+
You should do this //only// if the `X-Forwarded-For` header is always
56+
trustworthy. In particular, if users can make requests to the web server
57+
directly, they can provide an arbitrary `X-Forwarded-For` header, and thereby
58+
spoof an arbitrary client IP.
59+
60+
= Adjusting SSL =
61+
62+
If your install is behind an SSL terminating load balancer, Phabricator may
63+
detect requests as HTTP when the client sees them as HTTPS. This can cause
64+
Phabricator to generate links with the wrong protocol, issue cookies without
65+
the SSL-only flag, or reject requests outright.
66+
67+
To fix this, you can set `$_SERVER['HTTPS']` explicitly:
68+
69+
```
70+
name=Explicitly Configure SSL Availability
71+
<?php
72+
73+
$_SERVER['HTTPS'] = true;
74+
```
75+
76+
You can also set this value to `false` to explicitly tell Phabricator that a
77+
request is not an SSL request.
78+
79+
= Adjusting Rate Limiting =
80+
81+
Phabricator performs coarse, IP-based rate limiting by default. In most
82+
situations the default settings should be reasonable: they are set fairly high,
83+
and intended to prevent only significantly abusive behavior.
84+
85+
However, if legitimate traffic is being rate limited (or you want to make the
86+
limits more strict) you can adjust the limits in the preamble script.
87+
88+
```
89+
name=Adjust Rate Limiting Behavior
90+
<?php
91+
92+
// The default is 1000, so a value of 2000 increases the limit by a factor
93+
// of 2: users will be able to make twice as many requests before being
94+
// rate limited.
95+
96+
// You can set the limit to 0 to disable rate limiting.
97+
98+
PhabricatorStartup::setMaximumRate(2000);
99+
```
100+
101+
By examining `$_SERVER['REMOTE_ADDR']` or similar parameters, you could also
102+
adjust the rate limit dynamically: for example, remove it for requests from an
103+
internal network, but impose a strict limit for external requests.
104+
105+
Rate limiting needs to be configured in this way in order to make it as cheap as
106+
possible to activate after a client is rate limited. The limiting checks execute
107+
before any libraries or configuration are loaded, and can emit a response within
108+
a few milliseconds.
109+
110+
= Next Steps =
111+
112+
Continue by:
113+
114+
- returning to the @{article:Configuration Guide}.

0 commit comments

Comments
 (0)
Failed to load comments.