Static routing table does not match across cluster members-fortinet-FortiOS

error
high-availability
fortios
fortinet
Static routing table does not match across cluster members-fortinet-FortiOS
0

#1

Static routing table does not match across cluster members-fortinet-FortiOS

Vendor: fortinet

OS: FortiOS

Description:
Indeni will identify when two devices are part of a cluster and alert if their static routing tables are different.

Remediation Steps:
Ensure the static routing table matches across devices in a cluster.

How does this work?
This script logins to the Fortinet Firewall and retrieves the output of the “get router info routing-table static” command. The output includes a table with the device’s configured static routes.

Why is this important?
Capture the static route entries that are configured on the Fortinet Firewall. It is chekced if the next hop IP address set to the static routes can be resolved to a MAC address via ARP . If this is not the case, an alert would be generated.

Without Indeni how would you find this?
It is possible to poll this data through SNMP but additional external logic would be required to correlate the static routes table with the arp table entries and resolved next hop IP addresses.

fortios-get-router-info-routing-table-static

#! META
name: fortios-get-router-info-routing-table-static
description: Fortinet Firewall static route entries 
type: monitoring
monitoring_interval: 10 minutes
requires:
    vendor: fortinet
    os.name: FortiOS
    product: firewall
    vdom_enabled: false
    vdom_root: true

# --------------------------------------------------------------------------------------------------
# The script publish the following metrics
#
# [static-routing-table]           [complex array ]
# --------------------------------------------------------------------------------------------------


#! COMMENTS
static-routing-table:
    why: |
       Capture the static route entries that are configured on the Fortinet Firewall. It is chekced if the next hop IP
       address set to the static routes can be resolved to a MAC address via ARP . If this is not the case, an alert
       would be generated.
    how: |
       This script logins to the Fortinet Firewall and retrieves the output of the "get router info routing-table
       static" command. The output includes a table with the device's configured static routes.
    without-indeni: |
       It is possible to poll this data through SNMP but additional external logic would be required to correlate the
       static routes table with the arp table entries and resolved next hop IP addresses.
    can-with-snmp: true
    can-with-syslog: false


#! REMOTE::SSH
get router info routing-table static

#! PARSER::AWK
BEGIN{
    # Store mask in
    table_routing_index = 0
}

# Parse all the needed info ('network', 'mask' & 'next-hop') and store them in the table
#S*      0.0.0.0/0 [10/0] via 212.205.216.193, wan1
#S       10.0.0.0/8 [10/0] via 10.10.8.145, lan
#S       1.1.1.1/32 [10/0] is directly connected, port1
/^S/{

    # Ensure that the $5 is ip and not text
    if($5 ~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/){

        # Increase index of table
        table_routing_index++

        # Reading network and mask. Example is "10.0.0.0/8"
        ip_mask = $2
        split(ip_mask, ip_mask_array, "/")
        table_routing[table_routing_index, "network"] = ip_mask_array[1]
        table_routing[table_routing_index, "mask"] = ip_mask_array[2]

        # Storing next-hop
        next_hop = $5

        # Removing ','
        gsub(",", "", next_hop)
        table_routing[table_routing_index, "next-hop"] = next_hop

    }
}

END {
    writeComplexMetricObjectArray("static-routing-table", null, table_routing)
}




static_routing_table_comparison_non_vsx

package com.indeni.server.rules.library.templatebased.crossvendor

import com.indeni.server.common.data.conditions.{Equals => DataEquals}
import com.indeni.server.rules.RuleContext
import com.indeni.server.rules.library._

/**
  *
  */
case class static_routing_table_comparison_non_vsx(context: RuleContext) extends SnapshotComparisonTemplateRule(context,
  ruleName = "static_routing_table_comparison_non_vsx",
  ruleFriendlyName = "Clustered Devices (Non-VS): Static routing table does not match across cluster members",
  ruleDescription = "Indeni will identify when two devices are part of a cluster and alert if their static routing tables are different.",
  metricName = "static-routing-table",
  isArray = true,
  metaCondition = !DataEquals("vsx", "true"),
  baseRemediationText = "Ensure the static routing table matches across devices in a cluster.",
  alertDescription = "Devices that are part of a cluster must have the same static routing tables. Review the differences below.\n\nThis alert was added per the request of <a target=\"_blank\" href=\"http://il.linkedin.com/pub/itzik-assaraf/2/870/1b5\">Itzik Assaraf</a> (Leumi Card)."
  )(
  ConditionalRemediationSteps.VENDOR_CP -> "Use the \"show configuration\" command in clish to compare the calls to \"set static-route\".",
  ConditionalRemediationSteps.OS_NXOS ->
    """|
      |1. Execute the "show ip route static" command to display the current contents of the  static routes installed to the routing table.
      |2. Compare the static route config between the peer switches with the show run | i "ip route" command
      |NOTE: The static routes configured between the peer switches may be different in case of orphan devices without need of redundancy between the vPC peer switches
      |3. For more information please review the next Cisco configuration guide:
      |https://www.cisco.com/c/en/us/td/docs/switches/datacenter/sw/5_x/nx-os/unicast/configuration/guide/l3_cli_nxos/l3_route.html
    """.stripMargin
)
{override val deviceCondition = generateDevicePassiveAndPassiveLinkStateCondition(context.tsDao)}


case class static_routing_table_comparison_vsx(context: RuleContext) extends SnapshotComparisonTemplateRule(context,
  ruleName = "static_routing_table_comparison_vsx",
  ruleFriendlyName = "Clustered Devices (VS): Static routing table does not match across cluster members",
  ruleDescription = "Indeni will identify when two devices are part of a cluster and alert if their static routing tables are different.",
  metricName = "static-routing-table",
  isArray = true,
  descriptionMetricTag = "vs.name",
  metaCondition = DataEquals("vsx", "true"),
  alertDescription = "Devices that are part of a cluster must have the same static routing tables. Review the differences below.\n\nThis alert was added per the request of <a target=\"_blank\" href=\"http://il.linkedin.com/pub/itzik-assaraf/2/870/1b5\">Itzik Assaraf</a> (Leumi Card).",
  baseRemediationText = "Ensure the static routing table matches across devices in a cluster.")(
  ConditionalRemediationSteps.VENDOR_CP -> "Use the \"show configuration\" command in clish to compare the calls to \"set static-route\".",
  ConditionalRemediationSteps.OS_NXOS ->
    """|
       |1. Execute the "show ip route static" command to display the current contents of the  static routes installed to the routing table.
       |2. Compare the static route config between the peer switches with the show run | i "ip route" command
       |NOTE: The static routes configured between the peer switches may be different in case of orphan devices without need of redundancy between the vPC peer switches
       |3. For more information please review the next Cisco configuration guide:
       |https://www.cisco.com/c/en/us/td/docs/switches/datacenter/sw/5_x/nx-os/unicast/configuration/guide/l3_cli_nxos/l3_route.html
    """.stripMargin
)
{override val deviceCondition = generateDevicePassiveAndPassiveLinkStateCondition(context.tsDao)}