Example: Create custom IPS signatures and add them to a custom group.
Script:
#!
#Run on FortiOS v5.00
#This script will create custom ips signatures and #change the settings for the custom ips signatures
puts [exec “# This is an example Tcl script to create custom ips signatures and change the settings for the custom ips signatures on a FortiGate\n” “# ” 15 ]
#Enter custom ips signatures, signature names are the
#names of array elements set custom_sig(c1) {“F-SBID(–protocol icmp;–icmp_type 10; )”} set custom_sig(c2) {“F-SBID(–protocol icmp;–icmp_type 0; )”}
#Enter custom ips settings set custom_rule(c1) {{status enable} {action block} {log enable} {log-packet} {severity high}}
set custom_rule(c2) {{status enable} {action pass} {log} {log-packet disable} {severity low}}
#procedure to execute FortiGate command proc fgt_cmd cmd {
puts -nonewline [exec “$cmd\n” “# “]
}
#procedure to set a series of key-value pairs proc set_kv kv_list { foreach kv $kv_list { set len [llength $kv]
if {$len == 0} {
continue
} elseif {$len == 1} { fgt_cmd “unset [lindex $kv 0]”
} else {
fgt_cmd “set [lindex $kv 0] [lindex $kv 1]”
}
} }
#config ips custom—begin fgt_cmd “config vdom” fgt_cmd “edit root” fgt_cmd “config ips custom”
foreach sig_name [array names custom_sig] { fgt_cmd “edit $sig_name”
fgt_cmd “set signature $custom_sig($sig_name)” fgt_cmd “next”
}
fgt_cmd “end”
#config ips custom settings—begin foreach rule_name [array names custom_rule] { fgt_cmd “config ips custom” fgt_cmd “edit $rule_name” set_kv $custom_rule($rule_name) fgt_cmd “end”
}
fgt_cmd “end”
#config ips custom settings—end
Output:
Starting log (Run on device)
FortiGate-VM64 # config vdom FortiGate-VM64 (vdom) # edit root
current vf=root:0
FortiGate-VM64 (root) # config ips custom FortiGate-VM64 (custom) # edit c1
set signature “F-SBID(–protocol icmp;–icmp_type 10; )”
FortiGate-VM64 (c1) # set signature “F-SBID(–protocol icmp;–icmp_type 10; )”
FortiGate-VM64 (c1) # next
FortiGate-VM64 (custom) # edit c2
FortiGate-VM64 (c2) # set signature “F-SBID(–protocol icmp;–icmp_type 0; )”
FortiGate-VM64 (c2) # next
FortiGate-VM64 (custom) # end
FortiGate-VM64 (root) # config ips custom
FortiGate-VM64 (custom) # edit c1
FortiGate-VM64 (c1) # set status enable
FortiGate-VM64 (c1) # set action block
FortiGate-VM64 (c1) # set log enable
FortiGate-VM64 (c1) # unset log-packet
FortiGate-VM64 (c1) # set severity high
FortiGate-VM64 (c1) # end
FortiGate-VM64 (root) # config ips custom
FortiGate-VM64 (custom) # edit c2
FortiGate-VM64 (c2) # set status enable
FortiGate-VM64 (c2) # set action pass
FortiGate-VM64 (c2) # unset log
FortiGate-VM64 (c2) # set log-packet disable
FortiGate-VM64 (c2) # set severity low
FortiGate-VM64 (c2) # end
FortiGate-VM64 (root) # end
FortiGate-VM64 #
——- The end of log ———-
Variations:
None.
Tcl file IO
You can write to and read from files using Tcl scripts. For security reasons there is only one directory on the
FortiManager where scripts can access files. For this reason, there is no reason to include the directory in the file name you are accessing. For example “/var/temp/myfile” or “~/myfile” will cause an error, but “myfile” or “/myfile” is OK.
The Tcl commands that are supported for file IO are: file, open, gets, read, tell, seek, eof, flush, close, fcopy, fconfigure, and fileevent.
The Tcl file command only supports delete subcommand, and does not support the -force option.
There is 10MB of diskspace allocated for Tcl scripts. An error will be reported if this size is exceeded.
These files will be reset when the following CLI commands are run: exec format, exec reset partition, or exec resetall. The files will not be reset when the firmware is updated unless otherwise specified.
To write to a file: | |
Script | #!
set somefile [open “tcl_test” w] puts $somefile “Hello, world!” close $somefile |
To read from a file: | |
Script #!
set otherfile [open “tcl_test” r] while {[gets $otherfile line] >= 0} { puts [string length $line] } close $otherfile |
|
Output Hello, world! |
These two short scripts write a file called tcl_test and then read it back.
Line 3 in both scripts opens the file either for reading (r) or writing (w) and assigns it to a filehandle (somefile or otherfile). Later in the script when you see these filehandles, its input or output passing to the open file.
When reading from the file, lines 4 and 5 loop through the file line by line until it reaches the end of the file. Each line that is read is put to the screen.
Both scripts close the file before they exit.
Troubleshooting Tips
This section includes suggestions to help you find and fix problems you may be having with your scripts.
- Make sure the commands you are trying to execute are valid for the version of FortiOS running on your target FortiGate device.
- You should always use braces when evaluating code that may contain user input, to avoid possible security breaches. To illustrate the danger, consider this interactive session:
% set userinput {[puts DANGER!]}
[puts DANGER!] % expr $userinput == 1 DANGER!
0
% expr {$userinput == 1}
0
In the first example, the code contained in the user-supplied input is evaluated, whereas in the second the braces prevent this potential danger. As a general rule, always surround expressions with braces, whether using expr directly or some other command that takes an expression.
- A number that includes a leading zero or zeros, such as 0500 or 0011, is interpreted as an octal number, not a decimal number. So 0500 is actually 320 in decimal, and 0011 is 9 in decimal.
- There is a limit to the number of scripts allowed on the FortiManager unit. Try removing an old script before trying to save your current one.
- Using the Tcl command “catch” you can add custom error messages in your script to alert you to problems during the script execution. When catch encounters an error it will return 1, but if there is no error it will return 0. For example:
if { [catch {open $someFile w} fid] } {
puts stderr “Could not open $someFile for writing\n$fid” exit 1 ;# error opening the file! } else {
# put the rest of your script here
}
Use Tcl script to access FortiManager’s device database or ADOM database
You can use Tcl script to access FortiManager’s device database or ADOM database (local database). See the examples below:
Example 1: Run the Tcl script on an ADOM database for a specify policy package. For example, creating new a policy or object:
Syntax | puts [exec_ondb “/adom/<adom_name>/pkg/<pkg_fullpath>” “embedded cli commands” “#
“] |
Usage | puts [exec_ondb “/adom/52/pkg/default” ” config firewall address edit port5_address next end
” “# “] |
Example 2: Run the Tcl script on the current ADOM database for a specify policy package. For example, creating a new policy and object:
Syntax | puts [exec_ondb “/adom/./pkg/<pkg_fullpath>” “embedded cli commands” “# “] | |
or | puts [exec_ondb “/pkg/<pkg_fullpath>” “embeded cli commands” “# “] | |
Usage | puts [exec_ondb “/adom/./pkg/default” ” config firewall address edit port5_address next end
” “# “] |
Example 3: Run Tcl script on a specific device in an ADOM:
Syntax | puts [exec_ondb “/adom/<adom_name>/device/<dev_name>” “embedded cli commands” “#
“] |
|
Usage | puts [exec_ondb “/adom/v52/device/FGT60CA” ” config global config system global set admintimeout 440
end end ” “# “] |
|
Example 4: Run Tcl script on all devices in an ADOM:
Syntax | puts [exec_ondb “/adom/<adom_name>/device/.” “embedded cli commands” “# “] |
Usage | puts [exec_ondb “/adom/v52/device/.” ” config global config system global set admintimeout 440
end end ” “# “] |