IMC Icon

IMC Compliance – Advanced Policies

So far we’ve only looked at basic rules. Let’s take a look at some advanced uses of Compliance Center – advanced pattern matching with regular expressions, and Configuration Segment checks. The combination of these features lets us write far more advanced rules. You can solve almost any problem with these features, but be warned – it can take quite a while to figure out the exact syntax for your regular expressions.

“Some people, when confronted with a problem, think “I know, I’ll use regular expressions.”  Now they have two problems.”  (Jamie Zawinski)

Advanced Pattern-Matching

When configuring a rule, in the ‘Match Mode’ section, the default ‘Rule Type’ is Basic. Let’s create a new rule, and change the Rule Type to Advanced:

Match Mode

Note that the options change, and now we have Operation, Match Mode, and Match Patterns. The key items here are Match Mode and Match Patterns. Match Mode can be either Included or Excluded. If we set our Match Mode to Included, then we are saying “Our configuration MUST contain this pattern. If it does not, then this check should fail.” If we choose Excluded, we are saying “Our configuration MUST NOT contain this pattern.”

The Match Pattern box is where we can enter our regular expression. This follows the rules of regular expressions. These are far more complicated than simple wildcards, and beyond the scope of this blog post. If you’re not familiar with these, I highly recommend reading one of the many tutorials available online. Here’s some examples of patterns you might use:

Note that certain characters have special meaning – e.g. a ‘.’ represents “any character.” So if you’re entering an IP address, you will need to escape the ‘.’ with ‘\’ – e.g. “10.1.10.10”.

You can add multiple patterns. Once the first is added, you will get a Rule Relation drop-down, which you can set to AND or OR. Using this, you can build up complex policies – e.g. “Configuration must contain Pattern A and Pattern B, but NOT Pattern C.” Be careful with just how complex you get. You’ll probably need to work through it on paper first, to work out exactly what you need. Here’s a reasonably simple example of the sort of rule you could end up with:

Example Advanced Rule

Walk-through Example

The best way to see how and why we would use Advanced Pattern-Matching is to use an example. Consider SNMP community string configuration on a Cisco device. If our chosen community string is “mySecretString”, then this is what our configuration should look like:

We could use a regular basic pattern match to look for that string, and it would correctly alert if that string was missing. But what if someone adds in an incorrect string? Cisco SNMP community configuration is additive. Look at this example, which starts with the earlier SNMP configuration:

Now I have a problem – how do I detect this sort of configuration? I could write a rule that alerts if it sees “snmp-server community public” – but what if there’s some other random string added? What I really need to do is find a way to say “Alarm if the device does not have my community string, and ONLY my community string”. Advanced Pattern-Matching lets us do this. Here’s how:

First add a new Compliance rule, set the vendor as required, and set the Rule Type to Advanced. First add a Match Pattern of ‘snmp-server community mySecretString RO \d+’. The Operation should be ‘Check’, and the Match Mode should be ‘Excluded’. If you’re not familiar with regex syntax, the ‘\d+’ pattern says “match any digit, one or more times”. This will match any ACL number. So this first line will check that we have the right community string added, set to RO, and with an ACL defined. Now let’s add another line. This time, set the Match Mode to ‘Excluded’. Note we can also now set the Rule Relation – this should be AND. Set the Match Pattern as ‘snmp-server community (?!mySecretString)’. Add that. Your rule should now look like this:

Snmp String Rule

Hit OK to save the rule, and OK again to save the policy. Create a task to run the rule, and check the results. Here’s the output from running that check against my system:

Comm String Fail

Let’s fix up the device:

Run a backup in IMC, and re-run the Check Task. Success!

Comm String Pass

Configuration Segments

Let’s say you want to check that your switchports have “no logging event link-status” added. If you just use a normal rule, and look for that pattern, how will you know that every interface has this configuration applied? The rule won’t count individual matches, it will see the first match, and then the device will pass. What you really want to do is check every single interface. But what about non-Ethernet ports? And what about trunk ports? Maybe I want to log link status changes on those. Bugger. Now it’s getting complicated.

Let’s see how we can write a rule that meets these requirements:

  • Check all GigabitEthernet ports, to see that they have “no logging event link-status” set.
  • This should only apply to access ports. Trunk ports should not have “no logging event link-status”.
  • Non-Ethernet ports should not have “no logging event link-status” set.

Here’s an example of a typical interface configuration:

There’s two parts to this. First we need to define a rule that will look at interface configurations. Add a new rule, but this time change the ‘Check Type’ from the default of ‘Device’ to ‘Interface’. You’ll see that we now have a ‘Start Identifier’ and ‘End Identifier’ box. Our ‘Start Identifier’ will be ‘interface GigabitEthernet*’ and our ‘End Identifier’ will be ‘!’. Cisco uses ‘!’ between sections, while Comware uses ‘#’.

Interface Check

This setup will tell IMC to apply our rule only to the configuration under each GigabitEthernet interface. It will run this check against all GigabitEthernet interfaces on each device, and ensure they all comply. Now we need to define the actual pattern matching we need. We can’t just do a simple match for “no logging event link-status”, because that will create a false positive on trunk ports. Thinking more about, we can see that an interface configuration needs to contain EITHER “no logging event link-status”, OR “switchport mode trunk”.

Here’s one way of achieving that: First scroll down to the ‘Match Mode’ section, and change it to ‘Advanced’. Add ‘switchport mode trunk’, and click Add. Now set the ‘Rule Relation’ to OR, and add “no logging event link-status”. It should look like this:

Logging Event Status Rules

Because we’re using an OR match, only one of the conditions has to be true. When evaluating the condition, IMC will first look for the presence of ‘switchport mode trunk’ – if it sees that, it will stop evaluating, and pass that interface.

This rule can now be used in a policy, and deployed through a regular Check Task. When you run this task, if there are any non-compliant interfaces, you’ll see in the “Checked Content” link exactly which interface it was:

Check Content Interface

The sharp ones out there might say “What if we want to check that logging is ON for all trunk interfaces? This rule uses OR, not XOR, so a trunk could have logging disabled.” That’s true, and IMC doesn’t have an XOR Rule Relation. Instead, you’d need to build up a more complex rule that looked something like (“switchport mode trunk” AND NOT “no logging event link-status”) OR (“switchport mode access” AND “no logging event link-status”). There’s a few different ways of achieving it.

Other options for checking Configuration Segments are very similar, but can use different ‘Start Identifiers’ – this lets you check say EtherChannel interfaces, or sections like “router ospf” or “line vty *”.

,

One Response to IMC Compliance – Advanced Policies

  1. Jannie H August 11, 2016 at 12:18 am #

    I realise this is a very old post, but as this seems to be the only place known to search engines where these policies are discussed, I thought I’d contribute in the hope that it helps someone in future.

    For the last case mentioned, where you want to implement more complex policies: I was unable to figure out a way to build up complex rules using the and/or settings – there are no “brackets” to allow you to group conditions to establish precedence. This makes it very difficult to check for multiple conditions for a particular port type, and I very nearly gave up.

    I’m posting because I found a way of building such rules that might be useful to others. For example, say you want to make sure PoE is enabled on all ports set to “hybrid” or “access” mode, but not on trunk ports. You also want to make sure no port (trunk or otherwise) has its PoE power limited. The following rule should work for that:

    Included link-type trunk
    OR Included (?s)(port link-type hybrid|port access vlan).*poe enable
    AND Excluded poe max-power

    This type of approach also opens up some interesting possibilities where you can put “tags” in descriptions of ports. Say there are several settings you want applied on all ports, except if those ports have some bit of text in their description field. You could use the rule below:

    Included description .*Do not mess with this port or else!.*
    OR Included (?s).*voice-vlan 100 enable.*stp edged-port.*qos trust dscp.*poe enable

    For reference, a great tool for understanding and changing the regular expressions above is http://regex101.com. The key bit that I had to discover was that it’s very difficult to get the RegEx engine in Compliance Policies to match values across lines. “\n”, “\s” and any of the other variants do not seem to work reliably. The only way I’ve found that works around this in iMC Compliance Rules is to prefix the expression with “(?s)”, which configures the RegEx engine to match on line feeds for “.*”.

    In summary, the most important take-away is that Lindsay’s quote about regular expressions (see beginning of the article) is spot-on!