From 1fed9cb8d33f04b98d34ec74510d01b6d8b5c5e6 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 23 Dec 2022 13:38:28 +0100 Subject: Don't need to use redis to block tracker ips There could be many of them, so reduce load by storing IPs directly inside node memory --- server/controllers/tracker.ts | 32 ++++++++++++++++---------------- server/initializers/constants.ts | 5 ++++- server/lib/redis.ts | 15 --------------- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/server/controllers/tracker.ts b/server/controllers/tracker.ts index 19a8b2bc9..0ef98c35e 100644 --- a/server/controllers/tracker.ts +++ b/server/controllers/tracker.ts @@ -1,17 +1,22 @@ import { Server as TrackerServer } from 'bittorrent-tracker' import express from 'express' import { createServer } from 'http' +import LRUCache from 'lru-cache' import proxyAddr from 'proxy-addr' import { WebSocketServer } from 'ws' -import { Redis } from '@server/lib/redis' import { logger } from '../helpers/logger' import { CONFIG } from '../initializers/config' -import { TRACKER_RATE_LIMITS } from '../initializers/constants' +import { LRU_CACHE, TRACKER_RATE_LIMITS } from '../initializers/constants' import { VideoFileModel } from '../models/video/video-file' import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist' const trackerRouter = express.Router() +const blockedIPs = new LRUCache({ + max: LRU_CACHE.TRACKER_IPS.MAX_SIZE, + ttl: TRACKER_RATE_LIMITS.BLOCK_IP_LIFETIME +}) + let peersIps = {} let peersIpInfoHash = {} runPeersChecker() @@ -55,8 +60,7 @@ const trackerServer = new TrackerServer({ // Close socket connection and block IP for a few time if (params.type === 'ws') { - Redis.Instance.setTrackerBlockIP(ip) - .catch(err => logger.error('Cannot set tracker block ip.', { err })) + blockedIPs.set(ip, true) // setTimeout to wait filter response setTimeout(() => params.socket.close(), 0) @@ -102,20 +106,16 @@ function createWebsocketTrackerServer (app: express.Application) { if (request.url === '/tracker/socket') { const ip = proxyAddr(request, CONFIG.TRUST_PROXY) - Redis.Instance.doesTrackerBlockIPExist(ip) - .then(result => { - if (result === true) { - logger.debug('Blocking IP %s from tracker.', ip) + if (blockedIPs.has(ip)) { + logger.debug('Blocking IP %s from tracker.', ip) - socket.write('HTTP/1.1 403 Forbidden\r\n\r\n') - socket.destroy() - return - } + socket.write('HTTP/1.1 403 Forbidden\r\n\r\n') + socket.destroy() + return + } - // FIXME: typings - return wss.handleUpgrade(request, socket as any, head, ws => wss.emit('connection', ws, request)) - }) - .catch(err => logger.error('Cannot check if tracker block ip exists.', { err })) + // FIXME: typings + return wss.handleUpgrade(request, socket as any, head, ws => wss.emit('connection', ws, request)) } // Don't destroy socket, we have Socket.IO too diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 0e56f0c9f..ec5045078 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -781,6 +781,9 @@ const LRU_CACHE = { VIDEO_TOKENS: { MAX_SIZE: 100_000, TTL: parseDurationToMs('8 hours') + }, + TRACKER_IPS: { + MAX_SIZE: 100_000 } } @@ -884,7 +887,7 @@ const TRACKER_RATE_LIMITS = { INTERVAL: 60000 * 5, // 5 minutes ANNOUNCES_PER_IP_PER_INFOHASH: 15, // maximum announces per torrent in the interval ANNOUNCES_PER_IP: 30, // maximum announces for all our torrents in the interval - BLOCK_IP_LIFETIME: 60000 * 3 // 3 minutes + BLOCK_IP_LIFETIME: parseDurationToMs('3 minutes') } const P2P_MEDIA_LOADER_PEER_VERSION = 2 diff --git a/server/lib/redis.ts b/server/lib/redis.ts index c0e9aece7..451ddd0b6 100644 --- a/server/lib/redis.ts +++ b/server/lib/redis.ts @@ -8,7 +8,6 @@ import { AP_CLEANER, CONTACT_FORM_LIFETIME, RESUMABLE_UPLOAD_SESSION_LIFETIME, - TRACKER_RATE_LIMITS, TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME, USER_EMAIL_VERIFY_LIFETIME, USER_PASSWORD_CREATE_LIFETIME, @@ -157,16 +156,6 @@ class Redis { return this.exists(this.generateIPViewKey(ip, videoUUID)) } - /* ************ Tracker IP block ************ */ - - setTrackerBlockIP (ip: string) { - return this.setValue(this.generateTrackerBlockIPKey(ip), '1', TRACKER_RATE_LIMITS.BLOCK_IP_LIFETIME) - } - - async doesTrackerBlockIPExist (ip: string) { - return this.exists(this.generateTrackerBlockIPKey(ip)) - } - /* ************ Video views stats ************ */ addVideoViewStats (videoId: number) { @@ -365,10 +354,6 @@ class Redis { return `views-${videoUUID}-${ip}` } - private generateTrackerBlockIPKey (ip: string) { - return `tracker-block-ip-${ip}` - } - private generateContactFormKey (ip: string) { return 'contact-form-' + ip } -- cgit v1.2.3