Certificate(s) has expired-checkpoint-gaia

error
gaia
checkpoint
Certificate(s) has expired-checkpoint-gaia
0

#1

Certificate(s) has expired-checkpoint-gaia

Vendor: checkpoint

OS: gaia

Description:
Indeni will alert when a certificate has expired. Certificates that have expired more that a set number of days will be ignored. " +
"The threshold for the number of days after certificate expiration can be adjusted by the user.

Remediation Steps:
Renew any certificates that need to be renewed.
||Please review:
|Solution sk104400 on Check Point Support Center
|and the articles to which it links at the bottom.

chkp-cpca_client-lscert-mds

#! META
name: chkp-cpca_client-lscert-mds
description: Show list of certificates on the management (VPN, SIC etc) in MDS
type: monitoring
monitoring_interval: 5 minutes
requires:
    vendor: "checkpoint"
    os.name: "gaia"
    role-management: "true"
    mds: "true"
    vsx: "true"

#! COMMENTS
certificate-expiration:
    skip-documentation: true

#! REMOTE::SSH
COLUMNS=150 && export COLUMNS && ${nice-path} -n 15 mdsstat | grep CMA | awk '{sub(/\|/, "", $3); print $3}' | while read name; do mdsenv $name && ${nice-path} -n 15 mdsstat $name && ${nice-path} -n 15 cpca_client lscert; done

#! PARSER::AWK

# Checkpoint labels all of its certs with it's own "Status": Pending, Valid, Renewed, Expired, or Revoked. (Note: pretty
# sure this is a Checkpoint thing, not an X.509 thing). This script only looks at Expired, Valid and Renewed certs
# (we think that "Renewed" certs are just certs that, for a given Subject, have been revoked or expired and subsequently
# re-issued). We are intentionally ignoring Revoked and Pending certs, since we don't care about the expiration dates of
# those certs. See also https://indeni.atlassian.net/browse/IKP-1525.

# NOTE: This file and cpca_client-lscert-nomds.ind have very similar code. If you edit the code here, please look at the
# other file to see if the changes apply there as well.



# This function has a SIDE EFFECT: it uses 'getline'
function getExpirationDate() {
    #Not_Before: Sat Jul  9 11:21:26 2016   Not_After: Fri Jul  9 11:21:26 2021
    getline  # SIDE EFFECT

    expire_month = $(NF - 3)
    expire_day = $(NF - 2)
    expire_time = $(NF - 1)
    expire_year = $NF

    sub(/,/, "", expire_year)   # Sometimes a comma follows the year

    return date(expire_year, parseMonthThreeLetter(expire_month), expire_day)
}

# A Checkpoint device can have many certs with the same name (CN) and status. In that case, choose the one with the
# _latest_ expiration date.
function handleDuplicateName(name, certs, new_expiration) {
    if (name in certs) {
        existing_expiration = certs[name]
        if (new_expiration > existing_expiration)
            certs[name] = new_expiration
    } else {
        certs[name] = new_expiration
    }
}


BEGIN {
    # These statements 'declare' (create) these empty arrays before we actually use them, so that we can pass them into
    # 'handleDuplicateName'. This is just a hack/convention to declare arrays in awk.
    split("", expired_certs)
    split("", report_these_certs)
}

#| CMA |MDM-VSX_Management_Server | 10.10.6.14      | up 1531    | up 1616  | up 1493  | up 1720  |
/^\|\s+CMA\s+\|/ {
    cma_name = $3
    cma_ip = $5

    sub(/\|/, "", cma_name)   # Remove starting "|" in the name

    next
}

# Info for each certificate comes from three lines in a row. This script matches only on the first of the three lines,
# then uses 'getline' to process the entire record, e.g:

#Subject = CN=lab-CP-GW4 VPN Certificate,O=lab-CPMGMTR7730..9uifq5
#Status = Valid   Kind = IKE   Serial = 49229   DP = 1
#Not_Before: Mon Dec 26 10:47:02 2016   Not_After: Sun Dec 26 10:47:02 2021
/^Subject = / {

    # First, in case the cert name has spaces, we split on $0 and not $3.
    # Splitting on '=' gives us most of the string, but then we need to deal with the trailing ',X', where X can be any
    # of the X.509 acronyms (usually 'O=...' but I've seen 'OU=...'). So we need to further parse. AWK's string
    # manipulation support is poor, so this is a bit of a hack, but it seems to work.
    split($0, name_array, "=")  # split on the whole line: CNs can have spaces
    CN = name_array[3]
    split(CN, cn_arr, ",")
    last_str_len = length(cn_arr[arraylen(cn_arr)])  # in case there are multiple commas in the cert name...
    offset_from_end = last_str_len + 1  # do NOT combine this arithmetic with the next line. Scary JAWK bug...
    CN = substr(CN, 1, length(CN) - offset_from_end)

    # A given cert CN can be used on multiple CMA's, so to get a unique name, we need to combine CMA and CN.
    cert_unique_name = cma_name " - " CN

    #Status = Valid   Kind = SIC   Serial = 2562   DP = 0
    getline
    status = $3
    if (status == "Expired" || status == "Valid" || status == "Renewed") {
        cma_name_list[cert_unique_name] = cma_name
        cma_ip_list[cert_unique_name] = cma_ip

        if (status == "Expired") {
            handleDuplicateName(cert_unique_name, expired_certs, getExpirationDate())
        } else if (status == "Valid" || status == "Renewed") {
            handleDuplicateName(cert_unique_name, report_these_certs, getExpirationDate())
        }
    }# Note: if status is anything but Expired, Valid, or Renewed, just ignore it and do nothing.
}


END {
    # Only report on expired certs if they _don't_ have a valid corollary.
    for (expired_name in expired_certs) {
        if (!(expired_name in report_these_certs))
            report_these_certs[expired_name] = expired_certs[expired_name]
    }

    for (cert_name in report_these_certs) {
        cert_tags["name"] = cert_name
        cert_tags["vs.name"] = cma_name_list[cert_name]
        cert_tags["vs.ip"] = cma_ip_list[cert_name]

        cert_expiration = report_these_certs[cert_name]
        writeDoubleMetricWithLiveConfig("certificate-expiration", cert_tags, "gauge", 0, cert_expiration, "Certificate Expiration", "date", "name")
    }
}

RuleMetadata

.builder(
  "cross_vendor_certificate_has_expired
package com.indeni.server.rules.library.crossvendor

import com.indeni.apidata.time.TimeSpan
import com.indeni.apidata.time.TimeSpan.TimePeriod
import com.indeni.ruleengine.expressions.conditions.{And, GreaterThan, LesserThan}
import com.indeni.ruleengine.expressions.core.{StatusTreeExpression, _}
import com.indeni.ruleengine.expressions.data.{SelectTagsExpression, _}
import com.indeni.ruleengine.expressions.math.PlusExpression
import com.indeni.ruleengine.expressions.utility.NowExpression
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.library.core.PerDeviceRule
import com.indeni.server.rules.library.{ConditionalRemediationSteps, RuleHelper}
import com.indeni.server.sensor.models.managementprocess.alerts.dto.AlertSeverity

case class CrossVendorCertificateHasExpiredRule() extends PerDeviceRule with RuleHelper {

  private val highThresholdParameterName = "Effective_Duration_Threshold"
  private val highThresholdParameter = new ParameterDefinition(highThresholdParameterName,
                                                               "",
                                                               "Effective_Duration_Threshold",
                                                               "How long before expiration should Indeni alert.",
                                                               UIType.TIMESPAN,
                                                               TimeSpan.fromDays(30))

  override val metadata: RuleMetadata = RuleMetadata
    .builder(
      "cross_vendor_certificate_has_expired",
      "All Devices: Certificate(s) has expired",
      "Indeni will alert when a certificate has expired. Certificates that have expired more that a set number of days will be ignored. " +
        "The threshold for the number of days after certificate expiration can be adjusted by the user.",
      AlertSeverity.ERROR
    )
    .configParameter(highThresholdParameter)
    .build()

  override def expressionTree(context: RuleContext): StatusTreeExpression = {
    val actualValue = TimeSeriesExpression[Double]("certificate-expiration").last.toTimeSpan(TimePeriod.SECOND)

    StatusTreeExpression(
      // Which objects to pull (normally, devices)
      SelectTagsExpression(context.metaDao, Set(DeviceKey), True),
      // What constitutes an issue
      StatusTreeExpression(
        // The additional tags we care about (we'll be including this in alert data)
        SelectTagsExpression(context.tsDao, Set("name"), withTagsCondition("certificate-expiration")),
        StatusTreeExpression(
          // The time-series we check the test condition against:
          SelectTimeSeriesExpression[Double](context.tsDao, Set("certificate-expiration"), denseOnly = false),
          // The condition which, if true, we have an issue. Checked against the time-series we've collected
          And(
            LesserThan(
              actualValue,
              NowExpression()
            ),
            GreaterThan(
              PlusExpression[TimeSpan](actualValue, getParameterTimeSpanForTimeSeries(highThresholdParameter)),
              NowExpression()
            )
          )
          // The Alert Item to add for this specific item
        ).withSecondaryInfo(
            scopableStringFormatExpression("${scope(\"name\")}"),
            scopableStringFormatExpression("Expired on %s", timeSpanToDateExpression(actualValue)),
            title = "Affected Certificates"
          )
          .asCondition()
      ).withoutInfo().asCondition()
    ).withRootInfo(
      getHeadline(),
      ConstantExpression("One or more certificates has expired. See the list below."),
      ConditionalRemediationSteps("Renew any certificates that need to be renewed.",
        ConditionalRemediationSteps.VENDOR_CP ->
          """Please review:
            |<a target="_blank" href="https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk104400">Solution sk104400 on Check Point Support Center</a>
            |and the articles to which it links at the bottom.""".stripMargin,
        ConditionalRemediationSteps.VENDOR_PANOS ->
          """Please review this article on Palo Alto Networks Support Site:
            |<a target="_blank" href="https://www.paloaltonetworks.com/documentation/60/pan-os/pan-os/certificate-management/revoke-and-renew-certificates">Revoke and Renew Certificates</a>.""".stripMargin,
        ConditionalRemediationSteps.VENDOR_FORTINET ->
          """
            |1. Login via ssh to the Fortinet firewall and run the FortiOS command “get vpn certificate <X> detail”  to review the period for which the certificate is valid.
            |2. Login via ssh to the Fortinet firewall and run the FortiOS command “get vpn certificate setting” to review the settings.
            |3. Login via https to the Fortinet firewall and go to the menu System > Certificates tab to review the list of the certificates. Double click each certificate to get detailed information.
            |4. For more information review the Fortinet Certification Configuration Guide: http://help.fortinet.com/fos50hlp/54/Content/FortiOS/fortigate-authentication-54/Certificates.htm
            |5. If the problem persists, contact Fortinet Technical support at https://support.fortinet.com/ for further assistance.""".stripMargin
      )
    )
  }
}