:global GlobalScriptsUrl;
:local FwAddrListsUrl ($GlobalScriptsUrl . "fw-addr-lists.d/");
-
- :local FwAddrLists {
- "allow"={
- { url=($FwAddrListsUrl . "allow");
- cert="ISRG Root X2"; timeout=1w };
- };
- "block"={
- { url=($FwAddrListsUrl . "block");
- cert="ISRG Root X2" };
-# { url="https://raw.githubusercontent.com/stamparm/ipsum/refs/heads/master/levels/4.txt";
-# # higher level (decrease the numerical value) for more addresses, and vice versa
-# cert="ISRG Root X1" };
-# { url="https://www.dshield.org/block.txt"; cidr="/24";
-# cert="GTS Root R4" };
-# { url="https://lists.blocklist.de/lists/strongips.txt";
-# cert="GTS Root R4" };
-# { url="https://www.spamhaus.org/drop/drop_v4.json";
-# cert="GTS Root R4" };
-# { url="https://www.spamhaus.org/drop/drop_v6.json";
-# cert="GTS Root R4" };
- };
-# "mikrotik"={
-# { url=($FwAddrListsUrl . "mikrotik");
-# cert="ISRG Root X2"; timeout=1w };
-# };
- "FuckRKN"={
- { url=($FwAddrListsUrl . "FuckRKN");
- cert="ISRG Root X2"; timeout=1w };
- };
- };
+ :local FwAddrListsIndexUrl ($FwAddrListsUrl . "index");
:local FwAddrListTimeOut 1d;
:global CertificateAvailable;
:local FindDelim do={
:local ValidChars "0123456789.:/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-";
- :for I from=0 to=[ :len $1 ] do={
- :if ([ :typeof [ :find $ValidChars [ :pick ($1 . " ") $I ] ] ] != "num") do={
+ :for I from=0 to=([ :len $1 ] - 1) do={
+ :if ([ :typeof [ :find $ValidChars [ :pick $1 $I ] ] ] != "num") do={
:return $I;
}
}
}
:local ListComment ("managed by " . $ScriptName);
+ :local FwAddrListsIndex false;
+
+ :for I from=1 to=5 do={
+ :if ($FwAddrListsIndex = false) do={
+ :set FwAddrListsIndex [ :tolf [ $FetchHuge $ScriptName $FwAddrListsIndexUrl false ] ];
+ :if ($FwAddrListsIndex = false && $I < 5) do={
+ :log debug ($ScriptName . " Failed downloading address-list index, " . $I . ". try from: " . $FwAddrListsIndexUrl);
+ :delay (($I * $I) . "s");
+ }
+ }
+ }
+ :if ($FwAddrListsIndex = false) do={
+ :log warning ($ScriptName . " Failed downloading address-list index from: " . $FwAddrListsIndexUrl);
+ :set FwAddrListsIndex "";
+ }
+
+ :foreach FwListFile in=[ :deserialize $FwAddrListsIndex delimiter="\n" from=dsv options=dsv.plain ] do={
+ :local FwListName ($FwListFile->0);
+ :local Delim [ $FindDelim $FwListName ];
+ :if ($Delim = 0) do={ :set FwListName ""; };
+ :if ([ :len $FwListName ] = 0) do={ :error true; }
+ :set FwListName [ :pick $FwListName 0 $Delim ];
- :foreach FwListName,FwList in=$FwAddrLists do={
+ :local FwListUrl ($FwAddrListsUrl . $FwListName);
:local CntAdd 0;
:local CntRenew 0;
:local CntRemove 0;
:local IPv4Addresses ({});
:local IPv6Addresses ({});
:local Failure false;
+ :local Data false;
+ :local TimeOut $FwAddrListTimeOut;
- :foreach List in=$FwList do={
- :local CheckCertificate false;
- :local Data false;
- :local TimeOut [ $EitherOr [ :totime ($List->"timeout") ] $FwAddrListTimeOut ];
-
- :if ([ :len ($List->"cert") ] > 0) do={
- :set CheckCertificate true;
- :if ([ $CertificateAvailable ($List->"cert") "fetch" ] = false) do={
- :log warning ($ScriptName . " Downloading required certificate (" . $FwListName . \
- " / " . $List->"url" . ") failed, trying anyway.");
+ :for I from=1 to=5 do={
+ :if ($Data = false) do={
+ :set Data [ :tolf [ $FetchHuge $ScriptName $FwListUrl false ] ];
+ :if ($Data = false && $I < 5) do={
+ :log debug ($ScriptName . " Failed downloading for list '" . $FwListName . "', " . $I . ". try from: " . $FwListUrl);
+ :delay (($I * $I) . "s");
}
}
+ }
- :for I from=1 to=5 do={
- :if ($Data = false) do={
- :set Data [ :tolf [ $FetchHuge $ScriptName ($List->"url") $CheckCertificate ] ];
- :if ($Data = false) do={
- :if ($I < 5) do={
- :log debug ($ScriptName . " Failed downloading for list '" . $FwListName . \
- "', " . $I . ". try from: " . $List->"url");
- :delay (($I * $I) . "s");
- }
- }
- }
- }
+ :if ($Data = false) do={
+ :set Data "";
+ :set Failure true;
+ :log warning ($ScriptName . " Failed downloading for list '" . $FwListName . "' from: " . $FwListUrl);
+ } else={
+ :log debug ($ScriptName . " Downloaded " . [ $HumanReadableNum [ :len $Data ] 1024 ] . "B for list '" . $FwListName . "' from: " . $FwListUrl);
+ }
- :if ($Data = false) do={
- :set Data "";
- :set Failure true;
- :log warning ($ScriptName . " Failed downloading for list '" . $FwListName . \
- "' from: " . $List->"url");
+ :foreach Line in=[ :deserialize $Data delimiter="\n" from=dsv options=dsv.plain ] do={
+ :set Line ($Line->0);
+ :local Delim [ $FindDelim $Line ];
+ :if ($Delim = 0) do={ :set Line ""; };
+ :if ([ :len $Line ] = 0) do={ :error true; }
+ :local Address;
+ :if ([ :pick $Line 0 1 ] = "{" && [ :pick $Line ([ :len $Line ] - 1) ] = "}") do={
+ :do {
+ :set Address [ :tostr ([ :deserialize from=json $Line ]->"cidr") ];
+ } on-error={ }
} else={
- :log debug ($ScriptName . " Downloaded " . [ $HumanReadableNum [ :len $Data ] 1024 ] . \
- "B for list '" . $FwListName . "' from: " . $List->"url");
+ :set Address [ :pick $Line 0 [ $FindDelim $Line ] ];
}
-
- :foreach Line in=[ :deserialize $Data delimiter="\n" from=dsv options=dsv.plain ] do={
- :set Line ($Line->0);
- :local Address;
- :if ([ :pick $Line 0 1 ] = "{" && [ :pick $Line ([ :len $Line ] - 1) ] = "}") do={
- :do {
- :set Address [ :tostr ([ :deserialize from=json $Line ]->"cidr") ];
- } on-error={ }
- } else={
- :set Address ([ :pick $Line 0 [ $FindDelim $Line ] ] . ($List->"cidr"));
- }
- :do {
- :local Branch;
- :if ($Address ~ "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(/[0-9]{1,2})?\$") do={
- :local Net $Address;
- :local CIDR 32;
- :local Slash [ :find $Address "/" ];
- :if ([ :typeof $Slash ] = "num") do={
- :set Net [ :toip [ :pick $Address 0 $Slash ] ]
- :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ];
- :set Address [ :tostr (([ :toip $Net ] & [ $NetMask4 $CIDR ]) . [ $IfThenElse ($CIDR < 32) ("/" . $CIDR) ]) ];
- }
- :set Branch [ $GetBranch $Address ];
- :set ($IPv4Addresses->$Branch->$Address) $TimeOut;
- :error true;
+ :do {
+ :local Branch;
+ :if ($Address ~ "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(/[0-9]{1,2})?\$") do={
+ :local Net $Address;
+ :local CIDR 32;
+ :local Slash [ :find $Address "/" ];
+ :if ([ :typeof $Slash ] = "num") do={
+ :set Net [ :toip [ :pick $Address 0 $Slash ] ]
+ :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ];
+ :set Address [ :tostr (([ :toip $Net ] & [ $NetMask4 $CIDR ]) . [ $IfThenElse ($CIDR < 32) ("/" . $CIDR) ]) ];
}
- :if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={
- :local Net $Address;
- :local CIDR 128;
- :local Slash [ :find $Address "/" ];
- :if ([ :typeof $Slash ] = "num") do={
- :set Net [ :toip6 [ :pick $Address 0 $Slash ] ]
- :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ];
- }
- :set Address (([ :toip6 $Net ] & [ $NetMask6 $CIDR ]) . "/" . $CIDR);
- :set Branch [ $GetBranch $Address ];
- :set ($IPv6Addresses->$Branch->$Address) $TimeOut;
- :error true;
- }
- :if ($Address ~ "^[\\.a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\$") do={
- :set Branch [ $GetBranch $Address ];
- :set ($IPv4Addresses->$Branch->$Address) $TimeOut;
- :set ($IPv6Addresses->$Branch->$Address) $TimeOut;
- :error true;
+ :set Branch [ $GetBranch $Address ];
+ :if ([ :typeof ($IPv4Addresses->$Branch) ] != "array") do={ :set ($IPv4Addresses->$Branch) ({}) };
+ :set ($IPv4Addresses->$Branch->$Address) $TimeOut;
+ :error true;
+ }
+ :if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={
+ :local Net $Address;
+ :local CIDR 128;
+ :local Slash [ :find $Address "/" ];
+ :if ([ :typeof $Slash ] = "num") do={
+ :set Net [ :toip6 [ :pick $Address 0 $Slash ] ]
+ :set CIDR [ :pick $Address ($Slash + 1) [ :len $Address ] ];
}
- } on-error={:log error ($ScriptName . " Failed parsing address: " . $Line->0);}
- }
+ :set Address (([ :toip6 $Net ] & [ $NetMask6 $CIDR ]) . "/" . $CIDR);
+ :set Branch [ $GetBranch $Address ];
+ :if ([ :typeof ($IPv6Addresses->$Branch) ] != "array") do={ :set ($IPv6Addresses->$Branch) ({}) };
+ :set ($IPv6Addresses->$Branch->$Address) $TimeOut;
+ :error true;
+ }
+ :if ($Address ~ "^[\\.a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\$") do={
+ :set Branch [ $GetBranch $Address ];
+ :if ([ :typeof ($IPv4Addresses->$Branch) ] != "array") do={ :set ($IPv4Addresses->$Branch) ({}) };
+ :if ([ :typeof ($IPv6Addresses->$Branch) ] != "array") do={ :set ($IPv6Addresses->$Branch) ({}) };
+ :set ($IPv4Addresses->$Branch->$Address) $TimeOut;
+ :set ($IPv6Addresses->$Branch->$Address) $TimeOut;
+ :error true;
+ }
+ } on-error={:log error ($ScriptName . " Failed parsing address: " . $Line->0);}
}
:foreach Entry in=[ /ip/firewall/address-list/find where \