Community discussions

MikroTik App
 
nickjail
just joined
Topic Author
Posts: 15
Joined: Mon Feb 17, 2014 9:26 pm

Black list for failed login to IPSec VPN

Sat May 11, 2019 12:40 am

Hello!
Got a VPN Server on my router. Of course periodically someone tries to knock on it and I get tons of email messages before I add IP to block list.
I don't want to close ports. I want to make script that adds failed IPs to block list.

This command shows negotiation failed IPs
/log print where message~"negotiation"
This is what it shows (I've removed some digits from IP for not showing real IP):

apr/15 03:50:37 ipsec,error 216.xx.206.6 phase1 negotiation failed.
apr/16 03:31:44 ipsec,error 216.xx.206.118 phase1 negotiation failed.
apr/17 05:33:29 ipsec,error 216.xx.206.102 phase1 negotiation failed.
may/08 14:30:13 ipsec,error 122.xx.64.43 phase1 negotiation failed.
may/08 14:30:13 ipsec,error 122.xx.64.43 phase1 negotiation failed

Does anyone knows how to make script based on command above that parse log and adds IP to IP list?
Any information how alternatively secure IPSec would be useful.
Thanks.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Sat May 11, 2019 11:29 am

Edit updated here: viewtopic.php?p=905420#p905420


Here you go

Create a script with name Find_IPSEC that is used to find all lines with negotiation failed last 5m, extract the IP and add it to a access list.
Find_IPSEC
# Created Jotne 2019 v1.1
#
# This script add ip of user who failed IPSEC negotiation to a block list for 30 day
# Schedule the script to run every 5 min
# It should run on all routerOS version

# Find all "negotiation failed" error last 5 min
:local loglist [:toarray [/log find  time>([/system clock get time] - 5m) message~"negotiation failed"]]

# for all error do
:foreach i in=$loglist do={

# find message
	:local logMessage [/log get $i message]
# find ip
	:local ip [:pick $logMessage 0 [:find $logMessage " "]]

# Add ip to accesslist	
	/ip firewall address-list add address=$ip list=IPSEC timeout=30d
# Send a message to the log	
	:log info message="script=IPSEC_failed src_ip=$ip"
	}
	
Create a scheduler that do run the script Find_IPSEC every 5 min:
/system scheduler add interval=5m name="Find IPSEC" on-event=Find_IPSEC
Then add an access list high in your filter rules like this (change ether1 with your outside IP):
/ip firewall filter add action=drop chain=forward comment="Block wrong IPSEC" in-interface=ether1 src-address-list=IPSEC
You can change the timeout=24h to set it how long you will block all IP, or remove it to permanently block all IP
Last edited by Jotne on Fri Jan 14, 2022 8:02 am, edited 1 time in total.
 
plisken
Forum Guru
Forum Guru
Posts: 2509
Joined: Sun May 15, 2011 12:24 am
Location: Belgium
Contact:

Re: Black list for failed login to IPSec VPN

Sun Jul 28, 2019 7:58 pm

Very interesting application. I will definitely use this script. Thanks
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Thu Aug 08, 2019 8:03 pm

Edit: Updated see this post viewtopic.php?p=905420#p905420

Updated
Now also block user with these type of message:
SPI e14750001eda995ec not registred for 89.50.40.10[4500]

# Created Jotne 2019 v1.3
#
# This script add ip of user who with "IPSEC negotiation failed" and "SPI* not registered" to a block list for 24hour
# Schedule the script to run every 5 min
# It should run on all routerOS version
# 1.3 added "Invalid exchange"


# Find all "negotiation failed" error last 5 min
:local loglistN [:toarray [/log find  time>([/system clock get time] - 5m) message~"negotiation failed"]]

# for all error do
:foreach i in=$loglistN do={

# find message
	:local logMessageN [/log get $i message]
# find ip
	:local ipN [:pick $logMessageN 0 [:find $logMessageN " "]]

# Add ip to accesslist	
	/ip firewall address-list add address=$ipN list=IPSEC timeout=30d
# Send a message to the log	
	:log info message="script=IPSEC_failed src_ip=$ipN why=negotiation_failed"
	}

	

# Find all "SPI* not registered"" error last 5 min
:local loglistS [:toarray [/log find  time>([/system clock get time] - 5m) message~"SPI.*not regist"]]

# for all error do
:foreach j in=$loglistS do={

# find message
	:local logMessageS [/log get $j message]
# find ip
	:local ipS [:pick $logMessageS ([:find $logMessageS "for "]+4) [:find $logMessageS "["]]

# Add ip to accesslist	
	/ip firewall address-list add address=$ipS list=IPSEC timeout=30d
# Send a message to the log	
	:log info message="script=IPSEC_failed src_ip=$ipS why=SPI_not_registered"
	}
	
  
# Find all "Invalid exchange" error last 5 min
:local loglistS [:toarray [/log find  time>([/system clock get time] - 5m) message~"Invalid exchange"]]

# for all error do
:foreach j in=$loglistS do={

# find message
	:local logMessageS [/log get $j message]
# find ip
	:local ipS [:pick $logMessageS ([:find $logMessageS "for "]+4) [:find $logMessageS "["]]

# Add ip to accesslist	
	/ip firewall address-list add address=$ipS list=IPSEC timeout=7d
# Send a message to the log	
	:log info message="script=IPSEC_failed src_ip=$ipS why=SPI_not_registered"
	}
	 
	
Last edited by Jotne on Fri Jan 14, 2022 8:02 am, edited 2 times in total.
 
iamdc
just joined
Posts: 1
Joined: Mon Aug 19, 2019 7:35 am

Re: Black list for failed login to IPSec VPN

Mon Aug 19, 2019 7:39 am

181.209.165.10 parsing packet failed, possible cause: wrong password
181.209.165.10 parsing packet failed, possible cause: wrong password
181.209.165.10 parsing packet failed, possible cause: wrong password
181.209.165.10 parsing packet failed, possible cause: wrong password
181.209.165.10 parsing packet failed, possible cause: wrong password
181.209.165.10 parsing packet failed, possible cause: wrong password
181.209.165.10 parsing packet failed, possible cause: wrong password
phase1 negotiation failed due to time up xx.xx.xx.xx[4500]<=>181.209.165.10[4500]
run script is
script=IPSEC_failed src_ip=phase1 why=negotiation failed

can
# Find all "negotiation failed due to time up" error last 60 min
:local loglistTimeout [:toarray [/log find  time>([/system clock get time] - 60m) message~"phase1 negotiation failed due to time up"]]

# for all error do
:foreach i in=$loglistTimeout do={

# find message
	:local logMessageTimeout [/log get $i message]
# find ip
                :local ip1 [:pick $logMessageTimeout [:find $logMessageTimeout ">"] [:len $logMessageTimeout]]
                :local ipTimeout [:pick $ip1 1 [:find $ip1 "["] ]
# Add ip to accesslist	
	/ip firewall address-list add address=$ipTimeout list=IPSEC_failed timeout=245d
# Send a message to the log	
	:log info message="script=IPSEC_failed src_ip=$ipTimeout why=negotiation_failed due to time up"
	}
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Mon Aug 19, 2019 10:09 am

I see that you have used 60 minutes.
The you also have to schedule the script to run 60 min , not 5 min as I have used as standard.
If not you will get double logging and IP will be added multiple times.
 
brg3466
Member Candidate
Member Candidate
Posts: 177
Joined: Sat Aug 01, 2015 7:29 am

Re: Black list for failed login to IPSec VPN

Tue May 18, 2021 9:10 pm

@Jotne,
I would like to use your script. But may I know how to set up the system clock so that [/log find time>([/system clock get time] - 60m) message~"xxx"] works. I found it only works with GMT 0 time. My setup is below, and script doesn't work since afternoon local time ( in GMT 0 , it is tomorrow) because the log pr will produce "mmm/dd/yyyy" in front of time:
[brg3466@MikroTik] > /system clock pr
                  time: 11:03:45
                  date: may/18/2021
  time-zone-autodetect: yes
        time-zone-name: America/Los_Angeles
            gmt-offset: -07:00
            dst-active: yes
            
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Tue May 18, 2021 10:00 pm

Methods like [/system clock get time] - 5m (I see often on forum...) is wrong at any timezone,
for example 00:01:00 - 5 min do -23:56:00 and no log have negative time

previous year:
may/17/2020 10:47:30 system,info,account user admin logged out from 100.80.8.1 via winbox
may/17/2020 10:49:30 system,info,account user admin logged out from 100.80.8.1 via winbox
yesterday:
may/17 10:49:43 system,info,account user admin logged in from 100.80.8.1 via winbox
may/17 13:05:12 system,info,account user admin logged out from 100.80.8.1 via winbox
may/17 13:05:25 system,info,account user admin logged in from 100.80.8.1 via winbox
today:
08:18:40 system,info,account user admin logged out from 100.80.8.1 via winbox
08:18:51 system,info,account user admin logged in from 100.80.8.1 via winbox
08:18:54 system,info,account user admin logged out from 100.80.8.1 via winbox

Also on another thread of sometime ago, differencies between three time format used in LOG are coming out.
MikroTik have done the wrong choice to use "friendly" time format... MUST BE ful date & time in log, everytime.
And MUST use international date and time format as ISO standard: 2021-05-18 21:08:00
Last edited by rextended on Tue May 18, 2021 10:16 pm, edited 1 time in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Tue May 18, 2021 10:10 pm

>>> If not you will get double logging and IP will be added multiple times. <<<
It's impossible to add same identical IP adress to same address-list
the script on that case throw an error and exit if the IP are finded twice
also on right interval, without add subsequent IP on logs

Before add, must be check if already are present.
 
brg3466
Member Candidate
Member Candidate
Posts: 177
Joined: Sat Aug 01, 2015 7:29 am

Re: Black list for failed login to IPSec VPN

Tue May 18, 2021 10:28 pm

I agree. With 3 formats of time, it is very confusing. Better to have just one uniform format.

Back to the topic, how to get the past, say, 10minutes log if we don't use Jotne's script ?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Tue May 18, 2021 10:43 pm

Do not worry to use any time interval, parse all logs, the script prevent double-set IP on address list than cause interruption for error on duplicate entry.

This script do not prevent the lock of your own remote IP if some error happen meantime.
Remember to create the whitelist of yours IPs and add permit rule before the blocking rule!

Revised script:
# Revised from Rextended v1.2.rex
#
# Created Jotne 2019 v1.2
#
# This script add ip of user who with "phase1 negotiation failed" and "SPI .* not registered for" to a block list for 7 days
# Schedule the script to run every 5 min
# It should run on all routerOS version - Rex test it on 6.47.9

# example:
# 1.2.3.4 phase1 negotiation failed.
# SPI 4f23346ef367ea12 not registered for 1.2.3.4[4500]

:local logMessage ""
:local logIp 10.6.6.6

/log

:foreach i in=[find where message~"phase1 negotiation failed" or message~"SPI .* not registered for"] do={

    :set logMessage [get $i message]

    :if ($logMessage~"phase1 negotiation failed") do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC_failed add $logIp because negotiation failed"
        }
    }

    :if ($logMessage~"SPI .* not registered for") do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC_failed add $logIp because SPI not registered"
        }
    }

}
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Tue May 18, 2021 11:41 pm

Mikrotik write this about time log format:
You can store the logs remotely in a Syslog server, and there choose format that you like most.
I do use Syslog and Splunk

There has been several request to MT to use propper time log format like ISO8601
 
User avatar
diamuxin
Member
Member
Posts: 317
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: Black list for failed login to IPSec VPN

Mon Jan 03, 2022 10:44 pm

Updated
Now also block user with these type of message:
SPI e14750001eda995ec not registred for 89.50.40.10[4500]
Hello!

How to find the IP in this message? (second IP 27.115...)
phase1 negotiation failed due to time up 89.131.7.88[500]<=>27.115.124.74[30992] 0011223344556677:b59120571b9a18c2
:local ipS [:pick $logMessageS ([:find $logMessageS ">"]+1) ([:find $logMessageS "["]-1)]   ==> it does not work
Thanks!
 
User avatar
own3r1138
Long time Member
Long time Member
Posts: 680
Joined: Sun Feb 14, 2021 12:33 am
Location: Pleiades
Contact:

Re: Black list for failed login to IPSec VPN

Mon Jan 03, 2022 11:38 pm

I'm wondering if I can use the same concept for web fig logs.
After lets encrypt certificate enabled I get a few web fig login per day:(
login failure for user MikroTikSystem from 45.130.99.94 via web
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Tue Jan 04, 2022 7:42 am

:local ipS [:pick $logMessageS ([:find $logMessageS ">"]+1) ([:find $logMessageS "["]-1)] ==> it does not work
You are close. Problem is the second find, it does find the first [ (before 500), not the second [ (before 30992) that you need.

This works:
{
:local test "phase1 negotiation failed due to time up 89.131.7.88[500]<=>27.115.124.74[30992] 0011223344556677:b59120571b9a18c2"
:local temp [:pick $test ([:find $test ">"]+1) 999] 
:put [:pick $temp 0 [:find $temp "["]] 
}
It gets the IP and the rest of the line in the first pick. Then second pick gets all until [.

All in one ugly long line (better to split it up)
:local ipS [:pick [:pick $logMessageS ([:find $logMessageS ">"]+1) [:len $logMessageS]] 0 [:find [:pick $logMessageS ([:find $logMessageS ">"]+1) [:len $logMessageS]] "["]] 
 
User avatar
diamuxin
Member
Member
Posts: 317
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: Black list for failed login to IPSec VPN

Tue Jan 04, 2022 11:42 am

:local ipS [:pick $logMessageS ([:find $logMessageS ">"]+1) ([:find $logMessageS "["]-1)] ==> it does not work
You are close. Problem is the second find, it does find the first [ (before 500), not the second [ (before 30992) that you need.

This works:
{
:local test "phase1 negotiation failed due to time up 89.131.7.88[500]<=>27.115.124.74[30992] 0011223344556677:b59120571b9a18c2"
:local temp [:pick $test ([:find $test ">"]+1) 999] 
:put [:pick $temp 0 [:find $temp "["]] 
}
It gets the IP and the rest of the line in the first pick. Then second pick gets all until [.

All in one ugly long line (better to split it up)
:local ipS [:pick [:pick $logMessageS ([:find $logMessageS ">"]+1) [:len $logMessageS]] 0 [:find [:pick $logMessageS ([:find $logMessageS ">"]+1) [:len $logMessageS]] "["]] 
Thank you very much for the help!
BR.
 
User avatar
inteq
Member
Member
Posts: 402
Joined: Wed Feb 25, 2015 8:15 pm
Location: Romania

Re: Black list for failed login to IPSec VPN

Thu Jan 13, 2022 1:38 pm

Do not worry to use any time interval, parse all logs, the script prevent double-set IP on address list than cause interruption for error on duplicate entry.

This script do not prevent the lock of your own remote IP if some error happen meantime.
Remember to create the whitelist of yours IPs and add permit rule before the blocking rule!

Revised script:
# Revised from Rextended v1.2.rex
#
# Created Jotne 2019 v1.2
#
# This script add ip of user who with "phase1 negotiation failed" and "SPI .* not registered for" to a block list for 7 days
# Schedule the script to run every 5 min
# It should run on all routerOS version - Rex test it on 6.47.9

# example:
# 1.2.3.4 phase1 negotiation failed.
# SPI 4f23346ef367ea12 not registered for 1.2.3.4[4500]

:local logMessage ""
:local logIp 10.6.6.6

/log

:foreach i in=[find where message~"phase1 negotiation failed" or message~"SPI .* not registered for"] do={

    :set logMessage [get $i message]

    :if ($logMessage~"phase1 negotiation failed") do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC_failed add $logIp because negotiation failed"
        }
    }

    :if ($logMessage~"SPI .* not registered for") do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC_failed add $logIp because SPI not registered"
        }
    }

}
Was looking for such a script for a long time.
Trying to implement it on a router getting lots of "negotiation failed" but I have an issue.
The offending IP is added to IPSEC list, but it also adds 0.0.0.0 to the same list for some reason.
Any clue as to why? Nothing in log showing 0.0.0.0
ipsec.png
Thank you.
You do not have the required permissions to view the files attached to this post.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Thu Jan 13, 2022 2:32 pm

There is an 1.3 in this thread as well. Test it out. (Do not remember what was changed from 1.2 to 1.3)
 
User avatar
diamuxin
Member
Member
Posts: 317
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: Black list for failed login to IPSec VPN

Thu Jan 13, 2022 2:55 pm

Do not worry to use any time interval, parse all logs, the script prevent double-set IP on address list than cause interruption for error on duplicate entry.

This script do not prevent the lock of your own remote IP if some error happen meantime.
Remember to create the whitelist of yours IPs and add permit rule before the blocking rule!

Revised script:
# Revised from Rextended v1.2.rex
#
# Created Jotne 2019 v1.2
#
# This script add ip of user who with "phase1 negotiation failed" and "SPI .* not registered for" to a block list for 7 days
# Schedule the script to run every 5 min
# It should run on all routerOS version - Rex test it on 6.47.9

# example:
# 1.2.3.4 phase1 negotiation failed.
# SPI 4f23346ef367ea12 not registered for 1.2.3.4[4500]

:local logMessage ""
:local logIp 10.6.6.6

/log

:foreach i in=[find where message~"phase1 negotiation failed" or message~"SPI .* not registered for"] do={

    :set logMessage [get $i message]

    :if ($logMessage~"phase1 negotiation failed") do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC_failed add $logIp because negotiation failed"
        }
    }

    :if ($logMessage~"SPI .* not registered for") do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC_failed add $logIp because SPI not registered"
        }
    }

}
Was looking for such a script for a long time.
Trying to implement it on a router getting lots of "negotiation failed" but I have an issue.
The offending IP is added to IPSEC list, but it also adds 0.0.0.0 to the same list for some reason.
Any clue as to why? Nothing in log showing 0.0.0.0
ipsec.png

Thank you.
The same thing happened to me doing tests. I think that when it cannot get the IP correctly it adds an IP of type 0.0.0.0.

It is important that the error messages in the log are correctly filtered to obtain an IP. Use ": toip"

This is my script that I run every hour, for now it works great for me.
:local logMessage ""
:local logIp ""
:local message1 " phase1 negotiation failed."
:local message2 "phase1 negotiation failed due to time up "
:local message3 "first L2TP UDP "

/log

:foreach i in=[find where message~$message1 or message~$message2 or message~$message3 ] do={

    :set logMessage [get $i message]

    :if ($logMessage~$message1) do={
        :set logIp [:toip [:pick $logMessage 0 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC failed: add $logIp because negotiation failed"
        }
    }

    :if ($logMessage~$message2) do={
        :set logIp [:toip [:pick [:pick $logMessage ([:find $logMessage ">"]+1) [:len $logMessage]] 0 [:find [:pick $logMessage ([:find $logMessage ">"]+1) [:len $logMessage]] "["]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC failed: add $logIp because negotiation failed due to time up"
        }
    }

    :if ($logMessage~$message3) do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "from"]+5) [:len $logMessage]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="L2TP failed: first UDP packet received from $logIp. Added to blacklist"
        }
    }

}
Luck!
BR.
 
User avatar
inteq
Member
Member
Posts: 402
Joined: Wed Feb 25, 2015 8:15 pm
Location: Romania

Re: Black list for failed login to IPSec VPN

Thu Jan 13, 2022 3:19 pm



Was looking for such a script for a long time.
Trying to implement it on a router getting lots of "negotiation failed" but I have an issue.
The offending IP is added to IPSEC list, but it also adds 0.0.0.0 to the same list for some reason.
Any clue as to why? Nothing in log showing 0.0.0.0
ipsec.png

Thank you.
The same thing happened to me doing tests. I think that when it cannot get the IP correctly it adds an IP of type 0.0.0.0.

It is important that the error messages in the log are correctly filtered to obtain an IP. Use ": toip"

This is my script that I run every hour, for now it works great for me.
:local logMessage ""
:local logIp ""
:local message1 " phase1 negotiation failed."
:local message2 "phase1 negotiation failed due to time up "
:local message3 "first L2TP UDP "

/log

:foreach i in=[find where message~$message1 or message~$message2 or message~$message3 ] do={

    :set logMessage [get $i message]

    :if ($logMessage~$message1) do={
        :set logIp [:toip [:pick $logMessage 0 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC failed: add $logIp because negotiation failed"
        }
    }

    :if ($logMessage~$message2) do={
        :set logIp [:toip [:pick [:pick $logMessage ([:find $logMessage ">"]+1) [:len $logMessage]] 0 [:find [:pick $logMessage ([:find $logMessage ">"]+1) [:len $logMessage]] "["]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="IPSEC failed: add $logIp because negotiation failed due to time up"
        }
    }

    :if ($logMessage~$message3) do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "from"]+5) [:len $logMessage]]]
        :if ([:len [/ip fire addr find where address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="L2TP failed: first UDP packet received from $logIp. Added to blacklist"
        }
    }

}
Luck!
BR.
Thank you for the code.
The problem is:
first L2TP UDP packet received from
is a valid and normal message on a successful connection.
Your script adds valid IPs to the list.
valid.png
You do not have the required permissions to view the files attached to this post.
 
User avatar
inteq
Member
Member
Posts: 402
Joined: Wed Feb 25, 2015 8:15 pm
Location: Romania

Re: Black list for failed login to IPSec VPN

Thu Jan 13, 2022 3:24 pm

There is an 1.3 in this thread as well. Test it out. (Do not remember what was changed from 1.2 to 1.3)
Missed the 1.3 one. Will test now.
Thank you.
 
User avatar
diamuxin
Member
Member
Posts: 317
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: Black list for failed login to IPSec VPN

Thu Jan 13, 2022 4:14 pm

In my case, I have this message that goes to nothing. For me it works.
first L2TP UDP packet received from 154.88.26.233
the script is very configurable.

BR.
 
User avatar
inteq
Member
Member
Posts: 402
Joined: Wed Feb 25, 2015 8:15 pm
Location: Romania

Re: Black list for failed login to IPSec VPN

Fri Jan 14, 2022 5:01 am

There is an 1.3 in this thread as well. Test it out. (Do not remember what was changed from 1.2 to 1.3)
Tested the 1.3 version a bit and found some problems.
err.png
I guess the script was not supposed to add phase1 to the list, right?
You do not have the required permissions to view the files attached to this post.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Fri Jan 14, 2022 7:36 am

Error found.
Here is some data from the log:
64.62.197.52 phase1 negotiation failed.
64.62.197.217 phase1 negotiation failed.
65.49.20.109 phase1 negotiation failed.
phase1 negotiation failed due to time up 92.200.200.100[500]<=>27.115.124.10[48536] 0011223344556677:5c5c77ed781bf459
phase1 negotiation failed due to time up 92.200.200.100[500]<=>27.115.124.9[64696] 0011223344556677:53c620c089b6028e
65.49.20.124 phase1 negotiation failed.
94.206.221.159 phase1 negotiation failed.
94.206.221.159 phase1 negotiation failed.
Lines with "phase1 negotiation failed" is not equal and some lines do not contain IP at start.
So solution is to add a dot at the end of search term to ignore those lines
negotiation failed.

Script updated and based on rextendeds version. Simpler with just one loop.
Also added test for access list name to see if IP is in IPSEC access list. (it may be in multiple lists)
# Created Jotne && rextended 2022 v1.4
#
# This script add ip of user who with "IPSEC negotiation failed", "SPI* not registered" and "Invalid exchange" to a block list for 7 days
# Schedule the script to run every 5 min
# It should run on all routerOS version
# 1.3 added "Invalid exchange"
# 1.4 added dot behind "negotiation failed" to get only lines with IP
# 1.4 made all inn to one loop, based on idea by rextended

:local logMessage ""
:local logIp ""
/log
:foreach i in=[find where message~"phase1 negotiation failed\\." or message~"SPI.*not regist" or message~"Invalid exchange"] do={
    :set logMessage [get $i message]

    :if ($logMessage~"phase1 negotiation failed\\.") do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="script=IPSEC_failed src_ip=$logIp why=negotiation_failed"
        }
    }

    :if ($logMessage~"SPI .* not registered for") do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
			:log info message="script=IPSEC_failed src_ip=$logIp why=SPI_not_registered"
        }
    }

    :if ($logMessage~"Invalid exchange") do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
			:log info message="script=IPSEC_failed src_ip=$logIp why=Invalid_exchange"
        }
    }
} 
 
User avatar
own3r1138
Long time Member
Long time Member
Posts: 680
Joined: Sun Feb 14, 2021 12:33 am
Location: Pleiades
Contact:

Re: Black list for failed login to IPSec VPN

Fri Jan 14, 2022 10:23 am

Hello,
Thank you for the 1.4 <3
 
User avatar
inteq
Member
Member
Posts: 402
Joined: Wed Feb 25, 2015 8:15 pm
Location: Romania

Re: Black list for failed login to IPSec VPN

Fri Jan 14, 2022 10:28 am

Thank you Jotne
 
User avatar
diamuxin
Member
Member
Posts: 317
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: Black list for failed login to IPSec VPN

Fri Jan 14, 2022 11:31 am

:foreach i in=[find where message~"phase1 negotiation failed\\." or message~"SPI.*not regist" or message~"Invalid exchange"] 
Thanks for the new version of the script!
What does the double backslash before the point mean?
message~"phase1 negotiation failed\\."
BR.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Fri Jan 14, 2022 11:43 am

Its to make dot a dot and not just any character. (see regex info)
I RouterOS you need to double escape.
 
mmee
just joined
Posts: 8
Joined: Sat Aug 28, 2021 8:30 am
Location: Estonia

Re: Black list for failed login to IPSec VPN

Wed Jan 19, 2022 11:31 am

Thanks Jotne for this script.
"Invalid exchange " section does not work for me, it adds 0.0.0.0 to the address-list instead of the IP in the message.
I would like to parse this kind of message:
10:59:24 ipsec Invalid exchange type 243 from 185.xxx.142.172[500].

Maybe word "for" should be changed to "from" in line 33 ?
:set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Wed Jan 19, 2022 1:44 pm

You are 100% correct. Here is a fixed version.
Thanks :)
# Created Jotne && rextended 2022 v1.5
#
# This script add ip of user who with "IPSEC negotiation failed", "SPI* not registered" and "Invalid exchange" to a block list for 7 days
# Schedule the script to run every 5 min
# It should run on all routerOS version
# 1.3 added "Invalid exchange"
# 1.4 added dot behind "negotiation failed" to get only lines with IP
# 1.4 made all inn to one loop, based on idea by rextended
# 1.5 Fixed typo

:local logMessage ""
:local logIp ""
/log
:foreach i in=[find where message~"phase1 negotiation failed\\." or message~"SPI.*not regist" or message~"Invalid exchange"] do={
    :set logMessage [get $i message]

    :if ($logMessage~"phase1 negotiation failed\\.") do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="script=IPSEC_failed src_ip=$logIp why=negotiation_failed"
        }
    }

    :if ($logMessage~"SPI .* not registered for") do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
			:log info message="script=IPSEC_failed src_ip=$logIp why=SPI_not_registered"
        }
    }

    :if ($logMessage~"Invalid exchange") do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "from "]+5) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
			:log info message="script=IPSEC_failed src_ip=$logIp why=Invalid_exchange"
        }
    }
}
 
User avatar
own3r1138
Long time Member
Long time Member
Posts: 680
Joined: Sun Feb 14, 2021 12:33 am
Location: Pleiades
Contact:

Re: Black list for failed login to IPSec VPN

Wed Jan 19, 2022 1:52 pm

Is this 1.5? so it is :d
Thank you for the update.
@Jotne
What should be the policy for this script? read and write?
I see 2 times in the script +4 and +5. Both should be +5 or the +4 left out by mistake from 1.4v.
2022-01-19_15-54-39.png
You do not have the required permissions to view the files attached to this post.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Wed Jan 19, 2022 3:25 pm

Updated to 1.5 so its easy to see what is the latest :)

+4 and +5 is correct. If you look at how the pick works, you will see it gives the position on the first found letter.
from 8.8.8.8
x1234567890
for 8.8.8.8
x1234567890
So for the "from", you need to add 5 to get the first part of 8.8.8.8
and in the "for", it 4 characters to 8.8.8.8

SIP uses "for" in log message and
Invalid exchange uses "from".
 
User avatar
own3r1138
Long time Member
Long time Member
Posts: 680
Joined: Sun Feb 14, 2021 12:33 am
Location: Pleiades
Contact:

Re: Black list for failed login to IPSec VPN

Wed Jan 19, 2022 3:31 pm

Thank you for the A,
Honestly even you clearly explained this to me I still can't understand it as I don't know shit about coding. I wanted to set scheduler and I read that it must be the same as the script I just wanted to check this with you.
 
User avatar
diamuxin
Member
Member
Posts: 317
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: Black list for failed login to IPSec VPN

Sat Jan 22, 2022 2:56 pm

Its to make dot a dot and not just any character. (see regex info)
I RouterOS you need to double escape.
Hi @Jotne!

Is it possible for your script to export the IP addresses to the IPSEC list in cidr format?

That is to say:
64.128.34.17 --> 64.128.34.0/24

So that it blocks the entire subnet.

Thanks & BR.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Sat Jan 22, 2022 9:55 pm

Here is how you can convert the IP. Since there are no easy way to find last dot, I need to find all and count.
It may be a faster way
{
:local ip "64.128.34.17"
:local A1 [:find $ip "."]
:local A2 [:find $ip ($A1+1)]
:local A3 [:find $ip "." ($A2+1)]
:local new ([:pick $ip 0 $A3].".0/24")
:put $new
}
64.128.34.0/24

Or all in one ugly line:
{
:local ip "64.128.34.17"
:local new ([:pick $ip 0 [:find $ip "." ([:find $ip ([:find $ip "."]+1)]+1)]].".0/24")
:put $new
}
 
User avatar
rushlife
Member Candidate
Member Candidate
Posts: 243
Joined: Thu Nov 05, 2015 12:30 pm

Re: Black list for failed login to IPSec VPN

Thu Jun 23, 2022 2:25 pm

Hi guys, some edit for L2TP and login with wrong password ?
 
User avatar
BrateloSlava
Member Candidate
Member Candidate
Posts: 167
Joined: Mon Aug 09, 2021 10:33 am
Location: Ukraine, Kharkiv

Re: Black list for failed login to IPSec VPN

Mon Aug 08, 2022 4:35 pm

Is it possible to modify the script by adding a check, that the blocked IP address is not in the exclusion list?

There are several trusted routers, that are interconnected via IPIP(EOIP)+IpSec. Periodically, a situation arises, when the connections between these routers are interrupted and the process of reconnection begins. Sometimes the connection is not restored the first time and an error appears in the log. The script finds this error and blocks the IP address for 7 days. If the script is not run, then such "problem" connections are normally restored after a certain period of time.
 
User avatar
BrateloSlava
Member Candidate
Member Candidate
Posts: 167
Joined: Mon Aug 09, 2021 10:33 am
Location: Ukraine, Kharkiv

Re: Black list for failed login to IPSec VPN

Thu Aug 25, 2022 6:50 pm

Is it possible to modify the script by adding a check, that the blocked IP address is not in the exclusion list?
I will answer myself. It is enough to slightly change this line:
:if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
To this:
:if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1 and [:len [/ip fire addr find where list=Allow_ALL address=$logIp]] < 1) do={
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Thu Aug 25, 2022 7:14 pm

Here is how you can convert the IP.
Since there are no easy way to find last dot, I need to find all and count.

[…]

It may be a faster way

[…]
Yes...

Various examples:
{
:local stip 64.128.34.17
:put "$([:toip $stip] & 255.255.255.240)/28"
:put "$([:toip $stip] & 255.255.255.0)/24"
:put "$([:toip $stip] & 255.255.0.0)/16"
:put "$([:toip $stip] & 255.0.0.0)/8"
}

output

terminal code

[rex@tended] > {
{... :local stip 64.128.34.17
{... :put "$([:toip $stip] & 255.255.255.240)/28"
{... :put "$([:toip $stip] & 255.255.255.0)/24"
{... :put "$([:toip $stip] & 255.255.0.0)/16"
{... :put "$([:toip $stip] & 255.0.0.0)/8"
{... }
64.128.34.16/28
64.128.34.0/24
64.128.0.0/16
64.0.0.0/8

This is the simpliest way:
{
:local stip 64.128.34.17
:put "$(($stip >>8)<<8)/24"
}
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3279
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Black list for failed login to IPSec VPN

Thu Aug 25, 2022 9:41 pm

@rextended My script knowledge are not at the same level as you. I guess it never will be :D
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Fri Aug 26, 2022 10:38 am

For sure, for one thing I know more than you, you certainly know another thing more than me... :o
 
User avatar
diamuxin
Member
Member
Posts: 317
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: Black list for failed login to IPSec VPN

Fri Aug 26, 2022 2:06 pm

Duel of titans :D

Thank you both for teaching us so many useful things.

BR.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Fri Aug 26, 2022 4:04 pm

Added some functions here, can be useful:
viewtopic.php?p=953746#p953746
 
User avatar
own3r1138
Long time Member
Long time Member
Posts: 680
Joined: Sun Feb 14, 2021 12:33 am
Location: Pleiades
Contact:

Re: Black list for failed login to IPSec VPN

Mon Sep 05, 2022 9:52 pm

Could you guys include OVPN failed login into this Script, please? I tried to replicate it from your Script. However, I was not able to. Added IP is 0.0.0.0 at the created address list.
Thank you :d.
TLS Error: unknown opcode received (1)
<64.62.197.21>: disconnected <bad packet received>
ovpn-1.jpg
ovpn-2.jpg
You do not have the required permissions to view the files attached to this post.
 
ANTONBORODA
just joined
Posts: 8
Joined: Mon Nov 15, 2021 9:26 am

Re: Black list for failed login to IPSec VPN

Thu Mar 16, 2023 6:51 pm

I have another script to share:
# Created by Anton BORODA Borodyuk 2023
#
# This script adds users who end up with "parsing packet failed, possible cause: wrong password" message during
# VPN connection more then $maxTryCount times to the $listName for 7 days,
# This should be a good riddance for VPN password guessers.
#
# Losely based on Jotne && rextended 2022 v1.5 script.

:local listName "IPSEC"
:local maxTryCount 21;

:local offenders ({})

/log
:foreach i in=[find where message~"possible cause: wrong password"] do={
    :local logMessage [get $i message]

    :local ipString [:pick $logMessage 0 [:find $logMessage " "]]

    :if ($offenders->$ipString != nil) do={
        :set ($offenders->$ipString) ([:tonum ($offenders->$ipString)] + 1)
    } else={
        :set ($offenders->$ipString) 1
    }
}
:foreach key,value in=$offenders do {
    :local tryCount [:tonum ($value)]
    :if ($tryCount > $maxTryCount) do={
        :local logIp [:toip $key]
        :if ([:len [/ip fire addr find where list=$listName address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=$listName timeout=7d
            :log info message="script=IPSEC_failed src_ip=$logIp why=Password guesser"
        }
    }
}
This works a little differently.
I had a lot of false-positives with the scripts above, so I modified this to include only actual failed password attempts.
This counts the number of incorrect password messages and if it's more than 21 (iOS client retries 7 times before throwing an "unable to connect message", so it's giving a user 3 attempts in total), the user is added to the list.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Thu Mar 16, 2023 11:56 pm

Do not use ({}) for define empty array, the correct way is :local arrayvar [:toarray ""]
I myself used that method once suggested by another user, but it backfired because, although I don't quite remember now how,
it had unwanted effects that backfired on me in programming.
IT SEEMS to work, then it messes up...

Missing a space between do and {
:foreach key,value in=$offenders do {

The script is wrong on this line:
:if ($offenders->$ipString != nil) do={
You can not compare one array field with the string "nil".
Nil is not a reserved word usable for compare something on this way.
Nil is just a string, you can write anything, and for just a coincidence work.
Instead the "nothing" keyword exist, but you can not compare two nothing or two nil....

examples code

:global test [:toarray ""]
:global isnil  [:pick "" 0 1]
:global notnil ":)"

:put [:typeof $test]
:put [:typeof $isnil]
:put [:typeof $notnil]

:if ($isnil  != nil) do={:put "not nil"} else={:put "is nil"}
:if ($notnil != nil) do={:put "not nil"} else={:put "is nil"}

:if ($test->$isnil  != nil) do={:put "not nil"} else={:put "is nil"}
:if ($test->$notnil != nil) do={:put "not nil"} else={:put "is nil"}

:set ($test->$isnil) "is-nil"
:set ($test->$notnil) "not-nil"

:put [:typeof $test]
:put [:typeof $isnil]
:put [:typeof $notnil]

:if ($test->$isnil  != nil) do={:put "not nil"} else={:put "is nil"}
:if ($test->$notnil != nil) do={:put "not nil"} else={:put "is nil"}

:put [:typeof ($test->$isnil)]
:put [:typeof ($test->$notnil)]

:if ($test->$isnil  != anystring) do={:put "not nil"} else={:put "is nil"}
:if ($test->$notnil != anystring) do={:put "not nil"} else={:put "is nil"}

:if (($test->$isnil)  != [:nothing]) do={:put "not nothing"} else={:put "is nothing"}
:if (($test->$notnil) != [:nothing]) do={:put "not nothing"} else={:put "is nothing"}

The correct way is with ( ) and use :typeof, and is nothing the undefined "nil" on array:
:if ([:typeof ($offenders->$ipString)] != "nothing") do={

fixed and revised code

# Created by Anton BORODA Borodyuk 2023
# v1.0.r
# fixed and revised by rextended
#
# This script adds users who end up with "parsing packet failed, possible cause: wrong password" message during
# VPN connection more then $maxTryCount times to the $listName for 7 days,
# This should be a good riddance for VPN password guessers.
#
# Losely based on Jotne && rextended 2022 v1.5 script.

:local listName    "IPSEC"
:local maxTryCount 21
:local offenders   [:toarray ""]

/log
:foreach i in=[find where message~"possible cause: wrong password"] do={
    :local logMessage [get $i message]
    :local ipString   [:pick $logMessage 0 [:find $logMessage " "]]

    :if ([:typeof ($offenders->$ipString)] = "nothing") do={
        :set ($offenders->$ipString) 1
    } else={
        :set ($offenders->$ipString) (($offenders->$ipString) + 1)
    }
}
/ip firewall address-list
:foreach key,value in=$offenders do={
    :local tryCount [:tonum ($value)]
    :if ($tryCount > $maxTryCount) do={
        :local logIp [:toip $key]
        :if ([:len [find where list=$listName and address=$logIp]] < 1) do={
            add address=$logIp list=$listName timeout=7d
            :log info "script=IPSEC_failed src_ip=$logIp why=Password guesser"
        }
    }
}
 
User avatar
pkt
just joined
Posts: 14
Joined: Tue Jan 24, 2023 10:12 pm
Location: /u/mw/ss/e/eu/es

Re: Black list for failed login to IPSec VPN

Tue Mar 21, 2023 12:48 am

Do not use ({}) for define empty array, the correct way is :local arrayvar [:toarray ""]
I myself used that method once suggested by another user, but it backfired because, although I don't quite remember now how,
it had unwanted effects that backfired on me in programming.
IT SEEMS to work, then it messes up...

Testing in Ros 6.49.7 some scripts (written using functions stored as array members), I have found that using ({}) to initialize a variable (even local) with an empty array, sometimes doesn't clear it and persists the value assigned in the previous execution of the function, so if each execution adds 3 items to the (in theory) empty array, the first execution will return 3 items, the second will duplicate it and return 6 items, the third will return 9, ...

Those scripts worked well in Ros 7.7, so it seems that some script bugs where solved in v7.

I now use exclusively [:toarray ""]
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Tue Mar 21, 2023 1:52 am

Thanks, I do not remember precisely why, but I remember that updating one array defined with ({}) cause later a mess with other arrays defined on same way...
 
User avatar
anav
Forum Guru
Forum Guru
Posts: 18959
Joined: Sun Feb 18, 2018 11:28 pm
Location: Nova Scotia, Canada
Contact:

Re: Black list for failed login to IPSec VPN

Tue Mar 21, 2023 2:01 am

My script!

add chain=input action=drop
add chain=forward action=drop

That was easy.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Tue Mar 21, 2023 2:50 am

You forget to add first the admin access :lol: :lol: :lol:
 
ANTONBORODA
just joined
Posts: 8
Joined: Mon Nov 15, 2021 9:26 am

Re: Black list for failed login to IPSec VPN

Mon Mar 27, 2023 10:56 am

Do not use ({}) for define empty array, the correct way is :local arrayvar [:toarray ""]
I myself used that method once suggested by another user, but it backfired because, although I don't quite remember now how,
it had unwanted effects that backfired on me in programming.
IT SEEMS to work, then it messes up...

Missing a space between do and {
:foreach key,value in=$offenders do {

The script is wrong on this line:
:if ($offenders->$ipString != nil) do={
You can not compare one array field with the string "nil".
Nil is not a reserved word usable for compare something on this way.
Nil is just a string, you can write anything, and for just a coincidence work.
Instead the "nothing" keyword exist, but you can not compare two nothing or two nil....

examples code

:global test [:toarray ""]
:global isnil  [:pick "" 0 1]
:global notnil ":)"

:put [:typeof $test]
:put [:typeof $isnil]
:put [:typeof $notnil]

:if ($isnil  != nil) do={:put "not nil"} else={:put "is nil"}
:if ($notnil != nil) do={:put "not nil"} else={:put "is nil"}

:if ($test->$isnil  != nil) do={:put "not nil"} else={:put "is nil"}
:if ($test->$notnil != nil) do={:put "not nil"} else={:put "is nil"}

:set ($test->$isnil) "is-nil"
:set ($test->$notnil) "not-nil"

:put [:typeof $test]
:put [:typeof $isnil]
:put [:typeof $notnil]

:if ($test->$isnil  != nil) do={:put "not nil"} else={:put "is nil"}
:if ($test->$notnil != nil) do={:put "not nil"} else={:put "is nil"}

:put [:typeof ($test->$isnil)]
:put [:typeof ($test->$notnil)]

:if ($test->$isnil  != anystring) do={:put "not nil"} else={:put "is nil"}
:if ($test->$notnil != anystring) do={:put "not nil"} else={:put "is nil"}

:if (($test->$isnil)  != [:nothing]) do={:put "not nothing"} else={:put "is nothing"}
:if (($test->$notnil) != [:nothing]) do={:put "not nothing"} else={:put "is nothing"}

The correct way is with ( ) and use :typeof, and is nothing the undefined "nil" on array:
:if ([:typeof ($offenders->$ipString)] != "nothing") do={

fixed and revised code

# Created by Anton BORODA Borodyuk 2023
# v1.0.r
# fixed and revised by rextended
#
# This script adds users who end up with "parsing packet failed, possible cause: wrong password" message during
# VPN connection more then $maxTryCount times to the $listName for 7 days,
# This should be a good riddance for VPN password guessers.
#
# Losely based on Jotne && rextended 2022 v1.5 script.

:local listName    "IPSEC"
:local maxTryCount 21
:local offenders   [:toarray ""]

/log
:foreach i in=[find where message~"possible cause: wrong password"] do={
    :local logMessage [get $i message]
    :local ipString   [:pick $logMessage 0 [:find $logMessage " "]]

    :if ([:typeof ($offenders->$ipString)] = "nothing") do={
        :set ($offenders->$ipString) 1
    } else={
        :set ($offenders->$ipString) (($offenders->$ipString) + 1)
    }
}
/ip firewall address-list
:foreach key,value in=$offenders do={
    :local tryCount [:tonum ($value)]
    :if ($tryCount > $maxTryCount) do={
        :local logIp [:toip $key]
        :if ([:len [find where list=$listName and address=$logIp]] < 1) do={
            add address=$logIp list=$listName timeout=7d
            :log info "script=IPSEC_failed src_ip=$logIp why=Password guesser"
        }
    }
}
Thanks for all the improvements and corrections.

I'm far from good in writing mikrotik scripts tbh, so the corrections are most welcome.
 
lcguille
just joined
Posts: 3
Joined: Wed May 03, 2023 4:00 pm

Re: Black list for failed login to IPSec VPN

Wed May 03, 2023 4:05 pm

Hello, I modified the code but I have problems with "phase1 negotiation failed\\."
# Created Jotne && rextended 2022 v1.5
#
# This script add ip of user who with "IPSEC negotiation failed", "SPI* not registered" and "Invalid exchange" to a block list for 7 days
# Schedule the script to run every 5 min
# It should run on all routerOS version
# 1.3 added "Invalid exchange"
# 1.4 added dot behind "negotiation failed" to get only lines with IP
# 1.4 made all inn to one loop, based on idea by rextended
# 1.5 Fixed typo

:local logMessage ""
:local logIp ""
:local cont1 0
:local cont2 0
:local cont3 0
/log

:foreach i in=[find where message~"phase1 negotiation failed\\." or message~"SPI.*not regist" or message~"Invalid exchange"] do={
    :set logMessage [get $i message]

    :if ($logMessage~"phase1 negotiation failed\\.") do={
        :set $cont1 ($cont1 + 1)
        }
    :if ($logMessage~"SPI.*not regist") do={
        :set $cont2 ($cont2 + 1)
        }
    :if ($logMessage~"Invalid exchange") do={
        :set $cont3 ($cont3 + 1)
        }


    :if (($logMessage~"phase1 negotiation failed\\.") && ($cont1 > 2)) do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
            :log info message="Script=IPSEC - src_ip=$logIp Motivo=negotiation_failed"
        }
    }

    :if (($logMessage~"SPI .* not registered for") && ($cont2 > 2)) do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "for "]+4) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
	:log info message="Script=IPSEC - src_ip=$logIp Motivo=SPI.*not regist"
        }
    }
#:log info message="ipsec changed script settings by gleguizamon."
    :if (($logMessage~"Invalid exchange") && ($cont3 > 2)) do={
        :set logIp [:toip [:pick $logMessage ([:find $logMessage "from "]+5) [:find $logMessage "["]]]
        :if ([:len [/ip fire addr find where list=IPSEC address=$logIp]] < 1) do={
            /ip fire addr add address=$logIp list=IPSEC timeout=7d
	:log info message="Script=IPSEC - src_ip=$logIp Motivo=Invalid exchange"
               
        }
    }
}
 
mdadigital
newbie
Posts: 34
Joined: Tue Feb 21, 2023 7:48 pm

Re: Black list for failed login to IPSec VPN

Fri May 05, 2023 11:07 am

Here is my variant that also reports abuse
:local listName "portscanner"
:local logMessage ""
:local logIp ""
/log
:foreach i in=[find where message~"phase1 negotiation failed\\." or message~"phase1 negotiation failed due to time up "] do={
    :set logMessage [get $i message]

    :if ($logMessage~"phase1 negotiation failed\\.") do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]       
    }   

    :if ($logMessage~"phase1 negotiation failed due to time up ") do={
       :local temp [:pick $logMessage ([:find $logMessage ">"]+1) 999] 
       :set logIp [:pick $temp 0 [:find $temp "["]] 
    }   


   :if ([:len [/ip fire addr find where list=$listName address=$logIp]] < 1) do={   
      /ip fire addr add address=$logIp list=$listName timeout=7d

     
      :local data "ip=$logIp&comment=Port%20scanning&categories=14%2C15"
      :local result ([/tool fetch mode=https url="https://api.abuseipdb.com/api/v2/report" http-method=post http-data=$data http-header-field="key: [API_KEY],Accept: application/json,Content-Type: application/x-www-form-urlencoded" as-value output=user])
   }
}
 
lcguille
just joined
Posts: 3
Joined: Wed May 03, 2023 4:00 pm

Re: Black list for failed login to IPSec VPN

Thu May 11, 2023 4:44 am

Hello,
this line dont work
can you help me pls.

         :local temp [:pick $logMessage ([:find $logMessage ">"]+1) 999] 
     
 
mdadigital
newbie
Posts: 34
Joined: Tue Feb 21, 2023 7:48 pm

Re: Black list for failed login to IPSec VPN

Thu May 11, 2023 10:48 pm

I added this so that it only looks at todays logs. Otherwise it will report old logs after timeout period. I use the fact that todays logs only have time not date
:if ([:len [get $i time]] = 8 and [:len [/ip fire addr find where list=$listName address=$logIp]] < 1) do={   
 
holvoetn
Forum Guru
Forum Guru
Posts: 5317
Joined: Tue Apr 13, 2021 2:14 am
Location: Belgium

Re: Black list for failed login to IPSec VPN

Thu May 11, 2023 11:03 pm

Be advised, that assumption might become wrong.
It looks like they are moving towards standardized date/time formatting.
See latest change log on 7.10b5.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Black list for failed login to IPSec VPN

Thu May 11, 2023 11:06 pm

The time format alone is not changed,
this still valid until do not fix the "friendly" time on logs.
 
mdadigital
newbie
Posts: 34
Joined: Tue Feb 21, 2023 7:48 pm

Re: Black list for failed login to IPSec VPN

Thu May 11, 2023 11:13 pm

its a shame mikrotik log doesnt have a proper datetime data type
 
lcguille
just joined
Posts: 3
Joined: Wed May 03, 2023 4:00 pm

Re: Black list for failed login to IPSec VPN

Fri May 12, 2023 12:30 am

i have 6.48.6
Be advised, that assumption might become wrong.
It looks like they are moving towards standardized date/time formatting.
See latest change log on 7.10b5.
 
mdadigital
newbie
Posts: 34
Joined: Tue Feb 21, 2023 7:48 pm

Re: Black list for failed login to IPSec VPN

Fri May 12, 2023 10:02 am

i have 6.48.6
Be advised, that assumption might become wrong.
It looks like they are moving towards standardized date/time formatting.
See latest change log on 7.10b5.
My code you are trying to execute on your router was written on 7.8 - 7.9
 
mdadigital
newbie
Posts: 34
Joined: Tue Feb 21, 2023 7:48 pm

Re: Black list for failed login to IPSec VPN

Mon Feb 19, 2024 1:49 pm

I was locked out from my own VPN when a timeout occurred on a bad connection. I added this that checks if the IP have had a ISAKMP-SA established
    :if ($logMessage~"ISAKMP-SA established") do={
        :local temp [:pick $logMessage ([:find $logMessage "]-"] + 2) 999]
        :set whitelist [:pick $temp 0 [:find $temp "["]]       
    }
For this to work you need itterate over all log messages
/log
:foreach i in=[find] do={
Full script
:local listName "portscanner"
:local logMessage ""
:local lastLogMessage ""
:local whitelist "noop"
:local logIp ""
/log
:foreach i in=[find] do={
    :set logMessage [get $i message]

    :if ($logMessage~"ISAKMP-SA established") do={
        :local temp [:pick $logMessage ([:find $logMessage "]-"] + 2) 999]
        :set whitelist [:pick $temp 0 [:find $temp "["]]       
    }

    :if ($logMessage~"phase1 negotiation failed\\.") do={
        :set logIp [:toip [:pick $logMessage -1 [:find $logMessage " "]]]        
    }    

    :if ($logMessage~"phase1 negotiation failed due to time up " and ([:find $logMessage "[500]"]>0 or [:find $lastLogMessage "parsing packet failed"]>0)) do={
       :local temp [:pick $logMessage ([:find $logMessage ">"]+1) 999] 
       :set logIp [:toip [:pick $temp 0 [:find $temp "["]]]
    }    

   :if ([:len $logIp]  != 0 and $logIp != $whitelist) do={
      :if ([:len [get $i time]] = 8 and [:len [/ip fire addr find where list=$listName address=$logIp]] < 1) do={   
         /ip fire addr add address=$logIp list=$listName timeout=7d

      
         :local data "ip=$logIp&comment=Port%20scanning&categories=14%2C15"
         :local result ([/tool fetch mode=https url="https://api.abuseipdb.com/api/v2/report" http-method=post http-data=$data http-header-field="key: <keygoeshere>,Accept: application/json,Content-Type: application/x-www-form-urlencoded" as-value output=user])
      }
   }

   :set lastLogMessage $logMessage
   :set logIp ""
}

Who is online

Users browsing this forum: wirelesslywired and 14 guests