From e9dcf5ac04b083d284f0d1ea3fb20b8c581da85f Mon Sep 17 00:00:00 2001 From: abretonc7s <107169956+abretonc7s@users.noreply.github.com> Date: Wed, 6 Mar 2024 19:01:51 +0800 Subject: [PATCH] feat: enable redis tls (#733) --- packages/sdk-socket-server-next/.env.sample | 1 + .../sdk-socket-server-next/src/api-config.ts | 58 ++++++++++++++++--- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/packages/sdk-socket-server-next/.env.sample b/packages/sdk-socket-server-next/.env.sample index 32f5cdb2c..6c78bfd02 100644 --- a/packages/sdk-socket-server-next/.env.sample +++ b/packages/sdk-socket-server-next/.env.sample @@ -4,6 +4,7 @@ SEGMENT_API_KEY_DEBUG=123456789 # Example REDIS_NODES format: "redis://host1:6379,redis://host2:6379" REDIS_NODES=redis://localhost:6380,redis://localhost:6381,redis://localhost:6382 REDIS_PASSWORD=redis_password +REDIS_TLS=false RATE_LIMITER=false RATE_LIMITER_HTTP_WINDOW_MINUTE=1 RATE_LIMITER_HTTP_LIMIT=100000 diff --git a/packages/sdk-socket-server-next/src/api-config.ts b/packages/sdk-socket-server-next/src/api-config.ts index 77507c9b8..d4a27c5f7 100644 --- a/packages/sdk-socket-server-next/src/api-config.ts +++ b/packages/sdk-socket-server-next/src/api-config.ts @@ -6,7 +6,7 @@ import cors from 'cors'; import express from 'express'; import { rateLimit } from 'express-rate-limit'; import helmet from 'helmet'; -import { Cluster, ClusterOptions, Redis } from 'ioredis'; +import { Cluster, ClusterOptions, Redis, RedisOptions } from 'ioredis'; import { logger } from './logger'; import { isDevelopment, isDevelopmentServer } from '.'; @@ -37,19 +37,61 @@ if (redisNodes.length === 0) { } const redisCluster = process.env.REDIS_CLUSTER === 'true'; +const redisTLS = process.env.REDIS_TLS === 'true'; + let redisClient: Cluster | Redis | undefined; -const redisClusterOptions: ClusterOptions = { - // slotsRefreshTimeout: 2000, - redisOptions: { - // tls: {}, // WARN: enabling tls would fail the client if not setup with correct params - password: process.env.REDIS_PASSWORD, - }, + +export const getRedisOptions = ( + isTls: boolean, + password: string | undefined, +): RedisOptions => { + const tlsOptions = { + tls: { + checkServerIdentity: (/* host, cert*/) => { + return undefined; + }, + }, + }; + + return { + ...(password && { password }), + ...(isTls && tlsOptions), + connectTimeout: 30000, + maxRetriesPerRequest: 4, + retryStrategy: (times) => Math.min(times * 30, 1000), + reconnectOnError: (error) => { + // eslint-disable-next-line require-unicode-regexp + const targetErrors = [/READONLY/, /ETIMEDOUT/]; + return targetErrors.some((targetError) => + targetError.test(error.message), + ); + }, + }; }; export const getRedisClient = () => { if (!redisClient) { if (redisCluster) { - logger.info('Connecting to Redis Cluster'); + logger.info('Connecting to Redis Cluster...'); + + const redisOptions = getRedisOptions( + redisTLS, + process.env.REDIS_PASSWORD, + ); + const redisClusterOptions: ClusterOptions = { + dnsLookup: (address, callback) => callback(null, address), + slotsRefreshTimeout: 2000, + slotsRefreshInterval: 4000, + clusterRetryStrategy: (times) => Math.min(times * 30, 1000), + enableAutoPipelining: true, + redisOptions, + }; + + logger.debug( + 'Redis Cluster options:', + JSON.stringify(redisClusterOptions, null, 2), + ); + redisClient = new Cluster(redisNodes, redisClusterOptions); } else { logger.info('Connecting to single Redis node');