ISE C3PL Switch Configuration

In this blog post, I'm going to go over a different way to configure your switch for ISE called Cisco Common Classification Policy Language (C3PL). I have known about this configuration for awhile but I will admit that I didn't really try to learn it until recent. If you read the IBNS 2.0 deployment guide here, it's pretty intimidating guide at a whopping 65 pages long and reads like a typical manual. I ended up reading Jamey Heary and Aaron Woland's Cisco ISE for BYOD Second Edition and they broke it down beautifully in 4 pages which made me go "Team C3PL."

One thing to be aware of is that almost all of your global switch configurations will remain the same for the most part. The big change is how we're configuring the switchport itself and how the policy is applied. If you're wondering why we even need to have an alternate way of configuring the switchport, let's start by looking at how an existing switchport is configured for ISE: 

The configuration above is pretty massive when you multiply it by the number of switchports on a given switch and the way it behaves in a sequential manner. 

For example:
- First attempt to authenticate with 802.1x
- After 802.1x times out, attempt to authenticate with MAB
- Prefer 802.1x over MAB
- Periodically reauthenticate to the server
- If the RADIUS server is dead, reinitialize to VLAN 100 and reinitialize the voice VLAN on the port.
- etc etc etc 

It makes sense and it's served us well for some time now but it's not very dynamic and the config bloat is real as you can see from the the above screenshot from my lab.

So what does C3PL bring to the table that you can't get out of the previous configuration?

  • It gives us the ability to dynamically define actions based on events in the session in response to specified conditions and events. If the conditions or events don't match, it won't even try to take that certain type of action that you define. The list of different events and conditions is pretty robust. 
  • Optimization - The configuration can exist in memory once and called many times. 
  • Doesn't operate in a serial manner like the previous configuration style. For example, you can have 802.1x and MAB running at the same time but specify a preferred authentication method (802.1x). This can improve the end user experience since they don't have to wait 10 seconds for 802.1x to fail before MAB even starts.
  • Templates to control access if RADIUS fails such as a critical ACL instead of just dumping them into a VLAN. 

In order to activate C3PL configuration on a switch, I would recommend clearing the ISE port configurations and issue the following global exec command: authentication display new-style

Note: If you do not clear the ports prior to this, it will convert all your existing ISE port configurations to individual C3PL policies and if you plan on creating a single consistent policy on a switch, you don't want it to automatically create a policy per port. 


The anatomy of a C3PL policy

Looking at the policy, you'll notice it looks a bit like QoS MQC which can look a little initimidating at first. Let's break the control policy down:

1. Control Class - This is where you initially specify the condition that needs to be seen to cause a control policy to be triggered. Think of it this way: If you were looking at a policy set in ISE, this would be the top-level condition that would need to be matched for ISE to select a certain policy set to use. With a control class, you can specify if all, some or none of the matching statements are true. Once the class is created, you can match or not match on a number of different conditions.

The basic structure of a control class is such:

class-map type control subscriber {match-all | match-any | match-none} class-name
{match | no-match} conditions

It's pretty simple logic and you can get really interesting with what you can match as you can see in the screenshot below.

So many options! In reality, we'll probably be sticking with a pretty static template but I could definitely see myself creating a policy based on a matched SGT to do some pretty interesting things. 

Now I'm going to create a control class that matches on the RADIUS server being down:

class-map type control subscriber match-any AAA-DOWN
match result-type aaa-timeout

The above screenshot displays some of the many other options you have when configuring the above configuration.

Now we will create a control class for 802.1x authentication failing: 

class-map type control subscriber match-all DOT1X-FAILED
match method dot1x
match result-type method dot1x authoritative

In the initial line of the class-map, I specify that it needs to match all the conditions in the class map to trigger. Then in the match statements, I'm telling it that it has to match the 802.1x method type and fail. 

The one thing that I think initimidates a lot of people with C3PL is that there are so many different options. In most cases, you're going to do a pretty static configuration but just to give you an idea of some of the cool options you have, look at the below screenshot. With so many options, you can end up configuring the wrong thing if you're trying something new but that's where testing your configuration should come into play. In the below, we could easily specify matching on webauth or mab, successful authentication, etc for some interesting triggers. 


2. Creating your control policies - The control class that you created in step 1 are used in the control policy. The control class is the event that casuses the control policy to be evaluated and defines actions to take based on the event in the class map. The actions you can take are specific to what kind of event occurred. 

The way this is written is that the actions are numbers and executed sequentially. You use the previously created control class map in this control policy. The way the control policy is structured:

  • First you create the policy-map and specify the event:
    policy-map type control subscriber name
    event event-type {match-all | match-first} 
    Note: The different between match-all and match-first is that with match-all, you evaluate all of the classes you define and with match-first, you only evaluate the first class it matches.
  • Next you can specify the class and how to handle the actions:
    num class {class-name | always} {do-all | do-until-failure | do-until-success}
    Note: Here is where you can specify you class name you created in step 1 or you can specify always to ensure that the control class-map always matches. For the second argument in the above configuration, you can have it execute all the actions you specify, all of them until it fails, or all of them until it's successful. 
  • Next you specify the actions to take including actions to take for policy violations:
    num <action-type> <additional-arguements>
    Here is where you can specify the action to take including to activate a template or policy, authentication type and priority, authorize a session, notify the session attibutes, set a timer, and unauthorize a session along with a number of additional arguments depending on what type of argument you are making. 

Let's say I want to create the following configuration:

  • Run 802.1x and MAB at the same time on a port but prefer 802.1x 
  • If 802.1x fails authentication, fallback to MAB
  • If the RADIUS server is down, give access based on the critical ACL I define

First I would start by creating the critical ACL: 

ip access-list extended ACL-ALLOW
permit ip any any

Then I would add that ACL to a service template:

service-template CRITICAL
access-group ACL-ALLOW

Note: This ACL could be as restrictive or as liberal as you want it to be. The point is to craft it for your organization.

Next we will create the control policy:

policy-map type control subscriber DOT1X-DEFAULT <- Creates the control policy

event session-started match-all <- States that if a session starts, match all the below that we define.
10 class always do-all <- Matches everything after a session starts and do all the actions
10 authenticate using dot1x priority 10 <- Action is to authenticate using dot1x with a priority of 10
20 authenticate using mab priority 20 <- Action is to authenticate using MAB with priority of 20 - making it a lower priority than a successful dot1x authentication if both were to pass authentication.

event violation match-all <-specifies a new action to take when a control violation occurs
10 class always do-all <- Matches everything after a session starts and do all the actions
10 restrict <- The action is to drop violating packets and generate a syslog

event agent-found match-all <- The event is if an 802.1x supplicant is detected
10 class always do-all <- Do all the actions
10 authenticate using dot1x <- Action is to authenticate using 802.1x

In the above, we'd stated to attempt 802.1x and MAB authentication at the same time but the priority is for 802.1x to be the preferred authentication method. If there is a violation, drop the packets. If an 802.1x supplicant is detected, 

event authentication-failure match-all <- Now the event is an authentication failure
10 class AAA-DOWN do-all <- Match against our class of AAA-DOWN we configured in step 1
10 authorize <- Authorize the access
20 activate service-template CRITICAL <- Apply the service-template of CRITICAL
30 terminate dot1x <- Stop trying to authenticate using 802.1x
40 terminate mab <- Stop trying to authenticate using MAB
20 class DOT1X-FAILED do-all <- Matching against our DOT1X-FAILED class
10 authenticate using mab <- Fallback to authenticating using MAB

The above will look like this in the running config of the switch:



2. Apply the control policy on the interface - I'll go through the necessary commands for the interface:

interface range g1/0/1-24
switchport host
switchport access vlan 100
service-policy type control subscriber DOT1X-DEFAULT
authentication periodic
authentication timer reauthenticate server
access-session host-mode multi-auth
dot1x timeout tx-period 10
access-session port-control auto

Now when you look at the switchport configuration, it's a lot smaller and tighter in comparison to the first switchport configuration I posted. 


Of if you took away all the random other configs I have in my lab for testing, it would be even tighter: 



One thing to be aware of is that when you change the configuration to the new style, you will notice that if you issue the command show authentication session interface x/x/x detail, it will not work. That command has changed when you configure the new style and you would now use show access-session interface x/x/x details as demonstrated below:

For more late night reading on C3PL, feel free to read the following: IBNS 2.0 Deployment Guide