Community discussions

MikroTik App
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Add failed IPSec phase1 negotiation to AddrList

Mon Mar 22, 2021 7:39 pm

Hi all,
I was creating a script that looks in the memory log and if it finds an "ipsec,error" about failed phase1 negotiation adds the address to a blacklist.
In case someone else is interested, here is the script that I'm running on couple of routers.
The script is made by a function to search for duplicates addresses in the address-list and the main script itself.
The function is loaded as global variable and must be reloaded each time the router restarts.
# Function to search for duplicated IP in address-list
:global searchIPList do={
	:local listName $1
	:local ipAddr $2
	
	:if ([:len [/ip firewall address-list find list=$listName]] > 0) do={
		:foreach foundIP in=[/ip firewall address-list find list=$listName] do={
			:if ($ipAddr = ([:pick [/ip firewall address-list print as-value where .id=$foundIP] 0]->"address")) do={
				:return "duplicated"
			}
		}
	}
}


This is the main script that can be added to the router like any other script.
# Main script adds to blacklist addresses which failed IPSec phase1
:global searchIPList
:global myBlackListName "intruseBL"

:foreach i in=[/log find where (topics=ipsec,error && message~"phase1 negotiation failed")] do={
	:local iplength [:find [/log get value-name=message number=$i] " "]
	:if ([:typeof $iplength] = "num") do={
		:if ([:toip [:pick [/log get value-name=message number=$i] 0 $iplength]]~"^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}") do={
			:local intruseIP [:pick [/log get value-name=message number=$i] 0 $iplength]
			:if ([:len [/ip firewall address-list find list=$myBlackListName]] > 0) do={
				:if ([$searchIPList $myBlackListName $intruseIP] != "duplicated") do={ 
					/ip firewall address-list add list=$myBlackListName address=$intruseIP
				}
			} else={
				/ip firewall address-list add list=$myBlackListName address=$intruseIP
			}
		}
	}
}


Armando
Last edited by accarda on Tue Jan 04, 2022 9:32 am, edited 1 time in total.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3291
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Mar 22, 2021 10:40 pm

Just a tip that I do use.
If you do a port scan on a VPN server, it may show IPSec phase 1 error, since no correct data are give.

What I have done, is to have a access list that blocks all IP for 24 hours that tries any port on my router that are not open.
So if some do a port scan, they are blocked long time before it comes to IPSec ports. It will also be blocked for all open port as well, like Web server.
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Add failed IPSec phase1 negotiation to AddrList

Tue Mar 23, 2021 6:15 am

Hi @Jotne,
sure someone can apply different strategies to the firewall to achieve different results.
In my case I have forwarded to the router only those ports used by IPSec/IKEv2 and nothing else to internal hosts.

Anyway speaking of timers I have slightly modified the main script to allow a certain timeout for how long the "intruse" will stay quarantined in the blacklist.
So I have changed the main function to support this, like below.
:global searchIPList
:local myBlackListName "intruseBL"
# Set timerForJail to regular timeout or value=perpetual for permanent entry
:local timerForJail "perpetual"

:foreach i in=[/log find where (topics=ipsec,error && message~"phase1 negotiation failed")] do={
	:local iplength [:find [/log get value-name=message number=$i] " "]
	:if ([:typeof $iplength] = "num") do={
		:if ([:toip [:pick [/log get value-name=message number=$i] 0 $iplength]]~"^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}") do={
			:local intruseIP [:pick [/log get value-name=message number=$i] 0 $iplength]
			:if ([:len [/ip firewall address-list find list=$myBlackListName]] > 0) do={
				:if ([$searchIPList $myBlackListName $intruseIP] != "duplicated") do={
					:if ($timerForJail = "perpetual") do={
						/ip firewall address-list add list=$myBlackListName address=$intruseIP
					} else={
						/ip firewall address-list add list=$myBlackListName address=$intruseIP timeout=$timerForJail
					}
				}
			} else={
				:if ($timerForJail = "perpetual") do={
					/ip firewall address-list add list=$myBlackListName address=$intruseIP
				} else={
					/ip firewall address-list add list=$myBlackListName address=$intruseIP timeout=$timerForJail
				}
			}
		}
	}
}
So now variable $timerForJail can be set in 2 ways:
  • :local timerForJail "perpetual" to keep the entry permanently in the blackist
  • :local timerForJail "1d" to keep the entry only for 24H in the list and you can set such value to any regular timeout expression
I have also changed the scope of variables myBlackListName and timerForJail to be local as the script will be located inside the script's repository; however when testing this from a terminal you should change these variables to global, otherwise you will get errors.
So you can save couple of variables from being unnecessarily global.
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Sun Jan 02, 2022 6:18 pm

For some reason when using this script is working great when first execution. I found a new ip that tried to login ipsec vpn error, but it did not add it to the firewall list. After troubleshooting I deleted all the ip's on the firewall access list then ran the script again. That for some reason worked fine. I'm not sure if your duplicate address script is working. Let me know I am new to Mikrotik and really wanted to get this working. Thanks in advance.

@MikroTik] > /system script run intruseBL
failure: already have such entry
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 8:09 am

I have checked the function searchIPList with an address list and it worked in finding only duplicates.
Be aware that the function works only on IP addresses without CIDR notation.
So if you had any address with CIDR notation, the function would not give you the duplicate flag on exit.
I have tried on an empty list and it was able to add new addresses or avoid them if duplicates.

In order to avoid an arbitrary response on valid address, I was adding an output value of OK, otherwise if unset the function would have returned ;;; instead.
But this should not create any issue with the main script as it's looking for text "duplicated".
But on my installation I have updated the global function searchIPList with this additional output, even though it should not matter.

EDIT: don't use this code change as it stops the function to run for the entire address-list when it does not find a match. Stay with the original code.
:global searchIPList do={
	:local listName $1
	:local ipAddr $2
	
	:if ([:len [/ip firewall address-list find list=$listName]] > 0) do={
		:foreach foundIP in=[/ip firewall address-list find list=$listName] do={
			:if ($ipAddr = ([:pick [/ip firewall address-list print as-value where .id=$foundIP] 0]->"address")) do={
				return "duplicated"
			} else={
				return "OK"
			}
		}
	}
}
Last edited by accarda on Tue Jan 04, 2022 9:35 am, edited 1 time in total.
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 4:31 pm

Thank you accarda. So do I need to merge this script with the original master script or create a seperate script?
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 4:38 pm

Actually you can remove the global function searchIPList from your script -> environment menu in Winbox and load this new version instead.
But as I said it didn't change much other than setting an output value when there is not matching with the address in the list.
All the rest is the same.
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 6:12 pm

It's very strange it still does not add the new ip from my logs. Is this because I am running version 7.1.1?
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 7:53 pm

Not really sure as I have it in place on a router that it's still on v6.x.
However if there is anything not fully compatible with v7, it will be on the main script (not the function to search for duplicate IPs).
I have tested the searchIPList on ros v7.1.1 and it worked fine in finding a duplicate IP; but on that router I didn't have the full script to search with the log and add those failed attempts into the address list.
Not really sure whether in Ros v7.1.1 some of the code to get the IP from log has changed, but I wouldn't expect it.
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 9:27 pm

The below shows no outcome from command line. I deleted all the ip's in the access list firewall re ran the main script and it added the ip's fine. Something is weird like the searchIPList maybe not searching my the access list intruseBL or something. Does yours show output when running the searchIPList in command?

@MikroTik] > /system script run searchIPList
@MikroTik] >
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 11:36 pm

So I was researching the internet and found some users had success adding this line to their script. on-error={}. However, everytime I add it to the main script I get a line error. If we can integrate on-error={} to the main script I think it might work. Below is the example from another script.

:foreach i in=[/ip firewall address-list find ] do={
:if ( [/ip firewall address-list get $i comment] = "IPblacklist1" ) do={
:do {
/ip firewall address-list remove $i
} on-error={}
}
}

Thanks,
Taylor
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 11:43 pm

Actually searchIPList is a function (inside a global variable), therefore you can't call it like that.
From terminal you can call it with this :put [$searchIPList list IP] where list is your address-list name and the IP that you want to check.
So you run it by passing the 2 parameters needed for it to work.
The main script where this function is loaded can be executed from terminal in a similar way as you have indicated for searchIPList, but not the function itself.
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Mon Jan 03, 2022 11:58 pm

Okay I added my list name it shows up return as OK either if it is a duplicate or a new ip address. My firewall list name is same as your intruseBL.
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Tue Jan 04, 2022 12:55 am

Here's my output really weird should be showing as duplicate not ok.

[taylor@MikroTik] > /ip firewall address-list print
Columns: LIST, ADDRESS, CREATION-TIME
# LIST ADDRESS CREATION-TIME
0 intruseBL 74.82.47.21 jan/03/2022 10:13:03
1 intruseBL 65.49.20.106 jan/03/2022 10:13:03
2 intruseBL 64.62.197.78 jan/03/2022 10:13:03
3 intruseBL 74.82.47.27 jan/03/2022 10:13:03
4 intruseBL 184.105.247.195 jan/03/2022 10:13:03
5 intruseBL 184.105.247.227 jan/03/2022 10:13:03
6 intruseBL 184.105.247.219 jan/03/2022 10:13:03
7 intruseBL 184.105.139.68 jan/03/2022 10:13:03
8 intruseBL 216.218.206.85 jan/03/2022 10:13:03
9 intruseBL 64.62.197.146 jan/03/2022 10:13:03
[taylor@MikroTik] > :put [$searchIPList intruseBL 64.62.197.146]
OK
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Add failed IPSec phase1 negotiation to AddrList

Tue Jan 04, 2022 8:39 am

Hi Taylor,
please disregard the proposed change to the function searchIPList and stick with the original code (which I include again to avoid confusion).
:global searchIPList do={
	:local listName $1
	:local ipAddr $2
	
	:if ([:len [/ip firewall address-list find list=$listName]] > 0) do={
		:foreach foundIP in=[/ip firewall address-list find list=$listName] do={
			:if ($ipAddr = ([:pick [/ip firewall address-list print as-value where .id=$foundIP] 0]->"address")) do={
				:return "duplicated"
			}
		}
	}
}
As you can see I have removed again the OK message when the IP was not found.
That was my mistake because if you return that value, the function ends its job and stops analyzing the remaining elements.
It would have worked with a single entry address list, which was not the case.
So let's go back to the original function, which returns duplicated only when it founds a duplicate entry (that was the original intention).
If you test the function again you will see it will catch a duplicate; it will return ;;; when there is not match and the address is not in the list.

Then why you have got the initial issue is something to find out, but this rectifies the recent mistake.
Armando
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Tue Jan 04, 2022 4:34 pm

Hi accarda,

Many thanks to you and I believe it does work now. It's possible that the master script never created the script correctly in environment. Maybe we should add a master script to let everyone use this in the future. I search everywhere in the internet and this is the first one I believe this is solved. I will monitor and let you know tomorrow to see if it automatically adds, but from my test awhile ago it does it fine. I believe both of our troubleshooting fixed this long time issue =)...
 
accarda
Member Candidate
Member Candidate
Topic Author
Posts: 208
Joined: Fri Apr 05, 2019 4:06 pm
Location: Italy

Re: Add failed IPSec phase1 negotiation to AddrList

Tue Jan 04, 2022 5:51 pm

Thanks for confirming it worked for you as well.
Most likely the first time that you tried there was something not synched properly.
However the first part of this thread has both the main script and its function to work together and the code has not changed since then.
Script is supposed to be loaded and executed regularly from a scheduler, while the function must be a loaded global variable in the system.
Once the script runs, an additional global variable (lastTime) is created to keep last time that some IP has been added.
This is to avoid to add again and again from the same log portion, considering that by getting such log entry lines from memory, oldest info will get removed automatically after sometime.

Armando
 
Manth15
just joined
Posts: 9
Joined: Sun Jan 02, 2022 6:15 pm

Re: Add failed IPSec phase1 negotiation to AddrList

Tue Jan 04, 2022 6:51 pm

Yes that was my mistake and did not realize that I had to run two different scripts. I added it to scripts then ran both and it worked fine. I confirm it was the searchiplist script not being ran causing this issue, since when I look at the value there were none in environments. Thanks for all your hard work and helping me troubleshoot this issue.

Who is online

Users browsing this forum: onnyloh and 7 guests