mirror of
https://github.com/wukko/cobalt.git
synced 2024-11-15 04:39:58 +00:00
api: add support for redis to ratelimiter cache
This commit is contained in:
parent
d466f8a4af
commit
2317da5ba5
4 changed files with 39 additions and 1 deletions
|
@ -46,6 +46,7 @@
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"freebind": "^0.2.2",
|
"freebind": "^0.2.2",
|
||||||
|
"rate-limit-redis": "^4.2.0",
|
||||||
"redis": "^4.7.0"
|
"redis": "^4.7.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { env, setTunnelPort } from "../config.js";
|
||||||
import { extract } from "../processing/url.js";
|
import { extract } from "../processing/url.js";
|
||||||
import { Green, Bright, Cyan } from "../misc/console-text.js";
|
import { Green, Bright, Cyan } from "../misc/console-text.js";
|
||||||
import { hashHmac } from "../security/secrets.js";
|
import { hashHmac } from "../security/secrets.js";
|
||||||
|
import { createStore } from "../store/redis-ratelimit.js";
|
||||||
import { randomizeCiphers } from "../misc/randomize-ciphers.js";
|
import { randomizeCiphers } from "../misc/randomize-ciphers.js";
|
||||||
import { verifyTurnstileToken } from "../security/turnstile.js";
|
import { verifyTurnstileToken } from "../security/turnstile.js";
|
||||||
import { friendlyServiceName } from "../processing/service-alias.js";
|
import { friendlyServiceName } from "../processing/service-alias.js";
|
||||||
|
@ -40,7 +41,7 @@ const fail = (res, code, context) => {
|
||||||
res.status(status).json(body);
|
res.status(status).json(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const runAPI = (express, app, __dirname, isPrimary = true) => {
|
export const runAPI = async (express, app, __dirname, isPrimary = true) => {
|
||||||
const startTime = new Date();
|
const startTime = new Date();
|
||||||
const startTimestamp = startTime.getTime();
|
const startTimestamp = startTime.getTime();
|
||||||
|
|
||||||
|
@ -76,6 +77,7 @@ export const runAPI = (express, app, __dirname, isPrimary = true) => {
|
||||||
standardHeaders: 'draft-6',
|
standardHeaders: 'draft-6',
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator,
|
keyGenerator,
|
||||||
|
store: await createStore('session'),
|
||||||
handler: handleRateExceeded
|
handler: handleRateExceeded
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -85,6 +87,7 @@ export const runAPI = (express, app, __dirname, isPrimary = true) => {
|
||||||
standardHeaders: 'draft-6',
|
standardHeaders: 'draft-6',
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: req => req.rateLimitKey || keyGenerator(req),
|
keyGenerator: req => req.rateLimitKey || keyGenerator(req),
|
||||||
|
store: await createStore('api'),
|
||||||
handler: handleRateExceeded
|
handler: handleRateExceeded
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -94,6 +97,7 @@ export const runAPI = (express, app, __dirname, isPrimary = true) => {
|
||||||
standardHeaders: 'draft-6',
|
standardHeaders: 'draft-6',
|
||||||
legacyHeaders: false,
|
legacyHeaders: false,
|
||||||
keyGenerator: req => req.rateLimitKey || keyGenerator(req),
|
keyGenerator: req => req.rateLimitKey || keyGenerator(req),
|
||||||
|
store: await createStore('tunnel'),
|
||||||
handler: (_, res) => {
|
handler: (_, res) => {
|
||||||
return res.sendStatus(429)
|
return res.sendStatus(429)
|
||||||
}
|
}
|
||||||
|
|
19
api/src/store/redis-ratelimit.js
Normal file
19
api/src/store/redis-ratelimit.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { env } from "../config.js";
|
||||||
|
|
||||||
|
let client, redis, redisLimiter;
|
||||||
|
|
||||||
|
export const createStore = async (name) => {
|
||||||
|
if (!env.redisURL) return;
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
redis = await import('redis');
|
||||||
|
redisLimiter = await import('rate-limit-redis');
|
||||||
|
client = redis.createClient({ url: env.redisURL });
|
||||||
|
await client.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new redisLimiter.default({
|
||||||
|
prefix: `RL${name}_`,
|
||||||
|
sendCommand: (...args) => client.sendCommand(args),
|
||||||
|
});
|
||||||
|
}
|
|
@ -71,6 +71,9 @@ importers:
|
||||||
freebind:
|
freebind:
|
||||||
specifier: ^0.2.2
|
specifier: ^0.2.2
|
||||||
version: 0.2.2
|
version: 0.2.2
|
||||||
|
rate-limit-redis:
|
||||||
|
specifier: ^4.2.0
|
||||||
|
version: 4.2.0(express-rate-limit@7.4.1(express@4.21.0))
|
||||||
redis:
|
redis:
|
||||||
specifier: ^4.7.0
|
specifier: ^4.7.0
|
||||||
version: 4.7.0
|
version: 4.7.0
|
||||||
|
@ -1877,6 +1880,12 @@ packages:
|
||||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
rate-limit-redis@4.2.0:
|
||||||
|
resolution: {integrity: sha512-wV450NQyKC24NmPosJb2131RoczLdfIJdKCReNwtVpm5998U8SgKrAZrIHaN/NfQgqOHaan8Uq++B4sa5REwjA==}
|
||||||
|
engines: {node: '>= 16'}
|
||||||
|
peerDependencies:
|
||||||
|
express-rate-limit: '>= 6'
|
||||||
|
|
||||||
raw-body@2.5.2:
|
raw-body@2.5.2:
|
||||||
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
|
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
|
||||||
engines: {node: '>= 0.8'}
|
engines: {node: '>= 0.8'}
|
||||||
|
@ -3868,6 +3877,11 @@ snapshots:
|
||||||
|
|
||||||
range-parser@1.2.1: {}
|
range-parser@1.2.1: {}
|
||||||
|
|
||||||
|
rate-limit-redis@4.2.0(express-rate-limit@7.4.1(express@4.21.0)):
|
||||||
|
dependencies:
|
||||||
|
express-rate-limit: 7.4.1(express@4.21.0)
|
||||||
|
optional: true
|
||||||
|
|
||||||
raw-body@2.5.2:
|
raw-body@2.5.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
bytes: 3.1.2
|
bytes: 3.1.2
|
||||||
|
|
Loading…
Reference in a new issue