![]() |
Mikrotik Router OS 7.17. Нужна помощь в написании скрипта.
Доброго времени суток.
Есть такая задача: Имеется Mikrotik на базе Router OS 7.17, нужен скрипт, который будет проверять не лог на предмет не верной авторизации (api, Winbox, ssh), брать ip адрес и добавлять его в Adress List. Используя ИИ (ChatGPT и DeepSeek) пробовал сгенерировать код (не силен в написании кодов), при каждом варианте лог сообщал Лог ошибки
executing script blockbruteforce from winbox failed, please check it manually
А вот сами варианты скрипта: ChatGPT_1
/system logging action add name=bruteforce target=memory
/system logging add topics=login action=bruteforce :global blocklist "bruteforceblock" /ip firewall address-list add list=$blocklist address=0.0.0.0 comment="Temporary list for brute-force attackers" :local maxAttempts 5 :local banTime 1d :while (true) do={ :local logEntries [/log find where topics~"login failure"] :foreach entry in=$logEntries do={ :local message [/log get $entry message] :if ([:find $message "via ssh" -1] != -1 || [:find $message "via winbox" -1] != -1 || [:find $message "via api" -1] != -1) do={ :local ip [:pick $message ([:find $message "from "]+5) [:find $message " via"]] :local count [/ip firewall address-list find where list=$blocklist && address=$ip] :if ([:len $count] = 0) do={ /ip firewall address-list add list=$blocklist address=$ip timeout=$banTime comment="Blocked due to brute-force" :log warning "Blocked IP $ip due to multiple failed SSH/Winbox/API login attempts." } } } :delay 10s } ChatGPT_2
/system logging action add name=bruteforce target=memory
/system logging add topics=login action=bruteforce :global blocklist "bruteforceblock" :local maxAttempts 5 :local banTime "1d" :while (true) do={ :local logEntries [/log find where topics~"critical"] :foreach entry in=$logEntries do={ :local message [/log get $entry message] :log info "Checking message: $message" :if ([:find $message "via ssh" -1] != -1 || [:find $message "via winbox" -1] != -1 || [:find $message "via api" -1] != -1) do={ :local ipStart ([:find $message "from "] + 5) :local ipEnd [:find $message " via"] :if ($ipEnd > 0) do={ :local ip [:pick $message $ipStart $ipEnd] :log info "Extracted IP: $ip" :local count [/ip firewall address-list find where list=$blocklist && address=$ip] :if ([:len $count] = 0) do={ /ip firewall address-list add list=$blocklist address=$ip timeout=$banTime comment="Blocked due to brute-force" :log warning "Blocked IP $ip due to multiple failed login attempts." } } else={ :log error "Failed to extract IP from message: $message" } } } :delay 10s } DeepSeek_1
{
:local blocklist "bruteforceblock" # Название списка блокировки :local maxAttempts 5 # Максимальное количество попыток :local banTime "1d" # Время блокировки :local failedIPs [:toarray {}] # Массив для хранения количества попыток :local logEntries [/log find where topics~"critical"] :foreach entry in=$logEntries do={ :local message [/log get $entry message] :log info "Checking message: $message" # Проверяем, связано ли сообщение с неудачной попыткой входа :if ([:find $message "login failure for user"] != nil) do={ :local ipStart ([:find $message "from "] + 5) :local ipEnd [:find $message " via"] :local ip [:pick $message $ipStart $ipEnd] :if ($ip != "") do={ :log info "Extracted IP: $ip" :local ipCount 1 # Проверяем, есть ли уже запись об этом IP в массиве :foreach ipEntry in=$failedIPs do={ :if ([:pick $ipEntry 0 [:find $ipEntry "="]] = $ip) do={ :set ipCount ([:pick $ipEntry ([:find $ipEntry "="] + 1) [:len $ipEntry]] + 1) :set $failedIPs [:tostr [:replace $failedIPs $ipEntry ($ip . "=" . $ipCount)]] } } # Если IP не найден в массиве, добавляем его :if ($ipCount = 1) do={ :set $failedIPs [:tostr [:merge $failedIPs [:toarray [$ip . "=" . $ipCount]]] } # Если попыток больше maxAttempts, блокируем IP :if ($ipCount >= $maxAttempts) do={ /ip firewall address-list add list=$blocklist address=$ip timeout=$banTime comment="Blocked due to brute-force" :log warning "Blocked IP $ip due to $ipCount failed login attempts." } } else={ :log error "Failed to extract IP from message: $message" } } } } DeepSeek_2
/system script add name=block_bruteforce source="
:local blockTime 1d # Время блокировки (например, 1 день) :local maxAttempts 3 # Количество неудачных попыток до блокировки :local addressList \"BruteForce_Block\" # Название списка блокировки :local failedIPs [:toarray {}] # Используем массив для хранения данных :foreach logEntry in=[/log find where topics~\"account,info\"] do={ :local logMsg [/log get \$logEntry message] # Проверяем, есть ли в сообщении 'login failure' :if ([:find \$logMsg \"login failure for user\"] != nil) do={ :local startIndex [:find \$logMsg \"from\"] :local failedIP [:pick \$logMsg (\$startIndex + 5) [:len \$logMsg]] # Проверяем, не в списке ли уже этот IP :if ([:len [/ip firewall address-list find where address=\$failedIP]] = 0) do={ :local ipCount 1 # Проверяем, есть ли уже запись об этом IP в массиве :foreach ipEntry in=\$failedIPs do={ :if ([:pick \$ipEntry 0 [:find \$ipEntry \"=\"]] = \$failedIP) do={ :set ipCount ([:pick \$ipEntry ([:find \$ipEntry \"=\"] + 1) [:len \$ipEntry]] + 1) :set \$failedIPs [:tostr [:replace \$failedIPs \$ipEntry (\$failedIP . \"=\" . \$ipCount)]] } } # Если IP не найден в массиве, добавляем его :if (\$ipCount = 1) do={ :set \$failedIPs [:tostr [:merge \$failedIPs [:toarray [\$failedIP . \"=\" . \$ipCount]]]] } # Если попыток больше maxAttempts, блокируем IP :if (\$ipCount >= \$maxAttempts) do={ /ip firewall address-list add list=\$addressList address=\$failedIP timeout=\$blockTime :log warning \"Blocked IP \$failedIP after \$ipCount failed login attempts!\" } } } }" Вариантов было намного больше, но я выложил крайние. Может кто нибудь поможет в данном вопросе? |
Цитата:
Закройте порты в наружи и подключайтесь к микроту по VPN или используйте port knocking и не занимайтесь бесполезной фигнёй. P.S. Буквально два правила port knocking решат Вашу проблему: Код:
/ip firewall filter |
а можно пояснить строки?
как понял, по какому-то листу разрешен вход, но где этот лист и почему срок разрешения час? или имелось в виду блокирование, а не разрешение? |
Цитата:
Второе правило разрешает доступ по портам 22,8291 на интерфейсы в списке WAN-list для адресов, находящихся в списке allow-ip. Предполагается, что доступ по умолчанию запрещён. Стоило также написать, что стучать в калитку в данном случае следует так: Код:
ping <mikrotik-ip-in-WAN-list> -l 95 -n 1 28 - размер заголовка. Цитата:
Методы стука тоже есть разные, Anton04 привёл самый простой для исполнения со стороны клиента - ping практически везде есть, а скажем nmap - не везде. |
Цитата:
И как сам будешь работать, если твой ип из списка удалится почти сразу? Или такой стук должен предворять каждую сессию, а в ходе открытой сессии уже неважно остальное? |
Цитата:
1. Нет. 2. Подключился и работай. 3. ping -n 2 -l 95 "IP или адрес узла". Развёрнуто: 1. Все зависит от того какие услуги Вам предоставляет Ваш провайдер, если не выдаёт "белые" IP, то в микроте зафиксируется IP конечного шлюза, если выдаёт белый статический IP адрес, то в микроте появится именно этот адрес. 2. Послали ICMP пакет определённой длинный, микрот принял пакет обработал и добавил адрес источника от куда он пришёл в белый список. далее вы подключаетесь в течении указанного в правиле времени и работаете, можете не закрывать Windows или ssh хоть сутками, т.к. время важно только для новых подключений. 3. Смотря что вы подразумеваете под "сессией", в сетях есть такое понятие время жизни соединения, т.е. время в течении которого соединение считается активным (т.е. рабочим). Если вы подразумеваете это, то если активна сессия, то запрос на открытие параллельной сессии считается нормальным. За это у Вас должно отвечать другое правило в самом верху, пример: Код:
/ip firewall filter |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Время: 21:29. |
Время: 21:29.
© OSzone.net 2001-