Tuesday, 31 March 2015

Mikrotik Synchronize Address List

15:11 Posted by Jurgens Krause , , , No comments
This is a simple script solution to synchronize small address lists between Mikrotik routers. It is limited by the fact that there is a 4096 byte limit for variables in Mikrotik Scripts. I have maximized the number if entries you can sync by putting only the list name and address in the file


On the host router add the following script:

#Semicolon separated list of Address Lists you want to sync
:local lists {"List1";"List2"}

#Filename of export (must match receiving router import filename
:local exportFile ExportAddressList

/file remove [:file find name=$exportFile]

:local ipAddress
:local listEntry
:local fileContents

:set fileContents ""

:foreach listName in=$lists do={
  :foreach listEntry in=[/ip firewall address-list find where list=$listName] do={
    :set ipAddress [/ip firewall address-list get $listEntry address]
    :log info "=$listName"
    :set fileContents "$fileContents$listName=$ipAddress\n"
    }
}
/file print file=$exportFile
/file set $exportFile contents=$fileContents


On the client router, add the following script.
#Filename of export (must match receiving router import filename
:local importFile ExportAddressList.txt

#IP Address of router with existing address list(s)
:local hostIP 1.2.3.4

#FTP Username and Password
:local ftpUser username
:local ftpPassword userpassword

/tool fetch address=$hostIP src-path=$importFile dst-path=$importFile mode=ftp user=$ftpUser password=$ftpPassword
:local fileContent [/file get [/file find name=$importFile] contents]

#IMPORT NEW ROUTES
{
#Declare Local Variables
    :local contentLength [:len $fileContent];
    :local lineEnd 0
    :local lineContent ""
    :local lastEnd 0
    :local addressList
    :local addressListEnd
    :local ipAddress
    :local ipAddressStart
    :local lineLength

    :while ($lineEnd < $contentLength) do={
        :set lineEnd [:find $fileContent "\n" $lastEnd]
        :if ([:len $lineEnd] = 0) do={
            :set lineEnd $contentLength
        }
        :set lineContent [:pick $fileContent $lastEnd $lineEnd]
        :set lastEnd ($lineEnd +1)
        : if ($lineContent !="") do={
            :set addressListEnd [:find $lineContent "=" -1]
            :set addressList [:pick $lineContent 0 $addressListEnd]
            :set lineLength [:len $lineContent]
            :set ipAddressStart ($addressListEnd+1)
            :set ipAddress [:pick $lineContent $ipAddressStart $lineLength]
            /ip firewall address-list
            :if ([/ip firewall address-list find address=$ipAddress]="") do={add list=$addressList address=$ipAddress comment="Imported from $hostIP"}
        }
#^ENDIF^
    }
#^ENDWHILE^

}
#END OF IMPORT


#REMOVE ROUTES THAT ARE NO LONGER IN HOST LIST
{
    :local listEntry
    :local listName
    :local listIP
    :local listComment
    :local findResult
 
    :foreach listEntry in=[/ip firewall address-list find] do={
        :set listIP [/ip firewall address-list get $listEntry address]
        :set listName [/ip firewall address-list get $listEntry list]
        :set listComment [/ip firewall address-list get $listEntry comment]
        :if ($listComment ="Imported from $hostIP") do={
            :set findResult [:find $fileContent "$listName=$listIP" -1]
            :set findResult "a$findResult"
            :if ($findResult ="a") do={
                /ip firewall address-list remove $listEntry
            }
        }
    }
}
#END OF REMOVE ROUTES


Remember to replace the variables with your values.
You can now set the scheduler to synchronize the lists at regular intervals.

0 comments:

Post a Comment