diff options
Diffstat (limited to 'fw-addr-lists.rsc')
-rw-r--r-- | fw-addr-lists.rsc | 145 |
1 files changed, 91 insertions, 54 deletions
diff --git a/fw-addr-lists.rsc b/fw-addr-lists.rsc index 007282c..0c45f7e 100644 --- a/fw-addr-lists.rsc +++ b/fw-addr-lists.rsc @@ -1,17 +1,18 @@ #!rsc by RouterOS # RouterOS script: fw-addr-lists -# Copyright (c) 2023-2024 Christian Hesse <mail@eworm.de> -# https://git.eworm.de/cgit/routeros-scripts/about/COPYING.md +# Copyright (c) 2023-2025 Christian Hesse <mail@eworm.de> +# https://rsc.eworm.de/COPYING.md # -# requires RouterOS, version=7.13 +# requires RouterOS, version=7.16 # # download, import and update firewall address-lists -# https://git.eworm.de/cgit/routeros-scripts/about/doc/fw-addr-lists.md +# https://rsc.eworm.de/doc/fw-addr-lists.md -:global GlobalFunctionsReady; -:while ($GlobalFunctionsReady != true) do={ :delay 500ms; } - -:do { +:local ExitOK false; +:onerror Err { + :global GlobalConfigReady; :global GlobalFunctionsReady; + :retry { :if ($GlobalConfigReady != true || $GlobalFunctionsReady != true) \ + do={ :error ("Global config and/or functions not ready."); }; } delay=500ms max=50; :local ScriptName [ :jobname ]; :global FwAddrLists; @@ -23,6 +24,7 @@ :global HumanReadableNum; :global LogPrint; :global LogPrintOnce; + :global LogPrintVerbose; :global ScriptLock; :global WaitFullyConnected; @@ -35,11 +37,23 @@ } } + :local GetBranch do={ + :global EitherOr; + :return [ :pick [ :convert transform=md5 to=hex [ :pick $1 0 [ $EitherOr [ :find $1 "/" ] [ :len $1 ] ] ] ] 0 2 ]; + } + :if ([ $ScriptLock $ScriptName ] = false) do={ + :set ExitOK true; :error false; } $WaitFullyConnected; + :if ([ :len [ /log/find where topics=({"script"; "warning"}) \ + message=("\$LogPrintOnce: The message is already in log, scripting subsystem may have crashed before!") ] ] > 0) do={ + $LogPrintOnce warning $ScriptName ("Scripting subsystem may have crashed, possibly caused by us. Delaying!"); + :delay 5m; + } + :local ListComment ("managed by " . $ScriptName); :foreach FwListName,FwList in=$FwAddrLists do={ @@ -65,7 +79,7 @@ :for I from=1 to=5 do={ :if ($Data = false) do={ - :set Data [ $FetchHuge $ScriptName ($List->"url") $CheckCertificate ]; + :set Data [ :tolf [ $FetchHuge $ScriptName ($List->"url") $CheckCertificate ] ]; :if ($Data = false) do={ :if ($I < 5) do={ $LogPrint debug $ScriptName ("Failed downloading for list '" . $FwListName . \ @@ -86,41 +100,56 @@ "B for list '" . $FwListName . "' from: " . $List->"url"); } - :while ([ :len $Data ] != 0) do={ - :local Line [ :pick $Data 0 [ :find $Data "\n" ] ]; - :local Address ([ :pick $Line 0 [ $FindDelim $Line ] ] . ($List->"cidr")); + :foreach Line in=[ :deserialize $Data delimiter="\n" from=dsv options=dsv.plain ] do={ + :set Line ($Line->0); + :local Address; + :if ([ :pick $Line 0 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 [ $GetBranch $Address ]; :if ($Address ~ "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(/[0-9]{1,2})?\$") do={ - :set ($IPv4Addresses->$Address) $TimeOut; + :if ($Address ~ "/32\$") do={ + :set Address [ :pick $Address 0 ([ :len $Address ] - 3) ]; + } + :set ($IPv4Addresses->$Branch->$Address) $TimeOut; :error true; } :if ($Address ~ "^[0-9a-zA-Z]*:[0-9a-zA-Z:\\.]+(/[0-9]{1,3})?\$") do={ - :set ($IPv6Addresses->$Address) $TimeOut; + :if ([ :typeof [ :find $Address "/" ] ] = "nil") do={ + :set Address ($Address . "/128"); + } + :set ($IPv6Addresses->$Branch->$Address) $TimeOut; :error true; } :if ($Address ~ "^[\\.a-zA-Z0-9-]+\\.[a-zA-Z]{2,}\$") do={ - :set ($IPv4Addresses->$Address) $TimeOut; - :set ($IPv6Addresses->$Address) $TimeOut; + :set ($IPv4Addresses->$Branch->$Address) $TimeOut; + :set ($IPv6Addresses->$Branch->$Address) $TimeOut; :error true; } } on-error={ } - :set Data [ :pick $Data ([ :len $Line ] + 1) [ :len $Data ] ]; } } :foreach Entry in=[ /ip/firewall/address-list/find where \ list=$FwListName comment=$ListComment ] do={ :local Address [ /ip/firewall/address-list/get $Entry address ]; - :if ([ :typeof ($IPv4Addresses->$Address) ] = "time") do={ - $LogPrint debug $ScriptName ("Renewing IPv4 address in list '" . $FwListName . \ - "' with " . ($IPv4Addresses->$Address) . ": " . $Address); - /ip/firewall/address-list/set $Entry timeout=($IPv4Addresses->$Address); - :set ($IPv4Addresses->$Address); + :local Branch [ $GetBranch $Address ]; + :local TimeOut ($IPv4Addresses->$Branch->$Address); + :if ([ :typeof $TimeOut ] = "time") do={ + $LogPrintVerbose debug $ScriptName ("Renewing IPv4 address " . $Address . \ + " in list '" . $FwListName . "' with " . $TimeOut . "."); + /ip/firewall/address-list/set $Entry timeout=$TimeOut; + :set ($IPv4Addresses->$Branch->$Address); :set CntRenew ($CntRenew + 1); } else={ :if ($Failure = false) do={ - $LogPrint debug $ScriptName ("Removing IPv4 address from list '" . $FwListName . \ - "': " . $Address); + $LogPrintVerbose debug $ScriptName ("Removing IPv4 address " . $Address . \ + " from list '" . $FwListName . "."); /ip/firewall/address-list/remove $Entry; :set CntRemove ($CntRemove + 1); } @@ -130,47 +159,53 @@ :foreach Entry in=[ /ipv6/firewall/address-list/find where \ list=$FwListName comment=$ListComment ] do={ :local Address [ /ipv6/firewall/address-list/get $Entry address ]; - :if ([ :typeof ($IPv6Addresses->$Address) ] = "time") do={ - $LogPrint debug $ScriptName ("Renewing IPv6 address in list '" . $FwListName . \ - "' with " . ($IPv6Addresses->$Address) . ": " . $Address); - /ipv6/firewall/address-list/set $Entry timeout=($IPv6Addresses->$Address); - :set ($IPv6Addresses->$Address); + :local Branch [ $GetBranch $Address ]; + :local TimeOut ($IPv6Addresses->$Branch->$Address); + :if ([ :typeof $TimeOut ] = "time") do={ + $LogPrintVerbose debug $ScriptName ("Renewing IPv6 address " . $Address . \ + " in list '" . $FwListName . "' with " . $TimeOut . "."); + /ipv6/firewall/address-list/set $Entry timeout=$TimeOut; + :set ($IPv6Addresses->$Branch->$Address); :set CntRenew ($CntRenew + 1); } else={ :if ($Failure = false) do={ - $LogPrint debug $ScriptName ("Removing IPv6 address from list '" . $FwListName . \ - "': " . $Address); + $LogPrintVerbose debug $ScriptName ("Removing IPv6 address " . $Address . \ + " from list '" . $FwListName ."."); /ipv6/firewall/address-list/remove $Entry; :set CntRemove ($CntRemove + 1); } } } - :foreach Address,Timeout in=$IPv4Addresses do={ - $LogPrint debug $ScriptName ("Adding IPv4 address to list '" . $FwListName . \ - "' with " . $Timeout . ": " . $Address); - :do { - /ip/firewall/address-list/add list=$FwListName comment=$ListComment \ - address=$Address timeout=$Timeout; - :set ($IPv4Addresses->$Address); - :set CntAdd ($CntAdd + 1); - } on-error={ - $LogPrint warning $ScriptName ("Failed to add IPv4 address to list '" . $FwListName . \ - "': " . $Address); + :foreach BranchName,Branch in=$IPv4Addresses do={ + $LogPrintVerbose debug $ScriptName ("Handling branch: " . $BranchName); + :foreach Address,Timeout in=$Branch do={ + $LogPrintVerbose debug $ScriptName ("Adding IPv4 address " . $Address . \ + " to list '" . $FwListName . "' with " . $Timeout . "."); + :onerror Err { + /ip/firewall/address-list/add list=$FwListName comment=$ListComment \ + address=$Address timeout=$Timeout; + :set CntAdd ($CntAdd + 1); + } do={ + $LogPrint warning $ScriptName ("Failed to add IPv4 address " . $Address . \ + " to list '" . $FwListName . "': " . $Err); + } } } - :foreach Address,Timeout in=$IPv6Addresses do={ - $LogPrint debug $ScriptName ("Adding IPv6 address to list '" . $FwListName . \ - "' with " . $Timeout . ": " . $Address); - :do { - /ipv6/firewall/address-list/add list=$FwListName comment=$ListComment \ - address=$Address timeout=$Timeout; - :set ($IPv6Addresses->$Address); - :set CntAdd ($CntAdd + 1); - } on-error={ - $LogPrint warning $ScriptName ("Failed to add IPv6 address to list '" . $FwListName . \ - "': " . $Address); + :foreach BranchName,Branch in=$IPv6Addresses do={ + $LogPrintVerbose debug $ScriptName ("Handling branch: " . $BranchName); + :foreach Address,Timeout in=$Branch do={ + $LogPrintVerbose debug $ScriptName ("Adding IPv6 address " . $Address . \ + " to list '" . $FwListName . "' with " . $Timeout . "."); + :onerror Err { + /ipv6/firewall/address-list/add list=$FwListName comment=$ListComment \ + address=$Address timeout=$Timeout; + :set CntAdd ($CntAdd + 1); + } do={ + $LogPrint warning $ScriptName ("Failed to add IPv6 address " . $Address . \ + " to list '" . $FwListName . "': " . $Err); + } } } @@ -180,4 +215,6 @@ " - renewed: " . [ $HumanReadableNum $CntRenew 1000 ] . \ " - removed: " . [ $HumanReadableNum $CntRemove 1000 ]); } -} on-error={ } +} do={ + :global ExitError; $ExitError $ExitOK [ :jobname ] $Err; +} |