Comments only -- no code changed. Covers the blocklist, file allowlist, login allowlist, auto-denylist, CrowdSec reporter and firewall. Removes development narration: "(Task 2)" left over from a plan in Firewall.PurgeExpired, "matching the per-feature JSON config pattern used by X" repeated across four config loaders, "Recurring and tokenless before" describing an edit rather than the code, and a duplicated threading note in BlocklistSnapshot that the inline comment already made. Points Firewall at dev-docs/ip-bans-and-allowlists.md instead of a "ban-channel design doc" that does not exist. Fixes a stale reference the cleanup surfaced: FileAllowlist's remarks still told readers to opt in via blocklist.json's "allowlistEnabled", which moved to "enabled" in ip-allowlist.json. Kept, in tightened form, everything that encodes a reason the code cannot show: the CrowdSec culture and LAPI protocol notes, why the reporter flushes off the loop thread at shutdown, why FullMode.Wait rather than DropWrite, why Firewall reads Core.Now instead of DateTime.UtcNow, and the volatile-swap contracts on both snapshots. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
80 lines
3.3 KiB
C#
80 lines
3.3 KiB
C#
/*************************************************************************
|
|
* ModernUO *
|
|
* Copyright 2019-2026 - ModernUO Development Team *
|
|
* Email: hi@modernuo.com *
|
|
* File: AutoDenylistConfiguration.cs *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
*************************************************************************/
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Text.Json.Serialization;
|
|
using Server.Json;
|
|
|
|
namespace Server.Network;
|
|
|
|
/// <summary>
|
|
/// Loads the <see cref="AutoDenylistSettings"/> from <c>Configuration/auto-denylist.json</c>. Loaded once;
|
|
/// a missing file writes a template so operators have something to edit.
|
|
/// </summary>
|
|
public static class AutoDenylistConfiguration
|
|
{
|
|
private const string _path = "Configuration/auto-denylist.json";
|
|
|
|
public static AutoDenylistSettings Settings { get; private set; }
|
|
|
|
public static void Load()
|
|
{
|
|
var path = Path.Join(Core.BaseDirectory, _path);
|
|
|
|
if (File.Exists(path))
|
|
{
|
|
Settings = JsonConfig.Deserialize<AutoDenylistSettings>(path);
|
|
}
|
|
else
|
|
{
|
|
Settings = new AutoDenylistSettings();
|
|
Save();
|
|
}
|
|
}
|
|
|
|
private static void Save()
|
|
{
|
|
JsonConfig.Serialize(Path.Join(Core.BaseDirectory, _path), Settings);
|
|
}
|
|
}
|
|
|
|
/// <summary>Bound configuration for <see cref="AutoDenylist"/>.</summary>
|
|
public record AutoDenylistSettings
|
|
{
|
|
/// <summary>Whether behavioural detections are held locally. Disabled makes the filter inert.</summary>
|
|
[JsonPropertyName("enabled")]
|
|
public bool Enabled { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// How long an address is denied at accept after the shard catches it misbehaving. Deliberately
|
|
/// independent of the duration reported to external bouncers: this is a local holding pen, not a ban.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Short on purpose: it covers the gap before an OS bouncer reacts, and blunts a flood on shards running
|
|
/// none. An address still attacking is simply re-detected and re-added, so the list sustains itself while
|
|
/// a mistake clears on its own.
|
|
/// </remarks>
|
|
[JsonPropertyName("duration")]
|
|
public TimeSpan Duration { get; set; } = TimeSpan.FromMinutes(15);
|
|
|
|
/// <summary>
|
|
/// Hard cap on tracked addresses: a distinct-source flood is the case this exists for, so the cap is what
|
|
/// stops it becoming the exhaustion it prevents. At the cap new addresses are not tracked, but are still
|
|
/// disconnected by whichever gate detected them.
|
|
/// </summary>
|
|
[JsonPropertyName("maxEntries")]
|
|
public int MaxEntries { get; set; } = 65536;
|
|
}
|