使用自定义规则定制检测器

编辑

自定义规则 – 或 Kibana 中称之为的作业规则 – 使您能够根据特定领域的知识更改异常检测器的行为。

自定义规则描述了何时检测器应采取某种操作而不是遵循其默认行为。为了指定规则的何时,它使用 scope(范围)和 conditions(条件)。您可以将 scope 视为规则的类别规范,而 conditions 是数值部分。一个规则可以有一个范围,一个或多个条件,或者范围和条件的组合。有关规范详细信息的完整列表,请参阅创建异常检测作业 API 中的 custom_rules 对象

指定自定义规则范围

编辑

假设我们正在配置一个异常检测作业,以检测 DNS 数据外泄。我们的数据包含字段“subdomain”(子域名)和“highest_registered_domain”(最高注册域名)。我们可以使用一个类似于 high_info_content(subdomain) over highest_registered_domain 的检测器。如果我们运行这样的作业,我们可能会在出于信任理由经常使用的域上发现大量异常。作为安全分析师,我们对这些异常不感兴趣。理想情况下,我们可以指示检测器跳过我们认为安全的域的结果。使用具有范围的规则可以使我们实现这一目标。

首先,我们需要创建一个安全域的列表。这些列表在机器学习中称为过滤器。过滤器可以在异常检测作业之间共享。

您可以在 Kibana 的 异常检测 > 设置 > 过滤器列表 中或使用 put filter API 创建过滤器。

PUT _ml/filters/safe_domains
{
  "description": "Our list of safe domains",
  "items": ["safe.com", "trusted.com"]
}

现在,我们可以创建我们的异常检测作业,为 highest_registered_domain 字段指定使用 safe_domains 过滤器的范围。

PUT _ml/anomaly_detectors/dns_exfiltration_with_rule
{
  "analysis_config" : {
    "bucket_span":"5m",
    "detectors" :[{
      "function":"high_info_content",
      "field_name": "subdomain",
      "over_field_name": "highest_registered_domain",
      "custom_rules": [{
        "actions": ["skip_result"],
        "scope": {
          "highest_registered_domain": {
            "filter_id": "safe_domains",
            "filter_type": "include"
          }
        }
      }]
    }]
  },
  "data_description" : {
    "time_field":"timestamp"
  }
}

随着时间的推移,我们看到更多的数据和更多的结果,我们可能会遇到想要添加到过滤器中的新域。我们可以在 Kibana 的 异常检测 > 设置 > 过滤器列表 中或使用 update filter API 来完成此操作。

POST _ml/filters/safe_domains/_update
{
  "add_items": ["another-safe.com"]
}

请注意,我们可以在 scope 中使用任何 partition_field_nameover_field_nameby_field_name 字段。

在以下示例中,我们为多个字段设置范围

PUT _ml/anomaly_detectors/scoping_multiple_fields
{
  "analysis_config" : {
    "bucket_span":"5m",
    "detectors" :[{
      "function":"count",
      "partition_field_name": "my_partition",
      "over_field_name": "my_over",
      "by_field_name": "my_by",
      "custom_rules": [{
        "actions": ["skip_result"],
        "scope": {
          "my_partition": {
            "filter_id": "filter_1"
          },
          "my_over": {
            "filter_id": "filter_2"
          },
          "my_by": {
            "filter_id": "filter_3"
          }
        }
      }]
    }]
  },
  "data_description" : {
    "time_field":"timestamp"
  }
}

当所有三个范围字段的值都包含在引用的过滤器中时,这样的检测器将跳过结果。

指定自定义规则条件

编辑

假设一个检测器查找 CPU 利用率中的异常。假设一台机器空闲足够长的时间,CPU 的微小变化可能会导致异常结果,其中 actual 值很小,例如 0.02。鉴于我们对 CPU 利用率行为方式的了解,我们可能会确定具有如此小的实际值的异常不值得调查。

现在让我们配置一个异常检测作业,其中包含一个规则,该规则跳过 CPU 利用率低于 0.20 的结果。

PUT _ml/anomaly_detectors/cpu_with_rule
{
  "analysis_config" : {
    "bucket_span":"5m",
    "detectors" :[{
      "function":"high_mean",
      "field_name": "cpu_utilization",
      "custom_rules": [{
        "actions": ["skip_result"],
        "conditions": [
          {
            "applies_to": "actual",
            "operator": "lt",
            "value": 0.20
          }
        ]
      }]
    }]
  },
  "data_description" : {
    "time_field":"timestamp"
  }
}

当存在多个条件时,它们会与逻辑 AND 组合。当我们希望规则应用于一个范围时,这很有用。我们创建一个具有两个条件的规则,每个条件对应于所需范围的一端。

这是一个示例,其中计数检测器跳过计数大于 30 且小于 50 的结果

PUT _ml/anomaly_detectors/rule_with_range
{
  "analysis_config" : {
    "bucket_span":"5m",
    "detectors" :[{
      "function":"count",
      "custom_rules": [{
        "actions": ["skip_result"],
        "conditions": [
          {
            "applies_to": "actual",
            "operator": "gt",
            "value": 30
          },
          {
            "applies_to": "actual",
            "operator": "lt",
            "value": 50
          }
        ]
      }]
    }]
  },
  "data_description" : {
    "time_field":"timestamp"
  }
}

作业生命周期中的自定义规则

编辑

自定义规则仅影响在应用规则后创建的结果。假设我们配置了一个异常检测作业,并且它已经运行了一段时间。在观察其结果后,我们决定可以采用规则来消除一些不值得关注的结果。我们可以使用 update anomaly detection job API 来执行此操作。但是,我们添加的规则仅对从我们添加规则开始创建的任何结果生效。过去的结果不受影响。

使用自定义规则与过滤数据

编辑

似乎使用规则只是另一种过滤馈送到异常检测作业的数据的方式。例如,当分区字段值位于过滤器中时跳过结果的规则听起来等同于有一个过滤掉此类文档的查询。但是,存在根本的区别。当数据在到达作业之前被过滤时,对于作业而言,就好像它们从未存在过一样。使用规则,数据仍然到达作业并影响其行为(取决于规则操作)。

例如,具有 skip_result 操作的规则意味着所有数据仍在建模。另一方面,具有 skip_model_update 操作的规则意味着即使模型未通过规则匹配的数据进行更新,仍然会创建结果。