Configuration Mismatch-bluecoat-sgos

Configuration Mismatch-bluecoat-sgos

Vendor: bluecoat

OS: sgos

Description:
Indeni can verify that certain lines appear in the “show configuration” output for the device." +
" The required configuration lines need to be entered in Indeni Rules > Configuration tab. " +
" “*” can be used as a wildcard for a single word or numeric value.

Remediation Steps:
Modify the device’s configuration as required.

How does this work?
Indeni logs in over SSH and executes show advanced-url /cli/show/configuration.

Why is this important?
Pulling the configuration of the devices enables Indeni to apply compliance checks on the configuration to tell the user when a non-optimal configuration has been detected.

Without Indeni how would you find this?
Login via HTTPS (Port 8082) to the Bluecoat ProxySG and go to the /cli/show/configuration path.

bluecoat-show-configuration

name: bluecoat-show-configuration
description: Get the running configuration of the device
type: monitoring
monitoring_interval: 60 minutes
requires:
    vendor: bluecoat
    os.name: sgos
comments:
    configuration-content:
        why: |
            Pulling the configuration of the devices enables Indeni to apply compliance checks on the configuration to tell the user when a non-optimal configuration has been detected.
        how: |
            Indeni logs in over SSH and executes show advanced-url /cli/show/configuration.
        can-with-snmp: false
        can-with-syslog: false
    bluecoat-allowed-ips:
        why: |
            It is recommended to restrict which IP addresses are allowed to access the ProxySG management. Indeni will alert if there is no restriction on which IP addresses can connect to the management.
        how: |
            Indeni logs in over SSH and executes show advanced-url /cli/show/configuration.
        can-with-snmp: false
        can-with-syslog: false
    security-allowed-access:
        why: |
            This metric shows the IP addresses which are allowed to access the ProxySG management.
        how: |
            Indeni logs in over SSH and executes show advanced-url /cli/show/configuration.
        can-with-snmp: false
        can-with-syslog: false
    password-min-length-too-short:
        why: |
            The ProxySG does not enforces password complexity by default, therefore it is recommended to deploy a password policy with at least 14 characters in length.
        how: |
            Indeni logs in over SSH and executes show advanced-url /cli/show/configuration.
        can-with-snmp: true
        can-with-syslog: false

steps:
-   run:
        type: SSH
        command: show advanced-url "/cli/show/configuration"
    parse:
        type: AWK
        file: show-configuration.parser.1.awk

ConfigurationComplianceCheckRule

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

import com.indeni.ruleengine.Scope.{Scope, ScopeValueHelper}
import com.indeni.ruleengine.expressions.core._
import com.indeni.ruleengine.expressions.data.{MultiSnapshotExtractScalarExpression, SelectSnapshotsExpression, SelectTagsExpression, SnapshotExpression}
import com.indeni.ruleengine.expressions.scope.ScopableExpression
import com.indeni.ruleengine.expressions.utility.IsEmptyExpression.IsEmptyExpressionHelper
import com.indeni.ruleengine.expressions.utility._
import com.indeni.ruleengine.expressions.{Expression, conditions}
import com.indeni.server.common.AlertNotificationSettings
import com.indeni.server.common.AlertNotificationSettings._
import com.indeni.server.common.data.conditions.True
import com.indeni.server.params.ParameterDefinition
import com.indeni.server.params.ParameterDefinition.UIType
import com.indeni.server.rules._
import com.indeni.server.rules.config.expressions.DynamicParameterExpression
import com.indeni.server.rules.library.{ConditionalRemediationSteps, PerDeviceRule, RuleHelper}
import com.indeni.server.sensor.models.managementprocess.alerts.dto.AlertSeverity


/**
  * Created by amir on 19/02/2017.
  * Updated for wild card resolution by tomas on 2018 01 20.
  */
case class CrossVendorConfigurationComplianceCheckRule() extends
  PerDeviceRule with RuleHelper {

  private val linesParameterName = "config_lines_to_look_for"
  private val linesParameter = new ParameterDefinition(
    linesParameterName,
    "",
    "Configuration Lines Needed (multi-line)",
    "List the configuration commands that need to show in the output of \"show configuration\".",
    UIType.MULTILINE_TEXT,
    "")

  override def expressionTree(context: RuleContext): StatusTreeExpression = {
    val linesExpected = DynamicParameterExpression.withConstantDefault(linesParameter.getName, Seq[String]()).withLazy
    val snapshotKey = "configuration-content"
    val missingResolved = new SeqDiffWithoutOrderExpression[String](
      MultiSnapshotExtractScalarExpression(
        SnapshotExpression(snapshotKey)
          .asMulti()
          .mostRecent()
          .value(),
        "line"), linesExpected) {

      // Modification for a wildcard "*" resolution.
      override def eval(time: Long): SeqDiff[String] = {
        val actualSet = actual.eval(time).toSet
        val expectedSetResolved = expected.eval(time).toSet.map { x: String => x.replace("*", "\\S+").r.anchored }
        val redundant = Set[String]()
        val missingChecked = {
          for {
            i <- expectedSetResolved
            j <- actualSet
          } yield i.findFirstIn(j) match {
            case Some(_) => Some(i)
            case _ => None
          }
        }.flatten.map(_.toString())
        val expectedSet = expectedSetResolved.map(_.toString())
        val missing = (expectedSetResolved.map(_.toString()) diff missingChecked).map(_.replace("\\S+", "*"))
        SeqDiff(expectedSet, missing, redundant)
      }
    }.missings.withLazy

    val missingLineHeadline = new ScopableExpression[String] {
      override protected def evalWithScope(time: Long, scope: Scope): String =
        scope.getVisible(CrossVendorConfigurationComplianceCheckRule.ConfigurationTag).get.toString

      override def args: Set[Expression[_]] = Set()
    }

    StatusTreeExpression(
      // Which objects to pull (normally, devices)
      SelectTagsExpression(context.metaDao, Set(DeviceKey), True),

      // What constitutes an issue
      StatusTreeExpression(
        // The snapshot we check the test condition against:
        SelectSnapshotsExpression(context.snapshotsDao, Set(snapshotKey)).multi(),

        // The condition which, if true, we have an issue. Checked against the snapshots we've collected
        missingResolved.nonEmpty,

        multiInformers =
          Set(
            MultiIssueInformer(
              missingLineHeadline,
              EMPTY_STRING,
              "Missing lines"
            ).iterateOver(collection = missingResolved,
              scopeKey = CrossVendorConfigurationComplianceCheckRule.ConfigurationTag,
              condition = conditions.True)
          )

        // Details of the alert itself
      ).withRootInfo(
        getHeadline(),
        ConstantExpression("Some configuration lines that should be defined are not:\n" +
          "Indeni has found that some lines are missing. These are listed below."),
        ConditionalRemediationSteps("Modify the device's configuration as required.")
      ).asCondition()
    ).withoutInfo()
  }

  /**
    * @return The rule's metadata.
    */
  override def metadata: RuleMetadata =
    RuleMetadata.builder(
      "ConfigurationComplianceCheckRule",
      "Compliance Check: Configuration Mismatch",
      "Indeni can verify that certain lines appear in the \"show configuration\" output for the device." +
        " The required configuration lines need to be entered in Indeni Rules > Configuration tab. " +
        " \"*\" can be used as a wildcard for a single word or numeric value. ",
      AlertSeverity.ERROR,
      categories = Set(RuleCategory.VendorBestPractices),
      deviceCategory = DeviceCategory.ComplianceCheck).defaultAction(
      AlertNotificationSettings(NONE))
      .configParameter(linesParameter)
      .disableGlobalRuleSet(true)
    .build()
}


object CrossVendorConfigurationComplianceCheckRule {
  val ConfigurationTag = "ConfigurationTag"
}