Mailing List Archive

FortiGate - config fetch ends prematurely - hash-mark in config file
Noticed that a full config backup of some of our FortiGates have been failing due to a hash-mark (#) present in the configuration itself. FortiGates let you add comments to nearly any objects. The comment field is free-form, best I can tell, and lets you insert hash-mark characters. For example a service object had this configuration causing the rancid run to fail at the offending line of "set comment":

--------------
config firewall service custom
edit "TCP/UDP-4118-4122"
set proxy disable
set category ''
set protocol TCP/UDP/SCTP
set helper auto
set check-reset-range default
set comment "Ticket # 123456"
set color 1
set visibility enable
set iprange 0.0.0.0
set fqdn ''
set tcp-portrange 4118-4122
set udp-portrange 4118-4122
unset sctp-portrange
set tcp-halfclose-timer 0
set tcp-halfopen-timer 0
set tcp-timewait-timer 0
set udp-idle-timer 0
set session-ttl 0
next
end
--------------

After removing all offending characters from the firewall config the rancid-run completed fully and normally.

I've been playing around with fnrancid (3.8, build 3763) to try to find a way to accommodate this happening again, but with only partial success.

I changed the prompt setting code to the following:

--------------
# - FortiGate prompts end with either '#' or '$'. Further, they may
# be prepended with a '~' if the hostname is too long. Therefore,
# we need to figure out what our prompt really is.
if (!defined($prompt)) {
if ($_ =~ '^(.*) # ') {
$prompt = "$1 # ";
--------------

The above works great when the rancid user has root/super_admin permissions (hash-mark (#) prompt). Adjusting rancid to have non-root permissions with a dollar-sign ($) prompt and tacking on some additional code, rancid fails due to end of run not found.

--------------
# - FortiGate prompts end with either '#' or '$'. Further, they may
# be prepended with a '~' if the hostname is too long. Therefore,
# we need to figure out what our prompt really is.
if (!defined($prompt)) {
if ($_ =~ '^(.*) # ') {
$prompt = "$1 # ";
} else {
if ($_ =~ '^(.*) \$ ') {
$prompt = "$1 \$ ";
}
}
}
--------------

I tried some variations and either get the same error (end of run not found) or every config line is pre-pended with #. I even tried explicitly defining the firewall name inside $prompt against the firewall I am testing to bypass $1 expansion.

Anyone have ideas why this is failing? I added some debug statements and my regex matches and $prompt is being set as I would expect, but for some reason it's not matching when rancid runs.

Doing some testing, when the hostname in the prompt does get truncated, it stays the same regardless of what config level you enter.

Here is example of setting a 25-character hostname and then entering a few levels of config:

--------------
fortigate-firewall # config system global
fortigate-firewall (global) # set hostname 1234567890123456789012345
fortigate-firewall (global) # end
12345678901234567890~345 #
12345678901234567890~345 # config firewall service group
12345678901234567890~345 (group) # edit JD_TEST_GROUP
12345678901234567890~345 (JD_TEST_GROUP) # set comment "coding is fun"
12345678901234567890~345 (JD_TEST_GROUP) # end
12345678901234567890~345 #
--------------


Thanks,

-Aaron
Re: FortiGate - config fetch ends prematurely - hash-mark in config file [ In reply to ]
Wed, Oct 17, 2018 at 04:36:35AM +0000, Ni Ne:
> Noticed that a full config backup of some of our FortiGates have been failing due to a hash-mark (#) present in the configuration itself. FortiGates let you add comments to nearly any objects. The comment field is free-form, best I can tell, and lets you insert hash-mark characters. For example a service object had this configuration causing the rancid run to fail at the offending line of "set comment":
>
> --------------
> config firewall service custom
> edit "TCP/UDP-4118-4122"
> set proxy disable
> set category ''
> set protocol TCP/UDP/SCTP
> set helper auto
> set check-reset-range default
> set comment "Ticket # 123456"
> set color 1
> set visibility enable
> set iprange 0.0.0.0
> set fqdn ''
> set tcp-portrange 4118-4122
> set udp-portrange 4118-4122
> unset sctp-portrange
> set tcp-halfclose-timer 0
> set tcp-halfopen-timer 0
> set tcp-timewait-timer 0
> set udp-idle-timer 0
> set session-ttl 0
> next
> end
> --------------
>
> After removing all offending characters from the firewall config the rancid-run completed fully and normally.
>
> I've been playing around with fnrancid (3.8, build 3763) to try to find a way to accommodate this happening again, but with only partial success.
>
> I changed the prompt setting code to the following:
>
> --------------
> # - FortiGate prompts end with either '#' or '$'. Further, they may
> # be prepended with a '~' if the hostname is too long. Therefore,
> # we need to figure out what our prompt really is.
> if (!defined($prompt)) {
> if ($_ =~ '^(.*) # ') {
> $prompt = "$1 # ";
> --------------
>
> The above works great when the rancid user has root/super_admin permissions (hash-mark (#) prompt). Adjusting rancid to have non-root permissions with a dollar-sign ($) prompt and tacking on some additional code, rancid fails due to end of run not found.
>
> --------------
> # - FortiGate prompts end with either '#' or '$'. Further, they may
> # be prepended with a '~' if the hostname is too long. Therefore,
> # we need to figure out what our prompt really is.
> if (!defined($prompt)) {
> if ($_ =~ '^(.*) # ') {
> $prompt = "$1 # ";
> } else {
> if ($_ =~ '^(.*) \$ ') {
> $prompt = "$1 \$ ";
> }
> }
> }
> --------------
>
> I tried some variations and either get the same error (end of run not found) or every config line is pre-pended with #. I even tried explicitly defining the firewall name inside $prompt against the firewall I am testing to bypass $1 expansion.
>
> Anyone have ideas why this is failing? I added some debug statements and my regex matches and $prompt is being set as I would expect, but for some reason it's not matching when rancid runs.
>
> Doing some testing, when the hostname in the prompt does get truncated, it stays the same regardless of what config level you enter.
>
> Here is example of setting a 25-character hostname and then entering a few levels of config:

is the content before the '~' consistent? ie: the first 20 characters?
and its always followed by a space? and possibly a sub-level in
parentheses?

IOS does similar junk, so we have an art for this that just needs to be
tailored.

> --------------
> fortigate-firewall # config system global
> fortigate-firewall (global) # set hostname 1234567890123456789012345
> fortigate-firewall (global) # end
> 12345678901234567890~345 #
> 12345678901234567890~345 # config firewall service group
> 12345678901234567890~345 (group) # edit JD_TEST_GROUP
> 12345678901234567890~345 (JD_TEST_GROUP) # set comment "coding is fun"
> 12345678901234567890~345 (JD_TEST_GROUP) # end
> 12345678901234567890~345 #
> --------------
>
>
> Thanks,
>
> -Aaron
>

> _______________________________________________
> Rancid-discuss mailing list
> Rancid-discuss@shrubbery.net
> http://www.shrubbery.net/mailman/listinfo/rancid-discuss

_______________________________________________
Rancid-discuss mailing list
Rancid-discuss@shrubbery.net
http://www.shrubbery.net/mailman/listinfo/rancid-discuss