最後更新: 2021-11-18
目錄
- Configure Script
- Permission
- Netwatch
- Beep
- Comments
- Script Sytax
- Flow Control
- Variables
- Log
- 輸出螢幕
- Useful Script
Configure Script
# Cli
/system script # add, remove, enable, disable
# Add
/system script
add name=notify-ipsec-down source={/tool e-mail send to=tim@mydomain subject="ipsec down" body="ipsec down" start-tls=no}
system script> print [detail] [brief]
Flags: I - invalid 0 name="notify-ipsec-down" owner="admin" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive run-count=0 source=/tool e-mail send to=tim@mydomain subject="ipsec down" body="ipsec down" start-tls=no
# Run Script
/system script run NAME
OR
/system script run ID
Permission
dont-require-permissions (yes | no; Default: no)
Bypass permissions check when script is being executed,
useful when scripts are being executed from services that have limited permissions
such as Netwatch
policy
- ftp - can log on remotely via ftp and send and retrieve files from the router
- read - can retrieve the configuration
- test - can run ping, traceroute, bandwidth test
- policy - manage user policies, add and remove user
- reboot - can reboot the router
- password - change passwords
- sensitive - allows to change "hide sensitive" parameter
- sniff - can run sniffer, torch etc
- write - can change the configuration
- ...
Netwatch
Netwatch monitors state of hosts on the network.
It does so by sending ICMP pings to the list of specified IP addresses.
/tool netwatch
- down-script (string; Default: )
- host (IP; Default: 0.0.0.0)
- interval (time; Default: 1m)
- timeout (time; Default: 1s)
- up-script (string; Default: )
* Since RouterOS v6.42 Netwatch is limited to read,write,test,reboot script policies.
(It is possible to disable permission checking for RouterOS scripts "dont-require-permissions")
應用:
- Failover Default Gateway
Beep
script no need permission
i.e.
Super Mario Bross Theme Sound Beep script
:beep frequency=660 length=100ms; :delay 150ms; :beep frequency=660 length=100ms; :delay 300ms; :beep frequency=660 length=100ms; :delay 300ms; :beep frequency=510 length=100ms; :delay 100ms; :beep frequency=660 length=100ms; :delay 300ms; :beep frequency=770 length=100ms; :delay 550ms; :beep frequency=380 length=100ms; :delay 575ms; ...
Comments
Whitespace or any other symbols are not allowed before hash symbol.
# this is a comment # bad comment
If (#) character appear inside string it is not considered a comment.
Script Sytax
Syntax:
[prefix] [path] command [uparam] [param=[value]] .. [param=[value]]
prefix
":" or "/" character which indicates if command is "global command" or path.
global command: global, local, delay, put, log, put, set ...
path
relative path to the desired menu level. May or may not be required.
* The end of command line is represented by the token “;” or NEWLINE.
* Single command inside (), [] or {} does not require any end of command character.
Varable
# Set
:global a 5;
:local host1 "8.8.8.8";
# Printer to screen
:put $a;
Logical Operators
"!"
"&&"
"||"
"in"
:put (1.1.1.1/32 in 1.0.0.0/8);
Concatenation Operators
"." concatenates two strings
:put ("concatenate" . " " . "string");
"," concatenates two arrays or adds element to array
:put ({1;2;3} , 5 );
Expressions inside strings
# By using $[] and $()
i.e.
subject="$[/system clock get time]"
Operators
"$" substitution operator
"[]" command substitution. Can contain only single command line
"()" sub expression or grouping operator
Flow Control
if ... else ...
:if (<condition>) do={<commands>} else={<commands>} <expression>
:local RemoteIP "10.3.0.1" :if ([/ping $RemoteIP count=3] = 0) do={ /system script run notify-vpn-down; }
for
* "=" 兩邊不可以有空格
:for i from=0 to=9 do={ :put $i }
Variables
Scripting language has two types of variables:
- global - accessible from all scripts created by current user, defined by global keyword;
-
local - accessible only within the current scope, defined by local keyword.
Each local scope is enclosed in curly braces "{ }"
* Every variable, except for built in RouterOS variables, must be declared before usage
* Variable names are case sensitive.
* Do not define global variables inside local scopes
{ :local a 3; { :global b 4; } :put ($a+$b); }
Code:
[方式1]
:global myVar; :set myVar "my value"; :put $myVar;
[方式2]
:global RemoteIP 192.168.1.1 :put $RemoteIP
Log
Syntax
:log <topic> <message>
topic: debug, info, warning and error(紅色字)
i.e.
:log warning test123 # 藍色字
輸出螢幕
:put [get [find list=test] value-name=address]
i.e.
# print "test msg" on console
:put "test msg"
# "[...]" 係成功包的數量
:put [/ping 192.168.1.1 count=3]
SEQ HOST SIZE TTL TIME STATUS 0 192.168.1.1 56 64 2ms 1 192.168.1.1 56 64 2ms 2 192.168.1.1 56 64 3ms sent=3 received=3 packet-loss=0% min-rtt=2ms avg-rtt=2ms max-rtt=3ms 3
Useful Script
[1] Keep ping the tunnel every second
/system script
add name=ping-ipsec-tunnel source={ # BC /ping 192.168.1.254 interface=bridge1 count=1; # CB /ping 192.168.3.254 interface=bridge1 count=1; }
/system scheduler
add disabled=no interval=1s name="ping-ipsec-tunnel" on-event=ping-ipsec-tunnel
[2] Script to mon Ipsec
# config mail server
/tool e-mail set from="R1@mydomain" address="x.x.x.x" port="1025"
# setup script
/system script
[1] Script: notify-ipsec-down
add name=notify-ipsec-down source={/tool e-mail send to=sysadmin@mydomain subject="VPN Down - XXX" body="$[/system clock get time]" start-tls=no}
Test mail
/system script run notify-ipsec-down
[2] Script: ipsec-monitor
# 在 10s 內每 2s ping 1 次 remote, 如果有 4 次 fail 就 call script "ipsec-down"
add name=ipsec-monitor source={ :local RemoteIP "192.168.1.1" :local i 0; :local F 0; :for i from=1 to=5 do={ :if ([/ping $RemoteIP interface=bridge1 count=1]=0) do={:set F ($F + 1)} :delay 2; }; :if (($F>3)) do={ :put "sent mail to admin" /system script run ipsec-down; } }
簡化版
# "[/ping...]" 的 return 係成功包的數量
# 以下設定係 3 個包全失才行 script
add name=ipsec-monitor source={ :local RemoteIP "192.168.1.1" :if ([/ping $RemoteIP interface=bridge1 count=3] = 0) do={ /system script run notify-ipsec-down; } }
# config scheduler (run script(ipsec-monitor) minutely)
# 每分鐘行一次 "ipsec-monitor"
/system scheduler
add disabled=no interval=1m name="Mon-IPSEC-Conn" on-event=ipsec-monitor
Doc
http://wiki.mikrotik.com/wiki/Manual:Scripting