├── .gitignore ├── README.md ├── TODO.md ├── auto-upgrade.rsc ├── backup-config.rsc ├── dhcp-notify-slack.rsc ├── failover_without_scripts.src.rsc └── message-to-slack.rsc /.gitignore: -------------------------------------------------------------------------------- 1 | /work 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MikrtoTik / RouterOS Scripts 2 | 3 | 4 | 5 | ## auto-upgrade.rsc 6 | 7 | This script is for automatic upgrading of MikroTik routers. 8 | In our environment, I have one MikroTik (at my home) scheduled to upgrade every night, 9 | and all other routers scheduled to upgrade once per week. This is useful to catch possible 10 | troubles on one router and not on all routers at the same time. 11 | 12 | Auto-upgrade script will look for a new release in current-channel (production releases), 13 | if there is a new version available, it upgrade itself. When there is no new Router OS available, 14 | it checks for a new firmware - when available, it upgrades firmware. 15 | 16 | ### Installation 17 | 18 | Using Winbox / Web admin (if you are familiar with command line, you already know how to do it :) 19 | - Go to *System / Scripts, Add new* 20 | - Name it, ie. "Auto Upgrade", select required policies (if you are lazy like me, select all boxes) 21 | - Paste source code to *Source* field 22 | - Replace :local email "your@email.com" with your own e-mail 23 | - Save script 24 | - Check, if your MikroTik is configured to send e-mail correctly 25 | - Go to *System / Scheduler, Add New* 26 | - Schedule script regarding your needs. *OnEvent* field should be something like this: */system script run "Auto Upgrade"* 27 | 28 | 29 | 30 | ## backup-config.rsc 31 | 32 | This script backups your MikroTik's configuration and uploads it to FTP server (or optionally to two FTP servers). 33 | Backup is saved in two different file formats: 34 | - .backup is binary format, useful for restoring config to same hardware (model). 35 | - .rsc is plain text format, useful for editing and possible restoring to a different MikroTik hardware. 36 | Version number is attached to all files, so you always have latest backup from each RouterOS version. 37 | This is very useful when you need to downgrade Router OS for some reason - you have latest working backup for each Router OS version. 38 | 39 | ### Installation 40 | 41 | Using Winbox / Web admin (if you are familiar with command line, you already know how to do it :) 42 | - Go to *System / Scripts, Add new* 43 | - Name it, ie. "Backup Config", select required policies (if you are lazy like me, select all boxes) 44 | - Paste source code to *Source* field 45 | - Edit variables in section *Set variables* regarding your needs 46 | - Save script 47 | - Go to *System / Scheduler, Add New* 48 | - Schedule script regarding your needs. *OnEvent* field should be something like this: */system script run "Backup Config"* 49 | - Test it, your backup files should appear on your FTP(s) servers 50 | 51 | Warning: FTP protocol is not encrypted, so all information is transmitted unencrypted! I don't care in my case, 52 | because all data are pushed thru encrypted VPN channels, but the security can be improved here! 53 | 54 | 55 | 56 | ## message-to-slack.rsc 57 | 58 | This script allow to send messages from RouterOS to Slack channel. 59 | There is no way how to call webhooks from RouterOS, so it uses workaround using /tool fetch command. 60 | 61 | ### Installation 62 | 63 | Slack 64 | - Generate your API token here: https://api.slack.com/docs/oauth-test-tokens 65 | - More information here: http://jeremyhall.com.au/mikrotik-routeros-slack-messaging-hack/ 66 | 67 | Using Winbox / Web admin (if you are familiar with command line, you already know how to do it :) 68 | - Go to *System / Scripts, Add new* 69 | - Name it, ie. "Message To Slack", select required policies (if you are lazy like me, select all boxes) 70 | - Paste source code to *Source* field 71 | - Edit variables *botname* and *token* in section *Set variables* regarding your needs 72 | - Save script 73 | - Call it from another scripts using: 74 | ``` 75 | :global SlackMessage "my message" 76 | :global SlackChannel "my-channel" 77 | /system script run "Message To Slack"; 78 | ``` 79 | 80 | 81 | 82 | ## dhcp-notify-slack.rsc 83 | 84 | This script will send Slack message each time someone (or something) will get lease from your specific DHCP server - like when guest connects to Guests WiFi. 85 | 86 | ### Installation 87 | 88 | Slack 89 | - Generate your API token here: https://api.slack.com/docs/oauth-test-tokens 90 | - More information here: http://jeremyhall.com.au/mikrotik-routeros-slack-messaging-hack/ 91 | 92 | Using Winbox / Web admin (if you are familiar with command line, you already know how to do it :) 93 | - If not already done, install the *message-to-slack.rsc* script from this repository 94 | - Go to *IP / DHCP Server* 95 | - Click on DHCP server where you want notifications 96 | - Paste source code to *Lease Script* field 97 | - Edit variables *SlackChannel* and *SlackMessage* regarding your needs 98 | - Save settings 99 | 100 | 101 | 102 | Nice MikroTik'ing 103 | Maxim Krušina, Massimo Filippi, s.r.o. 104 | maxim@mfcc.cz 105 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | ToDo 2 | ==== 3 | 4 | - Send messages to Slack via POST + JSON (not possible now because there is no support for sending auth headers with /fetch) 5 | -------------------------------------------------------------------------------- /auto-upgrade.rsc: -------------------------------------------------------------------------------- 1 | ## 2 | ## Automatically upgrade RouterOS and Firmware 3 | ## https://github.com/massimo-filippi/mikrotik 4 | ## 5 | ## script by Maxim Krusina, maxim@mfcc.cz 6 | ## based on: http://wiki.mikrotik.com/wiki/Manual:Upgrading_RouterOS 7 | ## created: 2014-12-05 8 | ## updated: 2019-01-26 9 | ## tested on: RouterOS 6.43.8 / multiple HW devices 10 | ## 11 | 12 | 13 | ########## Set variables 14 | 15 | ## Update channel can take values before 6.43.8: bugfix | current | development | release-candidate 16 | ## Update channel can take values after 6.43.8: long-term | stable | development | testing 17 | :local updChannel "stable" 18 | 19 | ## Notify via Slack 20 | :local notifyViaSlack true 21 | :global SlackChannel "#log" 22 | 23 | ## Notify via E-mail 24 | :local notifyViaMail true 25 | :local email "your@email.com" 26 | 27 | 28 | ########## Upgrade firmware 29 | 30 | ## Let's check for updated firmware 31 | 32 | :local rebootRequired false 33 | /system routerboard 34 | 35 | :if ( [get current-firmware] != [get upgrade-firmware]) do={ 36 | 37 | ## New version of firmware available, let's upgrade 38 | 39 | ## Notify via Log 40 | :log info ("Upgrading firmware on router $[/system identity get name] from $[/system routerboard get current-firmware] to $[/system routerboard get upgrade-firmware]") 41 | 42 | ## Notify via Slack 43 | :if ($notifyViaSlack) do={ 44 | :global SlackMessage "Upgrading firmware on router *$[/system identity get name]* from $[/system routerboard get current-firmware] to *$[/system routerboard get upgrade-firmware]*"; 45 | :global SlackMessageAttachements ""; 46 | /system script run "Message To Slack"; 47 | } 48 | 49 | ## Notify via E-mail 50 | :if ($notifyViaMail) do={ 51 | /tool e-mail send to="$email" subject="Upgrading firmware on router $[/system identity get name]" body="Upgrading firmware on router $[/system identity get name] from $[/system routerboard get current-firmware] to $[/system routerboard get upgrade-firmware]" 52 | } 53 | 54 | ## Upgrade (it will no reboot, we'll do it later) 55 | upgrade 56 | :set rebootRequired true 57 | 58 | } 59 | 60 | 61 | ########## Upgrade RouterOS 62 | 63 | ## Check for update 64 | /system package update 65 | set channel=$updChannel 66 | check-for-updates 67 | 68 | ## Wait on slow connections 69 | :delay 15s; 70 | 71 | ## Important note: "installed-version" was "current-version" on older Roter OSes 72 | :if ([get installed-version] != [get latest-version]) do={ 73 | 74 | ## Notify via Log 75 | :log info ("Upgrading RouterOS on router $[/system identity get name] from $[/system package update get installed-version] to $[/system package update get latest-version] (channel:$[/system package update get channel])") 76 | 77 | ## Notify via Slack 78 | :if ($notifyViaSlack) do={ 79 | :global SlackMessage "Upgrading RouterOS on router *$[/system identity get name]* from $[/system package update get installed-version] to *$[/system package update get latest-version] (channel:$[/system package update get channel])*"; 80 | :global SlackMessageAttachements ""; 81 | /system script run "Message To Slack"; 82 | } 83 | 84 | ## Notify via E-mail 85 | :if ($notifyViaMail) do={ 86 | /tool e-mail send to="$email" subject="Upgrading RouterOS on router $[/system identity get name]" body="Upgrading RouterOS on router $[/system identity get name] from $[/system package update get installed-version] to $[/system package update get latest-version] (channel:$[/system package update get channel])" 87 | } 88 | 89 | ## Wait for mail to be sent & upgrade 90 | :delay 15s; 91 | install 92 | 93 | } else={ 94 | 95 | :if ($rebootRequired) do={ 96 | # Firmware was upgraded, but not RouterOS, so we need to reboot to finish firmware upgrade 97 | 98 | ## Notify via Slack 99 | :if ($notifyViaSlack) do={ 100 | :global SlackMessage "Rebooting..."; 101 | :global SlackMessageAttachements ""; 102 | /system script run "Message To Slack"; 103 | } 104 | 105 | /system reboot 106 | 107 | } else={ 108 | 109 | # No firmware nor RouterOS upgrade available, nothing to do, just log info 110 | :log info ("No firmware nor RouterOS upgrade found.") 111 | 112 | ## Notify via Slack 113 | :if ($notifyViaSlack) do={ 114 | :global SlackMessage "No firmware nor RouterOS upgrade found."; 115 | :global SlackMessageAttachements ""; 116 | /system script run "Message To Slack"; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /backup-config.rsc: -------------------------------------------------------------------------------- 1 | ## 2 | ## Automatically backup router's config and upload it to FTP server(s) 3 | ## https://github.com/massimo-filippi/mikrotik 4 | ## 5 | ## script by Maxim Krusina, maxim@mfcc.cz 6 | ## created: 2014-03-09 7 | ## updated: 2019-01-26 8 | ## tested on: RouterOS 6.43.8 / multiple HW devices 9 | ## 10 | 11 | 12 | ########## Set variables 13 | 14 | ## Base filename 15 | :local filename "daily-backup-myroutername" 16 | 17 | ## FTP server 1 for upload 18 | :local ftp1Address "ftp-1-hostname" 19 | :local ftp1User "ftp-1-username" 20 | :local ftp1Password "ftp-1-password" 21 | :local ftp1Path "ftp-1-path" 22 | 23 | ## FTP server 2 for upload - if second server is not used, just comment lines bellow 24 | :local ftp2Address "ftp-2-hostname" 25 | :local ftp2User "ftp-2-username" 26 | :local ftp2Password "ftp-2-password" 27 | :local ftp2Path "ftp-2-path" 28 | 29 | ## Log to Slack 30 | :local notifyViaSlack true 31 | :global SlackChannel "#log" 32 | 33 | 34 | ########## Message to Slack 35 | 36 | :if ($notifyViaSlack) do={ 37 | :global SlackMessage "Creating configuration backup on router *$[/system identity get name]*"; 38 | :global SlackMessageAttachements ""; 39 | /system script run "Message To Slack"; 40 | } 41 | 42 | 43 | ########## Do the stuff 44 | 45 | ## Get currrent RouterOS version 46 | :local myVer [/system package update get installed-version]; 47 | 48 | ## Append version number to filename (to not overwrite backups from older RouterOS versions) 49 | :set filename ($filename . "-" . $myVer); 50 | 51 | ## Backup & Export config to local file 52 | /system backup save name="$filename" 53 | /export file="$filename" 54 | 55 | ## Upload to .backup to FTP 1 56 | /tool fetch address=$ftp1Address src-path="$filename.backup" user=$ftp1User mode=ftp password=$ftp1Password dst-path=($ftp1Path . $filename . ".backup") upload=yes port=21 57 | 58 | ## Upload to .rsc to FTP 1 59 | /tool fetch address=$ftp1Address src-path="$filename.rsc" user=$ftp1User mode=ftp password=$ftp1Password dst-path=($ftp1Path . $filename . ".rsc") upload=yes port=21 60 | 61 | 62 | ########## Message to Slack 63 | 64 | :if ($notifyViaSlack) do={ 65 | :global SlackMessage "Backup upload to FTP *$ftp1Address*"; 66 | :global SlackMessageAttachements ""; 67 | /system script run "Message To Slack"; 68 | } 69 | 70 | 71 | ########## Upload to secondary FTP 72 | 73 | :if ([:len $ftp2Address] != 0) do={ 74 | 75 | ## Upload to .backup to FTP 2 76 | /tool fetch address=$ftp2Address src-path="$filename.backup" user=$ftp2User mode=ftp password=$ftp2Password dst-path=($ftp2Path . $filename . ".backup") upload=yes port=21 77 | 78 | ## Upload to .rsc to FTP 2 79 | /tool fetch address=$ftp2Address src-path="$filename.rsc" user=$ftp2User mode=ftp password=$ftp2Password dst-path=($ftp2Path . $filename . ".rsc") upload=yes port=21 80 | 81 | :if ($notifyViaSlack) do={ 82 | :global SlackMessage "Backup upload to FTP *$ftp2Address*"; 83 | :global SlackMessageAttachements ""; 84 | /system script run "Message To Slack"; 85 | } 86 | } 87 | 88 | 89 | ## Log 90 | :log info ("Configuration backup created on router $[/system identity get name].") 91 | 92 | 93 | ########## Message to Slack 94 | 95 | :if ($notifyViaSlack) do={ 96 | :global SlackMessage "Configuration backup on router *$[/system identity get name]* done"; 97 | :global SlackMessageAttachements ""; 98 | /system script run "Message To Slack"; 99 | } 100 | -------------------------------------------------------------------------------- /dhcp-notify-slack.rsc: -------------------------------------------------------------------------------- 1 | ## 2 | ## Send a message to Slack on DHCP Bound 3 | ## https://github.com/massimo-filippi/mikrotik 4 | ## 5 | ## script by Maxim Krusina, maxim@mfcc.cz 6 | ## based on: http://jeremyhall.com.au/mikrotik-routeros-slack-messaging-hack/ 7 | ## created: 2018-09-23 8 | ## updated: 2018-09-23 9 | ## 10 | ## usage: 11 | ## use this script as DHCP Lease Script 12 | ## 13 | 14 | 15 | :global leaseBound 16 | :global leaseServerName 17 | :global leaseActMAC 18 | :global leaseActIP 19 | 20 | 21 | # Do the stuff on Bind 22 | 23 | :if ($leaseBound = 1) do={ 24 | /ip dhcp-server lease { 25 | :foreach i in [find dynamic address=$leaseActIP] do={ 26 | 27 | :local hostName [/ip dhcp-server lease get $i host-name]; 28 | 29 | :global SlackChannel "#my-channel" 30 | :global SlackMessage "New guest connected to *My wifi name*" 31 | :global SlackMessageAttachements "[{\"fields\": [{\"title\": \"Host name\",\"value\": \"$hostName\",\"short\": false},{\"title\": \"IP\",\"value\": \"$leaseActIP\",\"short\": false},{\"title\": \"MAC\",\"value\": \"$leaseActMAC\",\"short\": false}],\"color\": \"#F35A00\",\"mrkdwn_in\":[\"text\",\"pretext\"]}]"; 32 | 33 | /system script run "Message To Slack"; 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /failover_without_scripts.src.rsc: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # # 3 | # Failover Withouth Scripts # 4 | # # 5 | ##################################################################### 6 | # Global Vars # 7 | # Gateway ISP 1 and 2 8 | :global Gateway1 "192.168.0.1" 9 | :global Gateway2 "11.11.11.1" 10 | # Host 1 (Any IP, Used OpenDNS) 11 | :global Host1 "208.67.222.222" 12 | # Host 1 (Any IP, Used OpenDNS) 13 | :global Host2 "208.67.220.220" 14 | ## Show Message 15 | :global Msg "Ok" 16 | ##################################################################### 17 | /ip route 18 | add dst-address=0.0.0.0/0 gateway=$Gateway1 distance=1 \ 19 | check-gateway=ping 20 | add dst-address=0.0.0.0/0 gateway=$Gateway2 distance=2 21 | 22 | /ip route 23 | add dst-address=$Host1 gateway=$Gateway1 scope=10 24 | add dst-address=$Host2 gateway=$Gateway2 scope=10 25 | 26 | /ip route 27 | add distance=1 gateway=$Host1 routing-mark=ISP1 check-gateway=ping 28 | add distance=2 gateway=$Host2 routing-mark=ISP1 check-gateway=ping 29 | 30 | /ip route 31 | add distance=1 gateway=$Host1 routing-mark=ISP2 check-gateway=ping 32 | add distance=2 gateway=$Host2 routing-mark=ISP2 check-gateway=ping 33 | 34 | /ip route 35 | add dst-address=$Host1 type=blackhole distance=20 36 | add dst-address=$Host2 type=blackhole distance=20 37 | -------------------------------------------------------------------------------- /message-to-slack.rsc: -------------------------------------------------------------------------------- 1 | ## 2 | ## Send message to Slack 3 | ## https://github.com/massimo-filippi/mikrotik 4 | ## 5 | ## script by Maxim Krusina, maxim@mfcc.cz 6 | ## based on: http://jeremyhall.com.au/mikrotik-routeros-slack-messaging-hack/ 7 | ## created: 2017-08-21 8 | ## updated: 2018-09-22 9 | ## 10 | ## usage: 11 | ## in another script, first setup global variable then call this script: 12 | ## 13 | ## :global SlackMessage "my message" 14 | ## :global SlackChannel "#my-channel" 15 | ## :global SlackMessageAttachements "url encoded attachements or empty string for none" 16 | ## /system script run MessageToSlack; 17 | ## 18 | ## PS: unfortunately, right now there is no better way to pass script parameters than via global variables 19 | ## 20 | 21 | 22 | :global SlackChannel; 23 | :global SlackMessage; 24 | :global SlackMessageAttachements; 25 | 26 | :local botname [/system identity get name]; 27 | :local token "xoxp-your-token-here" 28 | :local iconurl https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2015-12-08/16227284950_0c4cfc4b66e68c6273ad_48.jpg 29 | 30 | 31 | ## Replace ASCII characters with URL encoded characters 32 | ## Call this function: $urlEncode "string to encode" 33 | 34 | :global urlEncode do={ 35 | 36 | :local string $1; 37 | :local stringEncoded ""; 38 | 39 | :for i from=0 to=([:len $string] - 1) do={ 40 | :local char [:pick $string $i] 41 | :if ($char = " ") do={ :set $char "%20" } 42 | :if ($char = "\"") do={ :set $char "%22" } 43 | :if ($char = "#") do={ :set $char "%23" } 44 | :if ($char = "\$") do={ :set $char "%24" } 45 | :if ($char = "%") do={ :set $char "%25" } 46 | :if ($char = "&") do={ :set $char "%26" } 47 | :if ($char = "+") do={ :set $char "%2B" } 48 | :if ($char = ",") do={ :set $char "%2C" } 49 | :if ($char = "-") do={ :set $char "%2D" } 50 | :if ($char = ":") do={ :set $char "%3A" } 51 | :if ($char = "[") do={ :set $char "%5B" } 52 | :if ($char = "]") do={ :set $char "%5D" } 53 | :if ($char = "{") do={ :set $char "%7B" } 54 | :if ($char = "}") do={ :set $char "%7D" } 55 | :set stringEncoded ($stringEncoded . $char) 56 | } 57 | :return $stringEncoded; 58 | } 59 | 60 | :local channel [$urlEncode $SlackChannel]; 61 | :local message [$urlEncode $SlackMessage]; 62 | :local attachements [$urlEncode $SlackMessageAttachements]; 63 | 64 | 65 | ## Send the message to Slack 66 | 67 | /tool fetch url="https://slack.com/api/chat.postMessage?token=$token&channel=$channel&text=$message&icon_url=$iconurl&as_user=false&username=$botname&attachments=$SlackMessageAttachements"; 68 | --------------------------------------------------------------------------------