Код: Выделить всё
# protect from starting twice:
:local UniqueScriptID "QnJhdm8h"
:local ThisScriptName [/system script get ([find where source~"$UniqueScriptID"]->0) name]
:local AlreadyRunning "Script $ThisScriptName already running"
:if ([:len [/system script job find where script=$ThisScriptName]] > 1) do={:log error $AlreadyRunning; :error $AlreadyRunning}
# ping trigger settings
:local Pingcount 10
:local PingSucRate 80
:local Pingint 1000ms
:local PingTrigger ($Pingcount*$PingSucRate/100)
:local Pingresult
# :log info "PingTrigger is $PingTrigger"
# ping test 2 delay
:local PingTest2Delay 20s
# local Script variables
:local Time [/system clock get time]
:local Hour [:pick $Time 0 2]
:local phase2counter 0
:local CheckIPsec 0
:local Policies [/ip ipsec policy find active ph2-state=established ]
# local Peer variables
:local L2TPSession
:local L2TPPeer
:local L2TPDstadd
:local L2TPSrcadd
:local BadPeer
:local BadPeerDst
:local BadPeerSrc
# global variables
:global CheckIPsecBadPeerList
:global CheckIPsecClearBadPeerList
# clear <Check IPsec Bad Peer List>
if ($Hour > 23) do={
:global CheckIPsecBadPeerList [:toarray ""]
:log warning "Check IPsec: Bad Peer List is daily cleared"
}
# manual clear <Check IPsec Bad Peer List> >> just set <CheckIPsecClearBadPeerList> to any value
if ([:len $CheckIPsecClearBadPeerList] > 0) do={
:global CheckIPsecBadPeerList [:toarray ""]
:global CheckIPsecClearBadPeerList ""
:log warning "Check IPsec: Bad Peer List is manualy cleared"
}
# Show Check IPsec Bad Peer List
if ([:len $CheckIPsecBadPeerList] = 0) do={
:global CheckIPsecBadPeerList [:toarray ""]
} else={
foreach i in=$CheckIPsecBadPeerList do={
:log warning "Check IPsec: $i in Bad Peer List"
}
}
# if can't find IPSec Tunnel Peers
if ([:len $Policies] = 0) do={
:log info "Check IPsec: No IPsec Tunnel Peers is UP."
:set CheckIPsec 2
}
# start detect bad IPSec peers
if ([:len $Policies] > 0) do={
:foreach i in=$Policies do={
:local Dstadd ""
:local Srcadd ""
:local L2TPSession ""
:local L2TPPeer ""
:local L2TPDstadd ""
:local L2TPSrcadd ""
:local L2TPNetwork ""
:local Pingresult ""
:local BadPeer ""
:local BadPeerDst ""
:local BadPeerSrc ""
:local ActivePeersForKill ""
:local Peer [/ip ipsec policy get $i peer]
:local Dstadd [/ip ipsec policy get $i dst-address]
:set Dstadd [:pick $Dstadd 0 [:find $Dstadd "/"]]
:local Srcadd [/ip ipsec policy get $i src-address]
:set Srcadd [:pick $Srcadd 0 [:find $Srcadd "/"]]
:local L2TPSession [/ppp/active find caller-id=$Dstadd]
:delay 1s
if ([:len $L2TPSession] != 0) do={
:log info "Check IPsec: $Peer : $Dstadd has L2TP Active Connection"
:set L2TPPeer [/ppp/active get $L2TPSession name]
:set L2TPDstadd [/ppp/active get $L2TPSession address]
:set L2TPNetwork [/ip/address/ get [find network=$L2TPDstadd] address]
:set L2TPSrcadd [:pick $L2TPNetwork 0 [:find $L2TPNetwork "/"]]
:delay 1s
:log info "Check IPsec: Changes for ping L2TP > $L2TPPeer : $L2TPDstadd : $L2TPSrcadd"
}
# ping phase 1
if ([:len $L2TPSession] != 0) do={
:log info "Check IPsec: Start ping $L2TPDstadd from $L2TPSrcadd "
:set Pingresult [/ping address=$L2TPDstadd src-address=$L2TPSrcadd count=$Pingcount interval=$Pingint]
:log info "Check IPsec: Ping result for: $L2TPDstadd from $L2TPSrcadd > Ping result is: $Pingresult Ping trigger is: $PingTrigger"
} else={
:log info "Check IPsec: Start ping $Dstadd from $Srcadd"
:set Pingresult [/ping address=$Dstadd src-address=$Srcadd count=$Pingcount interval=$Pingint]
:log info "Check IPsec: Ping result for: $Dstadd from $Srcadd > Ping result is: $Pingresult Ping trigger is: $PingTrigger"
}
# reset phase
if ($Pingresult < $PingTrigger or [:len $Pingresult] = 0) do={
:set BadPeer $Peer
:set BadPeerDst $Dstadd
:set BadPeerSrc $Srcadd
:log warning "Check IPsec: Find a BAD Peer > $BadPeer : $L2TPPeer > Ping result is: $Pingresult Ping trigger is: $PingTrigger"
# find Bad Peer in Bad Peer List if yes > skip reset phase
:local BadPeerFindResult [:find $CheckIPsecBadPeerList $BadPeerDst]
if ([:typeof $BadPeerFindResult] = "num") do={
:log warning "Check IPsec: SKIP RESET FOR > $BadPeer : $L2TPPeer > Find in <Bad Peer List> with index=$BadPeerFindResult > Reset is disabled for this Peer"
:set CheckIPsec 1
} else={
# start reset
if ([:len $BadPeer] !=0) do={
:log warning "Check IPsec: STARTING RESET FOR > $BadPeer : $L2TPPeer"
:set CheckIPsec 1
:delay 1s
# kill L2TP Sesson
if ([:len $L2TPSession] != 0 ) do={
:do {
/ppp/active remove $L2TPSession
:log info "Check IPsec: For $BadPeer : $L2TPPeer : $L2TPDstadd > connection in -=PPP Active Connections=- is killed!"
} on-error={:log warning "Check IPsec: Can't kill $BadPeer : $L2TPPeer : $BadPeerDst connection in -=PPP Active Connections=-"}
}
:delay 1s
# find and kill all Active Peers with peer dst
:set ActivePeersForKill [/ip ipsec active-peers find remote-address=$BadPeerDst]
if ([:len $ActivePeersForKill] != 0) do={
:do {
:log info "Check IPsec: For $BadPeer : $L2TPPeer : $BadPeerDst > find Active Peers with numbers: $ActivePeersForKill in -=IPsec Active Peers=-"
:foreach i in=$ActivePeersForKill do={
/ip/ipsec/active-peers remove $i
:log info "Check IPsec: For $BadPeer : $L2TPPeer : $BadPeerDst > Active Peer with number $i in -=IPsec Active Peers=- is killed!"
}
} on-error={:log warning "Check IPsec: Can't kill $BadPeer : $L2TPPeer : $BadPeerDst connection: $ActivePeerToDelete in -=IPsec Active Peers=-"}
}
:delay 1s
:set $CheckIPsecBadPeerList ($CheckIPsecBadPeerList, $BadPeerDst)
:log warning "Check IPsec: Dst-Address: $BadPeerDst added to bad peer list."
:delay 1s
:log warning "Check IPsec: RESET PHASE 1 FOR $BadPeer : $L2TPPeer : $BadPeerDst : $L2TPDstadd > Complete!"
}
}
} else={
:local FindResult [:find $CheckIPsecBadPeerList $Dstadd]
if ([:typeof $FindResult] = "num") do={
:log warning "Check IPsec: $Dstadd in <Bad Peer List> with nuber: $FindResult"
:delay 1s
:local LenOfList [:len $CheckIPsecBadPeerList]
:local ArrgPosition [:find $CheckIPsecBadPeerList $Dstadd -1]
:set CheckIPsecBadPeerList ([:pick $CheckIPsecBadPeerList 0 $ArrgPosition],[:pick $CheckIPsecBadPeerList ($ArrgPosition + 1) $LenOfList])
:log warning "Check IPsec: Bad peer $Peer : $L2TPPeer : $Dstadd is UP! > And deleted from <Bad Peer List>!"
}
}
}
}
:delay 1s
# show test result
if ($CheckIPsec = 0) do={
:log info "Check IPsec: Test is OK"
}
if ($CheckIPsec = 1) do={
:log warning "Check IPsec: Test found peers for your attention"
}