fix: sanitize Discord community subnets and resolve WAN monitor hotplug spam (fixes #50, #51)

- Fix #50: Discord community subnets hijacking Cloudflare Anycast traffic:
  * Filter broad Cloudflare shared subnets (104.16.0.0/12, 172.64.0.0/13, etc.) for Discord preset in generator_routes.uc, nft/apply.uc, and updates.uc.
  * Add tachyon resolve_domain CLI and runtime.uc helper for DNS queries with rpcd ACL support.
  * Update LuCI Routing Rule Tracer to resolve queried domains against section subnets/CIDRs (including community subnets) and show shared CDN/Anycast warnings.
  * Add unit tests in tests/community_subnets_sanitization.sh.

- Fix #51: Telegram bot spamming WAN up/down notifications on hotplug:
  * Check enable_badwan_interface_monitoring, telegram.enabled, and badwan_monitored_interfaces list in 99-tachyon-wan-monitor.
  * Add background debounce with atomic directory locking and ubus interface status verification.
  * Implement state transition tracking to only notify on actual UP->DOWN and DOWN->UP changes without duplicates.
  * Preserve retry_start_on_wan_up behavior on ifup.
  * Add comprehensive integration test suite in tests/wan_monitor_hotplug.sh.
This commit is contained in:
Dushnilin
2026-09-11 23:07:10 +03:00
parent 5933fd2f0c
commit 0ea1c73832
16 changed files with 4456 additions and 3398 deletions
+22 -2
View File
@@ -6,6 +6,14 @@ let helpers = require("core.helpers");
let uci_core = require("core.uci");
let connections = require("config.connections");
function core_ip_module_or_null() {
try {
return require("core.ip");
} catch (e) {
return null;
}
}
function core_url_module_or_null() {
try {
return require("core.url");
@@ -2518,11 +2526,15 @@ function import_all_preset_lists(settings) {
}
}
let core_ip = core_ip_module_or_null();
let lines = split(as_string(fs.readfile(tmpfile)), "\n");
for (let l in lines) {
l = trim(replace(as_string(l), /\r/g, ""));
if (l != "" && substr(l, 0, 1) != "#")
if (l != "" && substr(l, 0, 1) != "#") {
if (as_string(service) == "discord" && core_ip && core_ip.is_cloudflare_shared_cidr(l))
continue;
push(combined_lines, l);
}
}
if (downloaded)
@@ -2584,12 +2596,20 @@ function import_builtin_subnets_from_rule(section, settings) {
}
}
let core_ip = core_ip_module_or_null();
let lines = split(as_string(fs.readfile(tmpfile)), "\n");
let filtered_for_nft = [];
for (let l in lines) {
l = trim(replace(as_string(l), /\r/g, ""));
if (l != "" && substr(l, 0, 1) != "#")
if (l != "" && substr(l, 0, 1) != "#") {
if (as_string(service) == "discord" && core_ip && core_ip.is_cloudflare_shared_cidr(l))
continue;
push(combined_lines, l);
push(filtered_for_nft, l);
}
}
if (as_string(service) == "discord")
write_file(tmpfile, join("\n", filtered_for_nft) + "\n");
nft_module_success([
"nft-add-community-subnet-file-for-uci-section",