delete address list old than 7 days

Can i set a script to delete all items older than 7 days in a specific address list?

thank you

Why don’t you specify, at the moment you place a IP on a address-list, that it has a lifetime of 7 days ? It will be removed automatically.
Or do you want the script for existing entries ?

sorry,
yes i need to delete a existing entries…

i think plan to use dynamic but they dont persist at reboot…

thank you

Hmm, that is going to be not so easy I think…
Can’t help you with the script, but out of curiosity I’ve been searching through the forums about this. (no real hits on THIS specific use-case)
The only “field” you have is the “Creation Time” when you added this (static) entry.
You’ll have to parse (eg. with some regex, only retain date part,convert it to a real date somehow) it and compare it to the actual daytime value, do the math and then decide (if > 7 days) to remove it.
Hopefully some of the real scripting guru’s here can jumpstart you.

Perhaps this sub-script could be used (or parts of its logic) for the aspect of conversion of “Mikrotik date” (eg dec/31/2019) to something usable.

http://forum.mikrotik.com/t/useful-universal-date-converter-function/87088/1

Also interesting, script/logic to get the difference between 2 dates..

http://forum.mikrotik.com/t/calculate-the-difference-between-two-dates/107120/1

Another one on string > time conversion and the issues it has.

http://forum.mikrotik.com/t/convert-string-to-time-value/68658/1

sorry,
but i think that function is for files, not for address list…

i’m reading link posted before, but i think is more complex …

can help if i would delete entries for past month?
so now is april, can i delete all entries for march?

:foreach i in=[/ip firewall address-list print where creation-time~"apr" and list="mylist"] do={
	:local address [/ip firewall address-list get $i address]
	/ip firewall address-list remove [find list="mylist" address="$address"]
}

seems work, but i test it on next month :smiley:

instead of create 12 script/scheduler can i create only 1 script to search past month?

thank you

creation-time~"apr"

change it to

creation-time~"mar"

yes, of course.

i did that , but now i no have entries with “mar”. next month i will try to “apr”

thank you

I just mailed MT and asked about date in RouterOS logs.
There are two problems.

  1. Less than 24 hour, only using hour/min/sec
  2. More than 24 hour uses monh/date hour/min/sec where moth are written with name “mar/apr”

So I asked for all log to logg with full info like 2020-04-24 12:15 This makes calculate using date simpler in RouterOS
Best if you could just do math directly with date.

MT respond that they may change this in version 7.x

ok thank you
is not a problem, i try to set search for month and wait next month to try it

thank you again

sorry, but my script seems not work. i added a log, so script is

:foreach i in=[/ip firewall address-list find where creation-time~"apr" and list="mylist"] do={
    :local address [/ip firewall address-list get $i address]
    :log info "Removing $address in mylist"
    /ip firewall address-list remove [find list="mylist" address="$address"]
}

but when i click run, it deleted all entries in address list… even those dated May…
why?

in log i find only (many times)

Removing in PortScanAttack

seems don’t find correct ip and delete all…


where i’m wrong?

thank you

Not sure why its not working, but since you already have the ID of the line to delete, just use the ID like this:

{
:foreach i in=[/ip firewall address-list find where creation-time~"apr" && list~"mylist"] do={
    :local address [/ip firewall address-list get $i address]
	:log info "Removing $address in mylist"
	/ip firewall address-list remove $i
}
}

This did work on my router.

Very nice.

Running this will show the *id of each found entry so you known how it looks. Every line and entry in RouterOS have a unique *id number. You can use that *id directly.

{
:foreach i in=[/ip firewall address-list find where creation-time~"may" && list~"mylist"] do={
 :put "*id: $i
}
}

works perfect!!! big thank you

Found this thread: http://forum.mikrotik.com/t/i-did-it-script-to-compute-unix-time/68576/1

If I am able to change the script to take input, I will try to make a script that convert the time field to epoch time.
Then it should be easy to calculate older than 7 days.

How do I specify a lifetime in an address list?

Just add a value on the “timeout” field ??

eg.
Under /ip/firewall/list you can “add” like add address=X.X.X.X list=mylist timeout=
This value could be : 5s , 5m , 3h , 7d whatever

Is there anyone can build this script. i also want similar script that need to delete address list old than 60 days. I can’t use dynamic IP timeout settings due to power failures.

delete exactly 30 days old address list values.

:global datetime2epoch do={
    :local dtime [:tostr $1]
    /system clock
    :local cyear [get date] ; :if ($cyear ~ "....-..-..") do={:set cyear [:pick $cyear 0 4]} else={:set cyear [:pick $cyear 7 11]}
    :if (([:len $dtime] = 10) or ([:len $dtime] = 11)) do={:set dtime "$dtime 00:00:00"}
    :if ([:len $dtime] = 15) do={:set dtime "$[:pick $dtime 0 6]/$cyear $[:pick $dtime 7 15]"}
    :if ([:len $dtime] = 14) do={:set dtime "$cyear-$[:pick $dtime 0 5] $[:pick $dtime 6 14]"}
    :if ([:len $dtime] =  8) do={:set dtime "$[get date] $dtime"}
    :if ([:tostr $1] = "") do={:set dtime ("$[get date] $[get time]")}
    :local vdate [:pick $dtime 0 [:find $dtime " " -1]]
    :local vtime [:pick $dtime ([:find $dtime " " -1] + 1) [:len $dtime]]
    :local vgmt  [get gmt-offset]; :if ($vgmt > 0x7FFFFFFF) do={:set vgmt ($vgmt - 0x100000000)}
    :if ($vgmt < 0) do={:set vgmt ($vgmt * -1)}
    :local arrm  [:toarray "0,0,31,59,90,120,151,181,212,243,273,304,334"]
    :local vdoff [:toarray "0,4,5,7,8,10"]
    :local MM    [:pick $vdate ($vdoff->2) ($vdoff->3)]
    :local M     [:tonum $MM]
    :if ($vdate ~ ".../../....") do={
        :set vdoff [:toarray "7,11,1,3,4,6"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
    }
    :local yyyy  [:pick $vdate ($vdoff->0) ($vdoff->1)] ; :if ((($yyyy - 1968) % 4) = 0) do={:set ($arrm->1) -1; :set ($arrm->2) 30}
    :local totd  ((($yyyy - 1970) * 365) + (($yyyy - 1968) / 4) + ($arrm->$M) + ([:pick $vdate ($vdoff->4) ($vdoff->5)] - 1))
    :return      (((((($totd * 24) + [:pick $vtime 0 2]) * 60) + [:pick $vtime 3 5]) * 60) + [:pick $vtime 6 8] - $vgmt)
}



      :local currDate [/system clock get date]
:log info $currDate 
      :local currDateSeconds [$datetime2epoch $currDate]
      :local aDayinSeconds "2592000"      #change this value to get number of days (per day =86400 x number of days ) in this case 259200 = 30 days
      :local DSR
      :set DSR ([:tonum $currDateSeconds]-[:tonum $aDayinSeconds])



#########################################################################xxxxxxxxxxxxxxxxxxxxxxxxxxx




:global unixtodatetime do={
    :local ux [:tonum $1]
    :local Fzerofill do={:return [:pick (100 + $1) 1 3]}
    :local prMntDays [:toarray "0,0,31,59,90,120,151,181,212,243,273,304,334"]
    :local vgmt      [:tonum [/system clock get gmt-offset]]; :if ($vgmt > 0x7FFFFFFF) do={:set vgmt ($vgmt - 0x100000000)}
    :if ($vgmt < 0) do={:set vgmt ($vgmt * -1)}
    :local tzepoch   ($ux + $vgmt)
    :if ($tzepoch < 0) do={:set tzepoch 0} ; # unsupported negative unix epoch
    :local yearStart (1970 + ($tzepoch / 31536000))
    :local tmpbissex (($yearStart - 1968) / 4) ; :if ((($yearStart - 1968) % 4) = 0) do={:set ($prMntDays->1) -1 ; :set ($prMntDays->2) 30}
    :local tmpsec    ($tzepoch % 31536000)
    :local tmpdays   (($tmpsec / 86400) - $tmpbissex)
    :if (($tmpsec < (86400 * $tmpbissex)) and ((($yearStart - 1968) % 4) = 0)) do={
        :set tmpbissex ($tmpbissex - 1) ; :set ($prMntDays->1) 0 ; :set ($prMntDays->2) 31 ; :set tmpdays  ($tmpdays + 1)
    }
    :if ($tmpsec < (86400 * $tmpbissex)) do={:set yearStart ($yearStart - 1) ; :set tmpdays   ($tmpdays + 365)}
    :local mnthStart 12 ; :while (($prMntDays->$mnthStart) > $tmpdays) do={:set mnthStart ($mnthStart - 1)}
    :local dayStart  [$Fzerofill (($tmpdays + 1) - ($prMntDays->$mnthStart))]
    :local timeStart (00:00:00 + [:totime ($tmpsec % 86400)])
    :return "$yearStart/$[$Fzerofill $mnthStart]/$[$Fzerofill $dayStart] $timeStart"
}

:local DATE [$unixtodatetime $DSR]

:local YYYY [:pick $DATE 0 4]
:local mm [:pick $DATE 5 7]
:local DD [:pick $DATE 8 10]
:local LASTDAY "$YYYY-$mm-$DD"

:log info $LASTDAY 






{
:foreach i in=[/ip firewall address-list find where creation-time~"$LASTDAY" && list~"mylist"] do={
    :local address [/ip firewall address-list get $i address]
	:log info "Removing $address in mylist"
	/ip firewall address-list remove $i
}
}

RouterOS 7.10.+ use Date on ISO format,
so something like “/ip firewall address-list remove [find where (creation-time<$daysago and list=$theList)]” work without use any clycle and is faster.
Just calc $daysago 30 days less than “today”

pseudocode, if RouterOS have such functions…
$daysago = [:todate [:toepoch [([:timestamp] - 2592000)]] ] ]
or better…
$daysago = ([:now] - 30d)
But since I wrote probably more scripting functions than RouterOS “programmers”…

http://forum.mikrotik.com/t/convert-uptime-to-date-and-time/157724/37

:global timetoseconds do={
:local inTime $1
:local wPos [:find $inTime “w” -1]
:local dPos [:find $inTime “d” -1]
:local itLen [:find $inTime “.” -1] ; :if ([:typeof $itLen] = “nil”) do={:set itLen [:len $inTime]}
:local itSec [:pick $inTime ($itLen - 2) $itLen]
:local itMin [:pick $inTime ($itLen - 5) ($itLen - 3)]
:local itHou [:pick $inTime ($itLen - 8) ($itLen - 6)]
:local itDay 0
:local itWee 0
:if (([:typeof $wPos] = “nil”) and ([:typeof $dPos] = “num”)) do={:set itDay [:pick $inTime 0 $dPos] }
:if (([:typeof $wPos] = “num”) and ([:typeof $dPos] = “num”)) do={:set itDay [:pick $inTime ($wPos + 1) $dPos] }
:if ([:typeof $wPos] = “num”) do={:set itWee [:pick $inTime 0 $wPos] }
:local totitSec ($itSec + (60 * $itMin) + (3600 * $itHou) + (86400 * $itDay) + (604800 * $itWee))
:return $totitSec
}

:global unixtodatetime do={
:local ux [:tonum $1]
:local Fzerofill do={:return [:pick (100 + $1) 1 3]}
:local prMntDays [:toarray “0,0,31,59,90,120,151,181,212,243,273,304,334”]
:local vgmt [:tonum [/system clock get gmt-offset]]; :if ($vgmt > 0x7FFFFFFF) do={:set vgmt ($vgmt - 0x100000000)}
:if ($vgmt < 0) do={:set vgmt ($vgmt * -1)}
:local tzepoch ($ux + $vgmt)
:if ($tzepoch < 0) do={:set tzepoch 0} ; # unsupported negative unix epoch
:local yearStart (1970 + ($tzepoch / 31536000))
:local tmpbissex (($yearStart - 1968) / 4) ; :if ((($yearStart - 1968) % 4) = 0) do={:set ($prMntDays->1) -1 ; :set ($prMntDays->2) 30}
:local tmpsec ($tzepoch % 31536000)
:local tmpdays (($tmpsec / 86400) - $tmpbissex)
:if (($tmpsec < (86400 * $tmpbissex)) and ((($yearStart - 1968) % 4) = 0)) do={
:set tmpbissex ($tmpbissex - 1) ; :set ($prMntDays->1) 0 ; :set ($prMntDays->2) 31 ; :set tmpdays ($tmpdays + 1)
}
:if ($tmpsec < (86400 * $tmpbissex)) do={:set yearStart ($yearStart - 1) ; :set tmpdays ($tmpdays + 365)}
:local mnthStart 12 ; :while (($prMntDays->$mnthStart) > $tmpdays) do={:set mnthStart ($mnthStart - 1)}
:local dayStart [$Fzerofill (($tmpdays + 1) - ($prMntDays->$mnthStart))]
:local timeStart (00:00:00 + [:totime ($tmpsec % 86400)])
:return “$yearStart/$[$Fzerofill $mnthStart]/$[$Fzerofill $dayStart] $timeStart”
}

{
:local theList “bannedList”
:local hmanyds 30
:local daysago [$unixtodatetime [$timetoseconds ([:timestamp] - ($hmanyds * 86400))]]
/ip firewall address-list remove [find where (creation-time<$daysago and list=$theList)]
}

i have tested this & this will delete entire list for some reason. not just more than 30 days old. sadly