summaryrefslogtreecommitdiffhomepage
path: root/HTTP
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-09-13 12:39:39 -0400
committerJoey Hess <joeyh@joeyh.name>2016-09-13 12:39:39 -0400
commit48ec718a6211a71ae0a796eb1c3a6ea091dc6e14 (patch)
tree5de158916354c254b00ee9a7aca4d14c3752ffd9 /HTTP
parent9225bb5aea76e135c9bb16e9fa98862317e0efd4 (diff)
downloadkeysafe-48ec718a6211a71ae0a796eb1c3a6ea091dc6e14.tar.gz
refactor
Diffstat (limited to 'HTTP')
-rw-r--r--HTTP/RateLimit.hs46
1 files changed, 33 insertions, 13 deletions
diff --git a/HTTP/RateLimit.hs b/HTTP/RateLimit.hs
index d8b3dc1..e6b0344 100644
--- a/HTTP/RateLimit.hs
+++ b/HTTP/RateLimit.hs
@@ -92,13 +92,43 @@ bloomMaxSize = 1000000
-- period, which is especially useful when retrieving keys that were
-- split into multiple chunks. However, setting this too high lets clients
-- cheaply store lots of data on a server that has been idle for a while,
--- which could be an attractive way to abuse keysafe servers.
+-- which could be an attractive way to abuse keysafe servers for general
+-- data storage.
burstSize :: Word64
burstSize = 4 -- 256 kb immediate storage
-- | Rate that the bucket is filled.
fillRate :: Word64
-fillRate = 2 * 60 * 1000000 -- 1 token ever other minute
+fillRate = 2 * 60 * 1000000 -- 1 token every other minute
+
+-- This is a second level rate limiter, that limits the rate that
+-- RandomSalts are generated.
+--
+-- This prevents an attacker flooding requests that cause new random
+-- salts to be assigned, in order to fill up the bloom table and cause
+-- salts assigned to other clients to be rejected.
+--
+-- Since the bloom filters hold 1 million salts, with a 1 token per second
+-- fill rate, the attacker would need to send requests for over 10 hours to
+-- force a bloom filter rotation, so would not impact many users.
+--
+-- This also makes there be a hard upper bound on the number of requests
+-- per second. In a sitation where an attacker is willing to burn as much
+-- CPU as necessary to do proof of work and fill up a keysafe server,
+-- this is
+overallRateLimit :: RateLimiter -> IO ()
+overallRateLimit ratelimiter = tokenBucketWait
+ (randomSaltGenerationLimiter ratelimiter)
+ overallBurstSize
+ overallFillRate
+
+-- | This can be quite high; being able to generate a few thousand
+-- RandomSalts is not useful to an attacker.
+overallBurstSize :: Word64
+overallBurstSize = 1000
+
+overallFillRate :: Word64
+overallFillRate = 100000 -- refill 1 token per second
-- | How much data could be stored, in bytes per second, assuming all
-- buckets in the rate limiter are kept drained, and all requests are
@@ -162,17 +192,7 @@ assignWork :: RateLimiter -> [Bucket] -> Handler (POWGuarded a)
assignWork ratelimiter bs = case mapMaybe mkProofReq bs of
[] -> throwError err404
(mkreq:_) -> liftIO $ do
- -- This prevents an attacker flooding requests that
- -- cause new random salts to be assigned, in order
- -- to fill up the bloom table and cause salts assigned
- -- to other clients to be rejected.
- -- Since the bloom filters hold 1 million salts,
- -- the attacker would need to send requests for over 10
- -- hours to force a bloom filter rotation, so would not
- -- impact many users.
- tokenBucketWait (randomSaltGenerationLimiter ratelimiter)
- 100 -- burst
- 100000 -- refill 1 token per second
+ overallRateLimit ratelimiter
salt <- liftIO mkRandomSalt
withBloomFilter ratelimiter assignedRandomSalts