Add text replies for DNSBL responses.

Closes #1243.
This commit is contained in:
Sadie Powell 2024-10-13 13:08:55 +01:00
parent 5d436585ca
commit e9018ab055
4 changed files with 135 additions and 4 deletions

View File

@ -8,4 +8,80 @@
records="3,5,6,7,8,9,10,11,13,14,15,16,17,19"
action="zline"
duration="7d"
reason="You are listed in DroneBL. Please visit https://dronebl.org/lookup.do?ip=%ip%&network=%network.url% for more information.">
reason="You are listed in DroneBL: %reason%. Please visit https://dronebl.org/lookup.do?ip=%ip%&network=%network.url% for more information.">
<dnsblreply name="DroneBL"
reply="1"
description="Testing">
<dnsblreply name="DroneBL"
reply="2"
description="Sample data used for heuristical analysis">
<dnsblreply name="DroneBL"
reply="3"
description="IRC spam drone (litmus/sdbot/fyle)">
<dnsblreply name="DroneBL"
reply="5"
description="Bottler">
<dnsblreply name="DroneBL"
reply="6"
description="Unknown worm or spambot">
<dnsblreply name="DroneBL"
reply="7"
description="DDoS drone">
<dnsblreply name="DroneBL"
reply="8"
description="Open SOCKS proxy">
<dnsblreply name="DroneBL"
reply="9"
description="Open HTTP proxy">
<dnsblreply name="DroneBL"
reply="10"
description="Proxychain">
<dnsblreply name="DroneBL"
reply="11"
description="Webpage proxy">
<dnsblreply name="DroneBL"
reply="12"
description="Open DNS resolver">
<dnsblreply name="DroneBL"
reply="13"
description="Automated dictionary attack">
<dnsblreply name="DroneBL"
reply="14"
description="Open WINGATE proxy">
<dnsblreply name="DroneBL"
reply="15"
description="Compromised router / gateway">
<dnsblreply name="DroneBL"
reply="16"
description="Autorooting worm">
<dnsblreply name="DroneBL"
reply="17"
description="Automatically determined botnet IP">
<dnsblreply name="DroneBL"
reply="18"
description="Possibly compromised DNS/MX type hostname detected on IRC">
<dnsblreply name="DroneBL"
reply="19"
description="Abused VPN service">
<dnsblreply name="DroneBL"
reply="255"
description="Uncategorized threat">

View File

@ -8,4 +8,24 @@
records="1,2,3,4,5"
action="zline"
duration="7d"
reason="You are listed in the EFnet RBL. Please visit https://rbl.efnetrbl.org/?i=%ip% for more information.">
reason="You are listed in the EFnet RBL: %reason%. Please visit https://rbl.efnetrbl.org/?i=%ip% for more information.">
<dnsblreply name="EFnet RBL"
reply="1"
description="Open proxy">
<dnsblreply name="EFnet RBL"
reply="2"
description="Spamtrap score of 666">
<dnsblreply name="EFnet RBL"
reply="3"
description="Spamtrap score of 50+">
<dnsblreply name="EFnet RBL"
reply="4"
description="Tor exit node">
<dnsblreply name="EFnet RBL"
reply="5"
description="Drones or flooding">

View File

@ -10,3 +10,7 @@
action="zline"
duration="7d"
reason="Tor exit nodes are not allowed on this network. See https://metrics.torproject.org/rs.html#search/%ip% for more information.">
<dnsblreply name="torexit.dan.me.uk"
reply="100"
description="Tor exit node">

View File

@ -96,6 +96,9 @@ public:
// A range of DNSBL result types to match against.
CharState records;
// A map of DNSBL replies to their descriptions.
insp::flat_map<uint32_t, std::string> replies;
// The message to send to users who's IP address is in a DNSBL.
std::string reason;
@ -365,12 +368,16 @@ public:
if (match)
{
const auto it = config->replies.find(result);
const auto reasonstr = it == config->replies.end() ? INSP_FORMAT("Result {}", result) : it->second;
const std::string reason = Template::Replace(config->reason, {
{ "dnsbl", config->name },
{ "dnsbl.url", Percent::Encode(config->name) },
{ "ip", them->GetAddress() },
{ "network", ServerInstance->Config->Network },
{ "network.url", Percent::Encode(ServerInstance->Config->Network) },
{ "reason", reasonstr },
{ "result", ConvToStr(result) },
});
@ -421,9 +428,9 @@ public:
}
}
ServerInstance->SNO.WriteGlobalSno('d', "{} {} ({}) detected as being on the '{}' DNSBL with result {}{}",
ServerInstance->SNO.WriteGlobalSno('d', "{} {} ({}) detected as being on the '{}' DNSBL: {}{}",
them->IsFullyConnected() ? "User" : "Connecting user", them->GetRealMask(), them->GetAddress(),
config->name, result, them->exempt ? " -- exempt" : "");
config->name, reasonstr, them->exempt ? " -- exempt" : "");
}
else
config->stats_misses++;
@ -594,6 +601,30 @@ public:
auto entry = std::make_shared<DNSBLEntry>(this, tag);
newdnsbls.push_back(entry);
}
for (const auto& [_, tag] : ServerInstance->Config->ConfTags("dnsblreply"))
{
const auto dnsblname = tag->getString("name");
auto dnsbl = std::find_if(newdnsbls.begin(), newdnsbls.end(), [&dnsblname](const auto& d)
{
return insp::equalsci(d->name, dnsblname);
});
if (dnsbl == newdnsbls.end())
throw ModuleException(this, "<dnsblreply:name> must be set to the name of a DNSBL at " + tag->source.str());
const auto dnsbldesc = tag->getString("description");
if (dnsbldesc.empty())
throw ModuleException(this, "<dnsblreply:description> must not be empty at " + tag->source.str());
const auto dnsblreply = tag->getNum<uint32_t>("reply", std::numeric_limits<uint32_t>::max());
if (dnsblreply > 16'777'215)
{
throw ModuleException(this, INSP_FORMAT("<dnsblreply:reply> ({}) is not a valid DNSBL reply at {}",
dnsblreply, tag->source.str()));
}
(*dnsbl)->replies[dnsblreply] = dnsbldesc;
}
data.dnsbls.swap(newdnsbls);
}