Initial commit - realms platform

This commit is contained in:
doomtube 2026-01-05 22:54:27 -05:00
parent c590ab6d18
commit c717c3751c
234 changed files with 74103 additions and 15231 deletions

118
openresty/lua/uberban.lua Normal file
View file

@ -0,0 +1,118 @@
-- Site-wide uberban checking module
-- Blocks uberbanned fingerprints from accessing any endpoint
local redis = require "resty.redis"
local fingerprint = require "fingerprint"
local _M = {}
-- Cache for ban status (5 second TTL to reduce Redis load)
local uberban_cache = ngx.shared.uberban_cache
local CACHE_TTL = 5 -- seconds
-- Redis password cached at module load time
local REDIS_PASSWORD = os.getenv("REDIS_PASS")
-- Get Redis connection (same pattern as redis_helper.lua)
local function get_redis_connection()
local red = redis:new()
red:set_timeouts(1000, 1000, 1000) -- connect, send, read timeout in ms
local host = "redis"
local port = tonumber(os.getenv("REDIS_PORT")) or 6379
local ok, err = red:connect(host, port)
if not ok then
ngx.log(ngx.ERR, "[uberban] Failed to connect to Redis: ", err)
return nil
end
-- Authenticate if password is set
if REDIS_PASSWORD and REDIS_PASSWORD ~= "" then
local res, err = red:auth(REDIS_PASSWORD)
if not res then
ngx.log(ngx.ERR, "[uberban] Failed to authenticate to Redis: ", err)
return nil
end
end
-- Select database 1 (where chat-service stores fingerprint bans)
local db = tonumber(os.getenv("REDIS_DB")) or 1
local res, err = red:select(db)
if not res then
ngx.log(ngx.ERR, "[uberban] Failed to select Redis db ", db, ": ", err)
return nil
end
return red
end
local function close_redis_connection(red)
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.log(ngx.ERR, "[uberban] Failed to set keepalive: ", err)
end
end
-- Check if a fingerprint is uberbanned
-- Returns true if banned, false if not banned
function _M.is_banned(fp)
if not fp then
return false
end
-- Check cache first
if uberban_cache then
local cached = uberban_cache:get(fp)
if cached ~= nil then
return cached == "1"
end
end
-- Query Redis
local red = get_redis_connection()
if not red then
-- SECURITY FIX: Fail closed - if Redis is unavailable, deny access
-- This prevents banned users from accessing the system during outages
ngx.log(ngx.ERR, "[uberban] Redis unavailable - blocking request (fail closed)")
return true
end
-- Check if fingerprint is in the uberbanned set
local res, err = red:sismember("chat:banned:fingerprints", fp)
close_redis_connection(red)
if not res then
ngx.log(ngx.ERR, "[uberban] Redis SISMEMBER failed: ", err)
return false
end
local is_banned = (res == 1)
-- Cache the result
if uberban_cache then
uberban_cache:set(fp, is_banned and "1" or "0", CACHE_TTL)
end
return is_banned
end
-- Check fingerprint and block if uberbanned
-- Call this in access_by_lua_block
function _M.check_and_block()
-- Generate server-side fingerprint
local fp = fingerprint.generate()
if not fp then
return -- Can't generate fingerprint, allow request
end
-- Check if banned
if _M.is_banned(fp) then
ngx.status = ngx.HTTP_FORBIDDEN
ngx.header["Content-Type"] = "application/json"
ngx.say('{"error": "Access denied", "banned": true}')
return ngx.exit(ngx.HTTP_FORBIDDEN)
end
end
return _M