-
-
Save uablacklist/b0e73deb75f2a1c43f035c59e5401e8c to your computer and use it in GitHub Desktop.
:local apiPrefix "https://uablacklist.net/subnets_mikrotik_" | |
:local tempFile "uablacklist.txt" | |
:local listName "uablacklist" | |
/log info "removing existing '$listName'..." | |
:put "removing existing '$listName'..." | |
/ip firewall address-list remove [/ip firewall address-list find list=$listName] | |
# mikrotik can't load >4KB file inside a variable, so backend contains file pieces which we download and parse one by one | |
:local i 0 | |
:local isEnd false | |
:do { | |
:local apiPath "$apiPrefix$i.txt" | |
/log info "fetching UA blacklist registry piece ($apiPath)..." | |
:put "fetching UA blacklist registry piece ($apiPath)..." | |
:local contentLen 0 | |
:local content "" | |
:do { | |
/tool fetch url=$apiPath dst-path=$tempFile | |
:set content [/file get [/file find name=$tempFile] contents] | |
:set contentLen [:len $content] | |
} on-error={ | |
/log info "no more pieces"; | |
:put "no more pieces" | |
:set isEnd true | |
} | |
:local lineEnd 0 | |
:local line "" | |
:local lastEnd 0 | |
:local company "" | |
:while ($lastEnd < $contentLen) do { | |
:set lineEnd [:find $content "\n" $lastEnd ] | |
:set line [:pick $content $lastEnd $lineEnd] | |
:set lastEnd ($lineEnd+1) | |
:local entry [:pick $line 0 ($lineEnd-1)] | |
:if ([:pick $line 0 1] != "#") do={ | |
:if ([:len $entry ] > 0) do={ | |
/log info "add '$entry' subnet of '$company' to list '$listName'..."; | |
:put "add '$entry' subnet of '$company' to list '$listName'..."; | |
:do { | |
/ip firewall address-list add list=$listName address=$entry comment=$company | |
} on-error={ | |
/log info "failed to add '$entry' subnet of '$company' to list '$listName', probably, it's duplication error."; | |
:put "failed to add '$entry' subnet of '$company' to list '$listName', probably, it's duplication error." | |
} | |
} | |
} else={ | |
:set company [:pick $line 2 ($lineEnd) ] | |
} | |
} | |
:set i (i+1) | |
} while (!$isEnd) |
Сейчас периодически бывает недоступна закачка с uablacklist.net а скрипт при запуске первым делом удаляет те листы, что уже есть, что естественно лишает возможности обхода.
Если это возможно, будет отлично с начала проверять начало закачки, а лишь после удалять маршруты.
На форуме микротика хорошее обсуждение с методами закачки листов.
Из плюсов то, что не используется диск самого роутера, что продлевает его жизнь, а так же есть методы контроля наличия достпуности url (в конце треда) и вторая методика замены адресов в виде таймаутов для листов.
В общем сам допилил.
-
Скрипт не задействует хранилище микротика, чем продлевает его жизнь.
-
Работает практически моментально по сравнению с оригиналом.
-
Скрипт теперь универсальный и кушает практически любые листы.
-
Изменен немного принцип действия.
Теперь лист создается с таймаутом в сутки, а я советую запускать его раз в 6-12 часов для обновления таймаутов и добавления новых записей.
Сам код:
{
/ip firewall address-list
:local update do={
:put "Starting import of address-list: $listname"
:if ($nolog = null) do={:log warning "Starting import of address-list: $listname"}
:local displayed true
:local maxretry 3
:local retrywaitingtime 120s
:local retryflag true
:for retry from=1 to=$maxretry step=1 do={
:if (retryflag) do={ :set $retryflag false; :set $sounter 0
:if (retry > 1) do={
:put "Source file changed. Retring after a $retrywaitingtime wait..."
:if ($nolog = null) do={:log warning "Source file changed. Retring after a $retrywaitingtime wait..."}
:delay $retrywaitingtime }
:local fetchResult [/tool fetch url=$url keep-result=no as-value]
:local filesize ($fetchResult->"total")
:local downsize ($fetchResult->"downloaded")
:if ($filesize = 0 && $downsize > 0) do={ :set $filesize $downsize}
:local start 0
:local maxsize 64000; # reqeusted chunk size
:local end ($maxsize - 1); # because start is zero the maxsize has to be reduced by one
:local partnumber ($filesize / ($maxsize / 1024)); # how many chunk are maxsize
:local remainder ($filesize % ($maxsize / 1024)); # the last partly chunk
:if ($remainder > 0) do={ :set $partnumber ($partnumber + 1) }; # total number of chunks
:if ($heirule != null) do={:put "Using as extra filtering: $heirule"} else={:set $heirule "."}
# remove the current list completely if "erase" is not present (default setting)
:if ($noerase = null) do={
:if ($timeout = null) do={:set $timeout 00:00:00; :do {:foreach i in=[/ip firewall address-list find list=$listname] do={/ip firewall address-list set list=("backup".$listname) $i }} on-error={} } else={
:do {:foreach i in=[/ip firewall address-list find list=$listname dynamic] do={/ip firewall address-list set list=("backup".$listname) $i }} on-error={} };
:put ("Conditional deleting all".$dynamic." entries in address-list: $listname")
:if ($nolog = null) do={:log warning ("Conditional deleting all".$dynamic." entries in address-list: $listname")}
} else={:put "Entries not conditional deleted in address-list: $listname"}; # ENDIF ERASE
:for x from=1 to=$partnumber step=1 do={
# get filesize to be compared to the orignal one and if changed then retry
:local comparesize ([/tool fetch url=$url keep-result=no as-value]->"total")
:if ($comparesize = 0 && $downsize > 0) do={ :set $comparesize $downsize}
# fetching the chunks from the webserver when the size of the source file has not changed
# empty array when the source file changed. No processing is done till the next complete retry
:if ($comparesize = $filesize) do={:set $data ([:tool fetch url=$url http-header-field="Range: bytes=$start-$end" output=user as-value]->"data")} else={:set $data [:toarray ""]; :set $retryflag true}
#:if ($ownposix = null) do={
# determining the used delimiter in the list, when not provided in the config
# this only run once and so the impact on the import time is low
:local ipv4Posix "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"
:local ipv4rangePosix "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/[0-9]{1,2}"
:local domainPosix "^.+\\.[a-z.]{2,7}"
:local sdata $data;
# removes any lines at the top of the file that could interfere with finding the correct posix. Setting remarksign is needed
:while ([:pick $sdata 0 1] = $remarksign) do={ :set $sdata [:pick $sdata ([:find $sdata "\n"]+1) [:len $sdata]] }
:while ([:len $sdata]!=0 && $delimiter = null) do={ # The check on length of $sdata is for if no delimiter is found.
:local sline [:pick $sdata 0 [:find $sdata "\n"]]; :local slen [:len $sline];
# set posix depending of type of data used in the list
:if ($sline ~ $ipv4Posix) do={:set $posix $ipv4Posix; :set $iden "List identified as a IPv4 list"}
:if ($sline ~ $ipv4rangePosix) do={:set $posix $ipv4rangePosix; :set $iden "List identified as a IPv4 with ranges list"}
:if ($sline ~ $domainPosix) do={:set $posix $domainPosix; :set $iden "List identified as a domain list"}
:if ($sline ~ $posix) do={:put $iden}
:if ($sline ~ $posix) do={ # only explore the line if there is a match at the start of the line.
:do {:if ([:pick $sline 0 ($slen-$send)] ~ ($posix."\$") || $send > $slen) do={
:set $delimiter [:pick $sline ($slen-$send) ($slen-($send-1))]; :set $result true} else={:set $send ($send+1)}
:if ($result) do={ :set $extra [:pick $sline ($slen-$send) ($slen-($send-1))]
:if ( $extra = " " ) do={ :set $delimiter [:pick $sline ($slen-$send) ($slen-($send-2))] }
:if ( $extra = " " ) do={ :set $delimiter [:pick $sline ($slen-$send) ($slen-($send-3))] }
:if ( $extra = " " ) do={ :set $delimiter [:pick $sline ($slen-$send) ($slen-($send-4))] }
}; # EndIf result
} while (!$result); # EndDoWhile
}; #IF sline posix
:set $sdata [:pick $sdata ([:find $sdata "\n"]+1) [:len $sdata]]; # cut off the already searched lines
:if ($delimiter != null) do={:local sdata [:toarray ""]} ; #Clearing sdata array ending the WhileDo loop
}; #WHILE END $sdata
:local sdata [:toarray ""]
:if ([:len $delimiter] = 0) do={ :set $delimiter "\n"; :set $delimiterShow "New Line" } else={ :set $delimiterShow $delimiter }; # when empty use NewLine 20220529
#} else={:put "User defind Posix: $ownposix"; :set $posix $ownposix } ; # ENDIF ownposix = null
:if ($delimiter != null && $displayed ) do={:set $displayed false; :put "Using config provided delimiter: \"$delimiterShow\""}
:if ($posix = null) do={:set $posix "."}; # Use a match all posix if nothing is defined or found
:if (!retryflag) do={:put "Reading Part: $x $start - $end"}
:if ($timeout = null) do={:local timeout 00:00:00}; # if no timeout is defined make it a static entry.
# Only remove the first line only if you are not at the start of list
:while ( [:pick $data 0 1] = $remarksign) do={ :set $data [:pick $data ([:find $data "\n"]+1) [:len $data]] }; # removes the invalid line (Spamhaus)
:if ($start > 0) do={:set $data [:pick $data ([:find $data "\n"]+1) [:len $data]]}
:while ([:len $data]!=0) do={
:local line [:pick $data 0 [:find $data "\n"]]; # create only once and checked twice as local variable
:if ( $line ~ $posix && $line~heirule) do={
:do {add list=$listname address=[:pick $data 0 [:find $data $delimiter]] comment=$comment timeout=$timeout; :set $counter ($counter + 1)} on-error={}; # on error avoids any panics
}; # if IP address && extra filter if present
:set $data [:pick $data ([:find $data "\n"]+1) [:len $data]]; # removes the just added IP from the data array
# Cut of the end of the chunks by removing the last lines...very dirty but it works
:if ([:len $data] < 256) do={:set $data [:toarray ""]}
}; # while
:set $start (($start-512) + $maxsize); # shifts the subquential start back by 512
:set $end (($end-512) + $maxsize); # shift the subquential ends back by 512 to keep the
}; # if retryflag
}; #do for x
}; # for retry
:if ($counter < 1) do={:set $resultline "Import was NOT successfull! Check if the list $listname is still being maintained."} else={:set $resultline "Completed reading $counter items into address-list $listname." }
:put $resultline
:if ($nolog = null) do={:log warning $resultline }
:if ($counter > 0) do={:do {/ip firewall address-list remove [find where list=("backup".$listname)]} on-error={} } else={
:do {:foreach i in=[/ip firewall address-list find list=("backup".$listname)] do={/ip firewall address-list set list=$listname $i }} on-error={}
:put "Restoring backup list: $listname"
:if ($nolog = null) do={:log warning "Restoring backup list: $listname"}
}; # if counter restore on failure and remove on success
}; # do
$update url=https://uablacklist.net/subnets.txt listname=uablacklist remarksign=";" timeout=1d nolog=1
}
# To be used configline settings:
# url= https://name.of.the.list
# listname= name of address-list
# Optinal settings
# timeout= the time the entry should be active. If omited then static entries are created.
# comment= puts this comment on every line in the choosen address-list (default: no comment)
# heirule= this will select on a word on each line if to import or not (default: no heirule)
# noerase= any value, then the current list is not erased (default: erase)
# ownPosix= allow to enter a onw regEX posix to be used (not ative at this moment)
# nolog= any value, then don't write to the log (default: writing to log)
@A-I-Demidov проверил оба скрипта:
первый скрипт, после запуска список не обновляется:
fetching UA blacklist registry piece (https://uablacklist.net/subnets_mikrotik_0.txt)...
removing existing 'uablacklist'...
started to loading
no more pieces
второй скрипт:
Starting import of address-list: uablacklist
я подозреваю что /tool fetch
выпадает с таймаутом, хотя открыть врчную адрес https://uablacklist.net/subnets.txt
я могу
Скрипт автора я уже не использую, хотя работать он должен.
В моей версии скрипта в логи ничего не пишется, он отрабатывает, практически моментально создавая address list в firewall.
Проверьте на всякий случай, а есть ли от вас вообще возможность его скачать, так как я видел где-то обсуждения, что сам https://uablacklist.net может блокировать провайдер и тогда надо скачивание пускать сразу через используемый вами VPN.
Как вариант могу предложить не использовать скрипт, а использовать BGP с помощью ребят с https://antifilter.network
У них основное предназначение это обход блокировок в РФ, но и наш лист они тоже подтянули, можно пользоваться или им или вообще пускать весь российский сегмент через VPN, с оглядкой что никто не балуется в сети не балуется с торрентами, а то можно забить канал.
P.S. Свой скрипт именно в этом варианте проверил, все работает.
P.P.S. Проверьте права у скрипта, все-таки он должен иметь возможность читать и записывать переменные.
Что случилоась с uablacklist.net не работает сайт, соответственно и скрипт...
Что происходит с uablacklist.net не работает сайт, соответственно и скрипт...
Сайт работает.
Возможно, у вашего провайдера он заблокирован, проверьте как разолвится его DNS имя и попробуйте перенаправить роутинг к нему сразу в VPN.
Но вообще рекомендую не список, а перейти на BGP https://antifilter.network/bgp
Как использовать сгенерированные списки: https://alexell.ru/blog/windows-internet/mikrotik-obhod-blokirovki-telegram.html.
Чтобы иметь постоянно актуальный список, добавьте запуск скрипта в
System - Scheduler
следующей командой:/system scheduler add name=sync_uablacklist interval=12:00:00 on-event="/system script run sync_uablacklist"