├── DynDNS.php ├── Mikrotik Scripts ├── Autoupdate ├── CheckTraffic ├── DynamicDNSwithWANinterfaceIP ├── DynamicDNSwithoutWANIP ├── LoginTelegram ├── scheduledBackup └── setGlobals └── README.md /DynDNS.php: -------------------------------------------------------------------------------- 1 | # this is the PHP file hosted on the web root of Dreamhost server to facilitate Dynamic DNS 2 | # more information here: https://help.dreamhost.com/hc/en-us/articles/217240068-Dynamic-DNS 3 | 4 | $val) { 30 | $args.="&" . urlencode($key) . "=" . urlencode($val); 31 | } 32 | } 33 | 34 | $url=$DH_API_BASE . $args; 35 | $curl_handle=curl_init(); 36 | curl_setopt($curl_handle,CURLOPT_URL,$DH_API_BASE . $args); 37 | curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,5); 38 | curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); 39 | $buffer = curl_exec($curl_handle); 40 | curl_close($curl_handle); 41 | 42 | if (empty($buffer)) { 43 | return(false); 44 | } else { 45 | return(json_decode($buffer,true)); 46 | } 47 | } 48 | function fail($str) { 49 | printf("error: %s",$str); 50 | exit(false); 51 | } 52 | function bad_input() { 53 | fail("invalid input\n"); 54 | } 55 | 56 | $passwd=$_REQUEST["passwd"]; 57 | $host=$_REQUEST["host"]; 58 | $addr=$_REQUEST["ip"]; 59 | $comment=$_REQUEST["comment"]; 60 | 61 | if($PASSWD != $passwd) { bad_input(); } 62 | if(!in_array($host,$HOSTS)) { bad_input(); } 63 | 64 | if(!$DH_API_KEY) { 65 | $DH_API_KEY=$_REQUEST["key"]; 66 | if(!$DH_API_KEY) { bad_input(); } 67 | } 68 | 69 | if(!$addr) { $addr=$_SERVER["REMOTE_ADDR"]; } 70 | 71 | $ret=dh_request("dns-list_records"); 72 | if($ret["result"] != "success") { 73 | fail("failed list records\n"); 74 | return(1); 75 | } 76 | $found=false; 77 | foreach($ret["data"] as $key => $row) { 78 | if($row["record"] == $host) { 79 | if($row["editable"] == 0) { 80 | fail("error: $host not editable"); 81 | } 82 | if($row["type"] != "A") { 83 | fail("error: $host not a A record"); 84 | } 85 | $found=$row; 86 | } 87 | } 88 | 89 | if($found) { 90 | if($addr==$found["value"]) { 91 | printf("record correct: %s => %s\n", $found["record"], $addr); 92 | return(0); 93 | } 94 | $ret=dh_request("dns-remove_record", 95 | array("record" => $found["record"], 96 | "type" => $found["type"], 97 | "value" => $found["value"])); 98 | if($ret["result"] != "success") { 99 | fail("failed to remove record\n"); 100 | return(1); 101 | } 102 | $record=$found["record"]; 103 | $type=$found["type"]; 104 | printf("deleted %s. had value %s\n", $record,$found["value"]); 105 | } else { 106 | $record=$host; 107 | $type='A'; 108 | } 109 | 110 | $ret=dh_request("dns-add_record", 111 | array("record" => $record, 112 | "type" => $type, 113 | "value" => $addr, 114 | "comment" => $comment)); 115 | 116 | if($ret["result"] != "success") { 117 | fail(sprintf("%s\n\t%s\n", 118 | "failed to add $record of type $type to $addr", $ret["data"])); 119 | return(1); 120 | } 121 | 122 | printf("success: set %s to %s\n", $record, $addr); 123 | ?> 124 | 125 | -------------------------------------------------------------------------------- /Mikrotik Scripts/Autoupdate: -------------------------------------------------------------------------------- 1 | #perform auto update of Mikrotik OS and send Telegram Notification 2 | 3 | :global TelegramToken 4 | :global TelegramGroupID 5 | :global TelegramURL 6 | 7 | /system package update 8 | check-for-updates 9 | 10 | :global InstalledVersion 11 | :global LatestVersion 12 | 13 | :global OSversion 14 | :set OSversion [/system resource get version] 15 | :global SystemName 16 | :set SystemName [/system identity get name] 17 | 18 | :set InstalledVersion [get installed-version] 19 | :set LatestVersion [get latest-version] 20 | :delay 1s; 21 | 22 | :if ($InstalledVersion != $LatestVersion) do={ 23 | :local TelegramMessage "*$SystemName alert $OSversion* %0ASystem will be upgraded from $InstalledVersion to $LatestVersion.%0A*Installing and Rebooting Now!*" 24 | /tool fetch url=($TelegramURL . $TelegramMessage) keep-result=no 25 | install 26 | } -------------------------------------------------------------------------------- /Mikrotik Scripts/CheckTraffic: -------------------------------------------------------------------------------- 1 | #script to check specific interface statistics every few minutes and send a telegram message if the bytes sent or bytes received exceed the threshold in Kilobytes 2 | 3 | :global TelegramToken 4 | :global TelegramGroupID 5 | :global TelegramURL 6 | 7 | :global MegaBytethreshold "3000" 8 | 9 | :global CheckTrafficInterface "ether10-WAN" 10 | 11 | :global OSversion 12 | :global OSversionShort 13 | :set OSversion [/system resource get version] 14 | :set OSversionShort [:pick $OSversion 0 [:find $OSversion " " -1]] 15 | 16 | :global SystemName 17 | :set SystemName [/system identity get name] 18 | 19 | :global TimeFresh [:put [/system clock get time]] 20 | :global TimeStale 21 | 22 | :global replaceChar do={ 23 | :for i from=0 to=([:len $1] - 1) do={ 24 | :local char [:pick $1 $i] 25 | :if ($char = $2) do={ 26 | :set $char $3 27 | } 28 | :set $output ($output . $char) 29 | } 30 | :return $output 31 | } 32 | 33 | :global txFreshMB 34 | :global rxFreshMB 35 | 36 | :global txStaleMB 37 | :global rxStaleMB 38 | 39 | :global txDiffMB 40 | :global rxDiffMB 41 | 42 | :set txFreshMB [ /interface ethernet get $CheckTrafficInterface driver-tx-byte] 43 | :set txFreshMB [ $replaceChar $txFreshMB " " "" ] 44 | :set txFreshMB [ $replaceChar $txFreshMB " " "" ] 45 | :set txFreshMB [:put (($txFreshMB/1024)/1024)] 46 | 47 | :set rxFreshMB [/interface ethernet get $CheckTrafficInterface driver-rx-byte] 48 | :set rxFreshMB [ $replaceChar $rxFreshMB " " "" ] 49 | :set rxFreshMB [ $replaceChar $rxFreshMB " " "" ] 50 | :set rxFreshMB [:put (($rxFreshMB/1024)/1024)] 51 | 52 | :set txDiffMB [:put ($txFreshMB-$txStaleMB)] 53 | :set rxDiffMB [:put ($rxFreshMB-$rxStaleMB)] 54 | 55 | :set txStaleMB $txFreshMB 56 | :set rxStaleMB $rxFreshMB 57 | 58 | 59 | :if (($txDiffMB > $MegaBytethreshold ) or ($rxDiffMB > $MegaBytethreshold)) do={ 60 | 61 | :local TelegramMessage "*$SystemName alert - rOS$OSversion*%0A$txDiffMB MB Transmitted%0A$rxDiffMB MB Received%0Abetween $TimeStale and $TimeFresh" 62 | /tool fetch url=($TelegramURL . $TelegramMessage) keep-result=no 63 | } 64 | 65 | :set TimeStale [:put [/system clock get time]] 66 | -------------------------------------------------------------------------------- /Mikrotik Scripts/DynamicDNSwithWANinterfaceIP: -------------------------------------------------------------------------------- 1 | # update Dynamic DNS on dreamhost domain and send telegram message with latest IP 2 | 3 | :global DynHOSTNAME "host.domain.com" 4 | :global DynPASSWORD "mypassword" 5 | :global DynINTERFACE "ADSL" #This is the external WAN interface we poll for it's IP. 6 | :global DynURL "http://www.domain.com/DynDNS.php" 7 | 8 | :global DynIPSTALE 9 | :global DynIPFRESH 10 | :local SAFETOPROCEED 11 | 12 | :global TelegramToken 13 | :global TelegramGroupID 14 | :global TelegramURL 15 | 16 | :global OSversion 17 | :global OSversionShort 18 | :set OSversion [/system resource get version] 19 | :set OSversionShort [:pick $OSversion 0 [:find $OSversion " " -1]] 20 | 21 | :global SystemName 22 | :set SystemName [/system identity get name] 23 | 24 | ### CHECK IF INTERFACE IS DISABLED ### 25 | :global DynSTATUS 26 | /interface pppoe-client monitor $DynINTERFACE once file=DynINTERFACE.txt 27 | :set DynSTATUS [/file get [/file find name=DynINTERFACE.txt] contents] 28 | :file remove [/file find name=DynINTERFACE.txt] 29 | 30 | :set DynSTATUS [:pick $DynSTATUS ( [:len $DynSTATUS] - 20) ( [:len $DynSTATUS] - 1) ] 31 | 32 | 33 | 34 | :do { 35 | :set DynIPFRESH [ /ip address get [/ip address find interface=$DynINTERFACE ] address ]; :set $SAFETOPROCEED 1; 36 | } on-error={ 37 | :log warning ("DynDynDNS: No ip address on $DynINTERFACE, terminating script prematurely.") 38 | } 39 | 40 | if ($SAFETOPROCEED = 1) do={ 41 | :for i from=( [:len $DynIPFRESH] - 1) to=0 do={ :if ( [:pick $DynIPFRESH $i] = "/") do= { :set DynIPFRESH [:pick $DynIPFRESH 0 $i]; } } 42 | 43 | :if ($DynIPSTALE != $DynIPFRESH) do={ 44 | :log info ("DynDynDNS: Stale IP = $DynIPSTALE") 45 | :log info ("DynDynDNS: Fresh IP = $DynIPFRESH") 46 | :log info ("DynDynDNS: Update IP needed, Sending UPDATE...!") 47 | 48 | /tool fetch url="$DynURL\?host=$DynHOSTNAME&passwd=$DynPASSWORD&ip=$DynIPFRESH" mode=http dst-path=("/DynDynDNS.".$DynHOSTNAME) 49 | :delay 1 50 | :local str [/file find name="DynDynDNS.$DynHOSTNAME"]; 51 | :file remove $str 52 | :set DynIPSTALE $DynIPFRESH 53 | :log warning "DynDynDNS: IP updated to $DynIPFRESH!" 54 | :local TelegramMessage "*$SystemName alert - rOS$OSversion*%0A$DynHOSTNAME DNS IP Updated to *$DynIPFRESH*" 55 | /tool fetch url=($TelegramURL . $TelegramMessage) keep-result=no 56 | } else={ 57 | :log info "DynDynDNS: no changes required. Exiting Normally"; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Mikrotik Scripts/DynamicDNSwithoutWANIP: -------------------------------------------------------------------------------- 1 | # update Dynamic DNS on dreamhost domain and send telegram message with latest IP 2 | # This script can be used if the public internet IP is not present on the Routerboard itself (behind another router). 3 | 4 | :global DynHOSTNAME "host.domain.com" 5 | :global DynPASSWORD "mypassword" 6 | :global DynURL "http://www.domain.com/DynDNS.php" 7 | 8 | 9 | :global DynIPSTALE 10 | :global DynIPFRESH 11 | 12 | 13 | :global TelegramToken 14 | :global TelegramGroupID 15 | :global TelegramURL 16 | 17 | :global OSversion 18 | :global OSversionShort 19 | :set OSversion [/system resource get version] 20 | :set OSversionShort [:pick $OSversion 0 [:find $OSversion " " -1]] 21 | 22 | :global SystemName 23 | :set SystemName [/system identity get name] 24 | 25 | 26 | :set DynIPFRESH [:resolve myip.opendns.com server=208.67.222.222]; 27 | 28 | 29 | # :for i from=( [:len $DynIPFRESH] - 1) to=0 do={ :if ( [:pick $DynIPFRESH $i] = "/") do= { :set DynIPFRESH [:pick $DynIPFRESH 0 $i]; } } 30 | 31 | :if ($DynIPSTALE != $DynIPFRESH) do={ 32 | :log info ("DynDNSScript: Stale IP = $DynIPSTALE") 33 | :log info ("DynDNSScript: Fresh IP = $DynIPFRESH") 34 | :log info ("DynDNSScript: Update IP needed, Sending UPDATE...!") 35 | 36 | :delay 1 37 | :local str [/file find name="DynDNSScript.$1HOSTNAME"]; 38 | :file remove $str 39 | :set DynIPSTALE $DynIPFRESH 40 | /tool fetch url="$1DNSURL\?host=$1HOSTNAME&passwd=$1PASSWORD&ip=$DynIPFRESH" mode=http dst-path=("/1DynDNS.".$1HOSTNAME) 41 | :log warning "DynDNSScript: IP updated to $DynIPFRESH!" 42 | 43 | 44 | :local TelegramMessage "*$SystemName alert - rOS$OSversion*%0A$1HOSTNAME DNS IP Updated to *$DynIPFRESH*" 45 | /tool fetch url=($TelegramURL . $TelegramMessage) keep-result=no 46 | 47 | 48 | } else={ 49 | :log info "DynDNSScript: no changes required. Exiting Normally"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Mikrotik Scripts/LoginTelegram: -------------------------------------------------------------------------------- 1 | #send a telegram message upon successful login to RB 2 | 3 | # BEGIN SETUP 4 | :local scheduleName "1loginmailscript" 5 | :local startBuf [:toarray [/log find message~"logged in" || message~"login failure"]] 6 | :local removeThese {"192.168.1.3";"whatever string you want"} 7 | # END SETUP 8 | 9 | :global TelegramToken 10 | :global TelegramGroupID 11 | :global TelegramURL 12 | 13 | :global OSversion 14 | :global OSversionShort 15 | :set OSversion [/system resource get version] 16 | :set OSversionShort [:pick $OSversion 0 [:find $OSversion " " -1]] 17 | 18 | :global SystemName 19 | :set SystemName [/system identity get name] 20 | 21 | 22 | # warn if schedule does not exist 23 | :if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={ 24 | /log warning "[LOGMON] ERROR: Schedule does not exist. Create schedule and edit script to match name" 25 | } 26 | 27 | # get last time 28 | :local lastTime [/system scheduler get [find name="$scheduleName"] comment] 29 | # for checking time of each log entry 30 | :local currentTime 31 | # log message 32 | :local message 33 | 34 | # final output 35 | :local output 36 | 37 | :local keepOutput false 38 | # if lastTime is empty, set keepOutput to true 39 | :if ([:len $lastTime] = 0) do={ 40 | :set keepOutput true 41 | } 42 | 43 | 44 | :local counter 0 45 | # loop through all log entries that have been found 46 | :foreach i in=$startBuf do={ 47 | 48 | # loop through all removeThese array items 49 | :local keepLog true 50 | :foreach j in=$removeThese do={ 51 | # if this log entry contains any of them, it will be ignored 52 | :if ([/log get $i message] ~ "$j") do={ 53 | :set keepLog false 54 | } 55 | } 56 | :if ($keepLog = true) do={ 57 | 58 | :set message [/log get $i message] 59 | 60 | # LOG DATE 61 | # depending on log date/time, the format may be different. 3 known formats 62 | # format of jan/01/2002 00:00:00 which shows up at unknown date/time. Using as default 63 | :set currentTime [ /log get $i time ] 64 | # format of 00:00:00 which shows up on current day's logs 65 | :if ([:len $currentTime] = 8 ) do={ 66 | :set currentTime ([:pick [/system clock get date] 0 11]." ".$currentTime) 67 | } else={ 68 | # format of jan/01 00:00:00 which shows up on previous day's logs 69 | :if ([:len $currentTime] = 15 ) do={ 70 | :set currentTime ([:pick $currentTime 0 6]."/".[:pick [/system clock get date] 7 11]." ".[:pick $currentTime 7 15]) 71 | } 72 | } 73 | 74 | # if keepOutput is true, add this log entry to output 75 | :if ($keepOutput = true) do={ 76 | :set output ($output.$currentTime." ".$message."\r\n") 77 | } 78 | # if currentTime = lastTime, set keepOutput so any further logs found will be added to output 79 | # reset output in the case we have multiple identical date/time entries in a row as the last matching logs 80 | # otherwise, it would stop at the first found matching log, thus all following logs would be output 81 | :if ($currentTime = $lastTime) do={ 82 | :set keepOutput true 83 | :set output "" 84 | } 85 | } 86 | 87 | # if this is last log entry 88 | :if ($counter = ([:len $startBuf]-1)) do={ 89 | # If keepOutput is still false after loop, this means lastTime has a value, but a matching currentTime was never found. 90 | # This can happen if 1) The router was rebooted and matching logs stored in memory were wiped, or 2) An item is added 91 | # to the removeThese array that then ignores the last log that determined the lastTime variable. 92 | # This resets the comment to nothing. The next run will be like the first time, and you will get all matching logs 93 | :if ($keepOutput = false) do={ 94 | # if previous log was found, this will be our new lastTime entry 95 | :if ([:len $message] > 0) do={ 96 | :set output ($output.$currentTime." ".$message."\r\n") 97 | } 98 | } 99 | } 100 | :set counter ($counter + 1) 101 | } 102 | 103 | # If we have output, save new date/time, and send email 104 | if ([:len $output] > 0) do={ 105 | /system scheduler set [find name="$scheduleName"] comment=$currentTime 106 | :local TelegramMessage "*$SystemName alert - $OSversion* %0A$output" 107 | /tool fetch url=($TelegramURL . $TelegramMessage) keep-result=no 108 | # /log info "[LOGMON] New logs found" 109 | } 110 | -------------------------------------------------------------------------------- /Mikrotik Scripts/scheduledBackup: -------------------------------------------------------------------------------- 1 | #perform scheduled backup of Mikrotik Config and save to Google Drive (with the help of IFTTT) 2 | 3 | :log info "backup beginning now" 4 | 5 | :global TelegramToken 6 | :global TelegramGroupID 7 | :global TelegramURL 8 | 9 | :global OSversion 10 | :global OSversionShort 11 | :set OSversion [/system resource get version] 12 | :set OSversionShort [:pick $OSversion 0 [:find $OSversion " " -1]] 13 | 14 | :global SystemName 15 | :set SystemName [/system identity get name] 16 | 17 | [:pick [/system clock get time] 0 2] 18 | [:pick [/system clock get time] 3 5] 19 | 20 | :global backupfile ([/system identity get name] . "-" . \ 21 | [:pick [/system clock get date] 7 11] . [:pick [/system clock get date] 0 3] . [:pick [/system clock get date] 4 6] . "-" . [:pick [/system clock get time] 0 2] . [:pick [/system clock get time] 3 5] . "-rOS" . $OSversionShort) 22 | 23 | 24 | /system backup save name="$backupfile" 25 | /export file=$backupfile 26 | :log info "backup pausing for 10s" 27 | :delay 10s 28 | :log info "backup being emailed" 29 | 30 | /tool e-mail send to=trigger@applet.ifttt.com subject="#mikrotik $backupfile.backup" file="$backupfile.backup" start-tls=yes from=test@example.com 31 | 32 | :delay 10s 33 | 34 | /tool e-mail send to=trigger@applet.ifttt.com subject="#mikrotik $backupfile.rsc" file="$backupfile.rsc" start-tls=yes from=test@example.com 35 | 36 | :local TelegramMessage "*$SystemName alert - rOS$OSversion*%0ABackup to Drive Completed" 37 | /tool fetch url=($TelegramURL . $TelegramMessage) keep-result=no 38 | 39 | :log info "backup finished" -------------------------------------------------------------------------------- /Mikrotik Scripts/setGlobals: -------------------------------------------------------------------------------- 1 | #set global variables for use by other scripts - Schedule this to run frequently - once a minute or so. 2 | # update token and IDs with your own. 3 | 4 | :global TelegramToken "123456789:ABC-DEFghIJkLMNOPqrstUvWxYZ" 5 | :global TelegramGroupID "-098765432" 6 | :global TelegramURL "https://api.telegram.org/bot$TelegramToken/sendMessage?chat_id=$TelegramGroupID&parse_mode=Markdown&text=" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mikrotik 2 | a Collection of handy Mikrotik Scripts 3 | 4 | Many of these scripts rely on Telegram to send notifications to your telegram bot with variables set in the setGlobals script. More details below on how to activate your bot. 5 | 6 | 7 | [![Donate Bitcoin](https://user-images.githubusercontent.com/18201320/42027759-bdec89d8-7aca-11e8-91b4-f36648eb0ae7.png)](https://jacauc.github.io/donate-bitcoin/) 8 | 9 | 10 | 11 | # How to Create a Telegram bot 12 | 13 | Detailed instructions for setting up the Telegram Bot: https://www.forsomedefinition.com/automation/creating-telegram-bot-notifications/ 14 | 15 | Simplified instructions: 16 | 17 | 0. Use telegram 18 | 1. Chat with @botfather 19 | 2. Type /newbot 20 | 3. Give your bot a name... e.g. myMikrotik 21 | 4. Give your bot a username... e.g. MyMikrotikBot 22 | 5. You will get a message like this: 23 | 24 | ![2018-01-06_15-53-12](https://user-images.githubusercontent.com/18201320/34640372-fd5d8314-f2f9-11e7-9b86-c9a30ee889b2.png) 25 | 26 | 6. RECORD THE TOKEN SHOWN IN THE MESSAGE 27 | 7. Start a chat with your bot and type /start 28 | 8. Exit aforementioned chat and create a Telegram Group conversation. Call it something like "Mikrotik Notifications" 29 | 9. Invite your bot to the group. 30 | 10. Access the following page (insert your bot's TOKEN and remove the <<< and >>> characters): 31 | ``` 32 | https://api.telegram.org/bot<<>>/getUpdates 33 | ``` 34 | 11. Look for the group's ID as shown in green below. The group ID will normally be preceded by a minus sign. RECORD THE GROUPID: 35 | 36 | ![2018-01-06_16-06-23](https://user-images.githubusercontent.com/18201320/34640491-4faaa5f0-f2fc-11e7-853e-72cc5b1df323.png) 37 | 38 | 12. Do a test - You should now get a hello world message in the telegram group from your bot. If this didn't work, check steps 1-11 again. 39 | ``` 40 | https://api.telegram.org/bot<<>>/sendMessage?chat_id=<<<-GROUPID>>>&text=Hello+World 41 | ``` 42 | 13. Keep your GROUPID and TOKEN and replace the values accordingly in setGlobals Script. 43 | 44 | 45 | 46 | 47 | [![Donate Bitcoin](https://user-images.githubusercontent.com/18201320/42027759-bdec89d8-7aca-11e8-91b4-f36648eb0ae7.png)](https://jacauc.github.io/donate-bitcoin/) 48 | --------------------------------------------------------------------------------