802.1x VLAN User Distribution (VLAN Group)

In this blog post, I will be going over 802.1x VLAN User Distribution (sometimes referred to as “VLAN Groups”) in Cisco IOS and a use case scenario that involves Cisco ISE (Identity Services Engine).

First, some background around VLAN Groups. Based on my research it seems there are two major types of VLAN Groups: The Firewall Service Module (FWSM) on the 6500 and on Cisco IOS & IOS XE Switches. It appears to possibly have other functionality within the Wireless Space for user assignment, but I did not do extensive research on that aspect to find an inclusive answer. In the world of IOS a VLAN group is simply a group that has a name assigned to it that can contain one or more VLANs assigned to that group.

The main purpose of 802.1x VLAN User Distribution is to dynamically provide VLAN load balancing by having the RADIUS server dictate the VLAN Group name within attribute 81 (Tunnel-Private-Group-ID) in the RADIUS response instead of a regular VLAN ID/Name. When the switch receives the VLAN Group name, it will assign the endpoint to the least populated configured VLAN for that group. Prior to IOS release 12.2(33)SXI1, this was accomplished by having multiple VLAN names specified under attribute 81.

A use case I have found outside of VLAN distribution load balancing (and the reason I know about VLAN Groups) is to provide a way to dynamically assign a preconfigured VLAN that does not have a uniform number across the enterprise from ISE. This case in particular was to have a predefined VLAN, that would span multiple different VLAN numbers, specific for Cisco IP Phones not tied to a Cisco CM dynamically assigned once the appropriate device profile in ISE was determined. This allows for the ability to have a different option 80 fields in the DHCP response to direct the phones to their non-Cisco based Call Manager.

To take advantage of this configuration, the VLAN group assigned with your desired VLAN(s) must be configured on the switch and the authorization profile that will be applied from ISE must be configured with RADIUS attribute 81 set to the VLAN group name.

To configure a VLAN group in IOS perform the following task:
SW1(config)# vlan group group-name vlan-list vlan-list

To note:

  • A VLAN Group name can be up to 32 characters
  • A VLAN Group name must start with a letter
  • Group members can be specified as a single VLAN ID, a list of VLAN IDs, or a VLAN ID range. Multiple entries are separated by a hyphen (-) or a comma (,) similar to the interface range command.
  • To remove a VLAN from the VLAN group, use the no version (no vlan group group-name vlan-list vlan-ID).
  • The VLAN Group will be removed once the last VLAN ID is removed from the group.

Configuring a VLAN Group on a Cisco Switch:rh3cn9l
vlan group TEST_VG vlan-list 410

Configuring VLAN Group assignment in ISE:
image002
Navigate to Policy Elements > Results > Authorization > Authorization Profiles > Profile
Select VLAN and Enter VLAN Group Name

Once a endpoint is authenticated against the switch via 802.1X and the appropriate authorization profile is assigned, the VLAN configured on the switch for the VLAN group is assigned:Verfication

Some bonus verification information:

When a VLAN is statically assigned via 802.1X, the VLAN assignment can be seen across multiple switchport / VLAN status commands.

The first command is show vlan.

Before dynamic VLAN assignment (port configuration):verification1

After dynamic VLAN assignment (via 802.1X with VLAN Group):verification2

The second command is show interface interface-name switchport:

Before dynamic VLAN assignment (port configuration):verification3

After dynamic VLAN assignment (via 802.1X with VLAN Group):verification4

Advertisements

Cisco ISE REST API & Python

I’ve been faced with a fun little challenge on how to make sure our ISE deployment has every NAD (Network Access Device) configured appropriately to allow for successful EAP communications. Originally I was planning on utilizing a CSV and the bulk import tool to regularly import new devices into ISE as they were built. This allows for a number (small or large) of devices to be imported into ISE without taking too much time. This has worked well in the past but creates an reliance on making sure the CSV is proper and that someone (me) still has to manually login and import the file. With that I decided to look into other possibilities to remove the “me” from the process flow. At first I was looking into ways to automatically populate the CSV and then script out away to login to ISE and force the bulk import. While that option would work, it seemed to be too complicated to really deploy and rely on. I finally decided to give another whack at using the REST API ( I had previously tried years prior with ACS but did not have much luck).

There are a two things that need to be done on ISE prior to being able to utilize the REST API. The below screens and settings are based on ISE 2.2 but are similar between all recent releases of ISE:

  1. Create an account that will be utilized for the REST calls.  To do this navigate to: Administration > Admin Access > Administrators > Admin Users and click on “Add”:ialbmj4
    Currently there are two different access types you can assign: Read/Write or ReadOnly. For the code about to be run, we need Read/Write.
  2. Enable ERS (External RESTful Services) to allow REST calls. To do this navigate to: Administration > System > Settings > ERS Settings then select “Enable ERS for Read/Write” under the Primary Administration Node:fsdtf17
    This setting must be enabled after each upgrade as its set to disabled during the upgrade. If you plan to utilize the REST API, I recommend adding to your upgrade documentation / process that the REST API is enabled at the end of the upgrade.

After a user account is created and ERS is enabled the REST API can be utilized via HTTPS on port 9060. API documentation can be found at: https://ISE-PAN-IP:9060/ers/sdk

Now that the API is exposed its now for some fun! But first some cautions / warnings..

  1. This is by no means a tutorial about REST API or Python.
  2. You really should have a good understanding about REST API before enabling it. I’m still skeptical about the security around access when it comes to REST.
  3. You should never use a production system to develop code that makes changes to it.
  4. Use the code shown at your own risk!

And a few notes about the code…

  1. The below code is not complete, and needs tweaking to be functional. Its intention is simply to show a proof of concept for automating device creation.
  2. The code calls ‘nad.xml’ which is a separate XML file (can be found on my github repository). I will not be going over the file in this tutorial, but can be manipulated for actual use.
  3. The final output is not pretty and may not be complete depending on the number of devices being imported.
  4. The code below is a picture due to me not knowing how to easily paste code that looks nice on wordpress. A copy of the code can by found on my github repository.
  5. The IP address or FQDN of your ISE PAN needs to be updated prior to running the code.
  6. A proper authorization key needs to be added prior to running the code. This will be from the account you created earlier.
  7. It would be a good idea to create a variable for the ISE PAN information to use for multiple URLs.
  8. It would be a good idea to create a variable for the authorization information to use for multiple calls.

Now its really time for the fun part!

The below code is intended to do two things: Bulk create network devices in ISE and to verify the status of the bulk job:

kdtfnke

Code Breakdown:

  • Lines 2 – 8 are simply to deal with importing the XML file. You could just include it in the script and assign it to the payload variable (referenced in line 18) but that doesn’t make this usable in a production environment.
  • Line 11 is the URL used for the first API call. Don’t forget to update with your ISE PAN information.
  • Line 15 is where you should update your authorization information.
  • Line 18 has an extra variable in the request which is “verify” set to “False”. This lets you ignore certificate warnings. In my lab I didn’t bother deploying trusted certs so I needed this.
  • Line 18 is the actual API call being pushed. If you do not care about the status you could simply end here or just print the response.
  • Line 21 grabs just the location header from the response from the API call. The location header is a URL containing the BULK ID that is parsed from the entire URL to use for the second portion of the script.
  • Line 28 is the URL used for the second API call + the BULK ID. Don’t forget to update with your ISE PAN information.
  • Line 32 is where you should update your authorization information.
  • Line 36 has an extra variable in the request which is “verify” set to “False”. This lets you ignore certificate warnings. In my lab I didn’t bother deploying trusted certs so I needed this.

Lets see the code in action!

First we will look to see whats configured in ISE for network devices:9aczrfjNow lets run the script:hghklfn

As can be seen the XML containing 10 network devices was still in progress when the status check was run. If this was production code there are multiple options to avoid this such as a timer could be implemented, the user could be asked when to run the check, or constant checking until it completes.

Now lets see what we have in ISE:qghpxe9Ten brand new devices!

The API in Cisco ISE has many different functions that can allow for the creation, modification, or deletion of several different objects outside of network devices. This is just one example of the power that is available for automating functions within ISE that have been around for a while.

 

IKEv2 with RSA Signatures

Currently my studies have taken me on an adventure into the wonderful world of Cisco Security. I am studying for the 300-209 (SIMOS) certification exam which is VPN technologies including DMVPN, FlexVPN, and a few other flavors of VPN.I find it interesting that so many try very hard to avoid having to implement security because its hard, or because that’s not how they did it at their old job. In this post I am going to go over the simple process of adding RSA Signatures into a DMVPN phase 3 deployment.

 

Below is the high level topology I’ve been  using for my DMVPN labs:

DMVPNTopologyAs can been seen, its a single hub deployment with two spokes (one with two routers and the other with a single router). I am utilizing two separate tunnel types to allow for the addition of another hub (Datacenter) later on down the road. For this post, addressing doesn’t matter too much as I am only going over the parts that are required for RSA Signatures to work.

Lets start with the basics of what’s already in place:

  • NTP (Time) – All routers are already configured with NTP to have synchronized time. This is important for certificates as they have Valid From and Valid To fields that are enforced.
  • DMVPN Phase 3 with Pre-Shared Keys (PSKs)
    • This includes all parts from IKEv2 Policies, all the way to tunnel protection being configured. Maybe another time I’ll go over my lab but there’s a good amount of posts about DMVPN already so not sure it’s really worth while.
  • Routing
    • Both on the FVRF (Front Door VRF) and Internal VRF
  • PKI Infrastructure
    • I setup a single Signing CA for my lab environment with auto enrollment to allow for easy certificate signing on my routers.

Now that what’s in place has been gone over, lets see if things actually working.

dmvpn1

As can be seen, from DMVPNR2 (which is the DMVPN hub for the second tunnel), both remote locations are currently using PSKs and sessions are in a healthy state.

And now the fun part,  actually authenticating the CA, getting a signed RSA signature, and utilizing it with the current DMVPN configuration! As note, any configurations done on a device will be in italics, and any variable that can be changed will be in red like the following: hostname Branch2-R1

1.Generate a RSA keypair for your router:
crypto key generate rsa modulus 2048 label Branch2-R1.dmpvn.com

2.Configure the CA trustpoint:
crypto pki trustpoint TrustedCA
    enrollment url http://10.0.0.6
    rsakeypair Branch2-R1.dmpvn.com
    fqdn Branch2-R1.dmpvn.com
    subject-name CN=Branch2-R1,O=dmpvn.com
    revocation-check crl none

3. Authenticate CA
crypto pki authenticate TrustedCACA Authenticate.jpg

4.Enroll with the CA
crypto pki enroll TrustedCA

CA Enroll

The following fields will need to be filled out:

  • Password – This is needed to revoke the certificate
  • The option to include the Serial number in the subject name (Yes or No)
  • The option to include IP address in the subject name (Yes or No)
    • If yes – it must be configured
  • Accept the request to a certificate from CA (Yes or No)

The certificate request process runs in the background and syslogs are shown when the certificate is received from the CA. The command show crypto pki certificate verbose TrustedCA can be utilized to view the certificate fingerprints for the configured CA.

5. Create a certificate map
crypto pki certificate map CMAP 10
    issuer-name co CA
For my lab environment, I simply created a certificate map that looks for the word “CA” in the issure-name field of the certificate. This can be a very specific variable to allow for strict control over what exactly is allowed for authentication.

6. Create / Modify IKEv2 profile for RSA Signature based authentication
crypto ikev2 profile FVRF-IKEv2
    identity local dn
    match certificate CMAP
    authentication local rsa-sig
    authentication remote rsa-sig
    pki trustpoint TrustedCA

It’s important to make sure you add the authentication local and remote commands for rsa-sig, without them PSKs will still be used! In addition, if the profile is being reused and had the configuration for PSKs, the command for PSKs is NOT overwritten when the rsa-sig command is issued and need to be removed with the “no authentication remote pre-share” if it is no longer desired to utilize PSKs for IKEv2 SAs.

 

And that’s it! Any new SA for DMVPN IPSEC tunnels will be created utilizing RSA. Now, the way Cisco IOS maintains security SAs, they will be active with their negotiated security settings until the SA is renegotiated (if supported) or torn down. This means the old sessions (if RSA was added to an already configured deployment) will have been setup with PSKs. The easiest way to “refresh” these SA’s is to flap the tunnel. Extreme caution should be used when pushing changes to production environments, and as always test in your lab first!

Hiding (filtering) a specific user from reporting in Cisco ISE

I ran into an interesting problem preparing for an 802.1x deployment – the authentications report in Cisco ISE was full of all the network devices checking to make sure ISE was still available (health checks). As seen below the load balancer’s keep alive fill the logs pretty much on their own, imagine trying to troubleshoot a login issue!1 YUCK!

Something else I found interesting that my Google Foo (or knowledge of ACS and how to filter out a certain user) was no match for trying to find a solution for my issue. Because of this, I decided a quick how-to on this would be helpful (I can’t be the only person who will want to filter out such an annoying problem).

First Navigate to Administration > System > Logging:2

Once in the System Settings for Logging, navigate to “Collection Filters”:3

At this point, the rest is pretty straight forward. But for completeness I am going to finish the whole process, so click “Add”:4

After that just fill in the type of attribute you want to filter (Username, Policy Set Name, NAS IP Address, Device IP Address, or MAC Address), the Value for the selected attribute, and the Filter Type (Filter All, Filter Passed, FIlter Failed, or Bypass Suppression [with time limit]). Finally, click “Submit”!

5

For me, it made the most sense to filter the username used for the monitors, and to only filter on passes for that username. This allows me to use the least amount of filters, and if a health monitor fails for any reason will show up in the reporting still.

Final result (don’t mind the old logs, I was too impatient to wait for them to clear):

6

Happy troubleshooting!

Controlling Traffic to a Virtual Server on F5

There are multiple ways to control what traffic is allowed or not allowed through a BIG-IP or for specific Virtual Servers (VS). The following method uses F5’s AFM (Application Firewall Manager) to create security policies which are then applied to a specific VS. For this method example, traffic from three specific hosts will be allowed to a specific VS, while all other traffic is blocked. The below diagram illustrates the environment used:
diagram

In this example the VS (192.168.35.100) is setup for TCP port 80 (HTTP) traffic only. This within itself controls some of the allowed traffic flow (assuming there are not other VS configured to accept all traffic) by only allowing port 80 traffic destined to the VS to be processed. An address list is created with the addresses that are allowed to the VS and then a Network Firewall Policy Rule is created and applied to the specified VS with an accept action. To finish this method, a block rule is added to the Network Firewall Rule Policy rule-set to drop all other traffic.

The first step is to create a Address List by going to Security > Network Firewall > Address Lists and either clicking the plus sign under Address Lists:
AddressLists

or selecting Create on the next screen:
CreateAddressList

Enter the following Information (Only Name and Addresses are required):
CreatingAddressList Click finish when completed. A side note, the first time I did this I spent a few moments figuring out you must push enter after typing the address in the address field.

The next step is to create the Rule Policies by going to Security > Network Firewall > Active Rules and clicking the plus sign under Active Rules:
ActiveRules

or selecting Add on the next screen:
AddRule

Enter the following information:

  • Context: Virtual Server – VS_Name
  • Policy: New – Policy_Name
  • Rule Properties:
    • Name: Rule_Name
    • Description: Rule_Description
    • Source:
      • Address/Region: Specify
      • Type: Address List
      • List: Address_List (From last step)
    • Action: Accept

NewRule Select Repeat to move onto the next rule.

For the next rule include the following information:

  • Rule Properties:
    • Name: Rule_Name
    • Description: Rule_Description
    • Source:
      • Address/Region: Any
    • Action: Drop

NewRule2 Click Finished when all set. When adding the block rule, or any other rule for that matter, make sure to add to the current policy. Otherwise, the current policy will be overwritten along with any rules in those policies. In this example creating the blocking rule improperly would overwrite the policy with the allow rule and block ALL traffic to the VS.

Once completed, it is now time to test. Attempting to browse to http://192.168.35.100 from an “allowed IP address” should allow access to the site while browsing from an IP address that isn’t on the list should be blocked.

Lets just go ahead and use DTP & VLAN 1… Part 1: Attacking DTP – getting those server files

In my previous post, I discussed the vulnerabilities introduced from using the defaults of DTP and VLAN1 along with ways to mitigate the vulnerabilities. In this post a basic example of attacking DTP will be reviewed.

To make things easier to follow the following diagram will be used throughout the series:VH

Before the attack, for demonstration purposes, we verify that the attacker’s switchport (fa 0/14) is not a trunk:

Untitled2

We will also verify the inability of the attacker to access the target server (due to the router’s ACL):a1

Now that we have verified the inability for the attacker to gain access to the server we can begin the attack.

The first phase of the attack will be to trick the switch into thinking its connected to another switch and negotiate a trunk link. This will be completed through spoofing DTP packets, which can be seen below:at1

We can see the switch port flap as it resets, and then its verified that the attacker’s port is now a trunk:Untitled3

Now that the switch believes its connected to another switch via a trunk connection its now possible to create virtual interfaces for any VLAN allowed across the trunk (all by default):at2

As can be imagined, with the attacker able to successfully trick the connected switch into thinking s/he is also a switch almost anything is possible. For today, we will simply pull a file off of the server which is supposed to be protected by an ACL on the router:
at3

passwords

With DTP enabled on a port it takes a matter of seconds to trick a switch into thinking its connected to another switch, this is why its very important to configure any port that is not a trunk port in use as an access port with other appropriate security configurations.

Lets just go ahead and use DTP & VLAN 1… Part 0: What using DTP & VLAN 1 means

By default, DTP auto negation is enabled on Cisco switches on all layer 2 ports and they are placed in VLAN 1. These two defaults allow for an easy way to just deploy a switch, or attach another switch to gain more port density, without needing any configuration knowledge. While this is very helpful, the use of VLAN 1 and leaving DTP auto negation on has been widely accepted as standard use for data ports and in turn has left the ability for someone with physical access to gain access to other VLANs and the devices in them.

In part 0 of this series we are going to go over the theory of why the use of DTP and VLAN 1 could be used to allow for an attacker to execute a VLAN hopping attack.

DTP:

Dynamic Trunking Protocol (DTP) is a Cisco proprietary protocol used to allow for trunks to automatically form between switches without requiring any configuration knowledge when they are plugged into each other. DTP sends updates every 60 seconds over links with DTP enabled and includes the switch’s DTP type, interface status, and VTP domain.

Attacking DTP:

While there really isn’t much to say about DTP (even at a technical level) having DTP on allows for a security hole that can easily be exploited to allow full access to any VLANs the switch has access to. There are two different ways to take advantage of DTP both of which are pretty straight forward.

The first method involves simply plugging in another Cisco switch, that the attacker has control over, with DTP enabled. Once the two switches form a trunk, the attacker can then configure the switch they control and put a device in any VLAN that’s allowed across the trunk (which is all by default). SS

Figure 1 – Adding a third switch

The second method involves forging DTP frames to trick the victim switch into forming a trunk with the attackers computer. Once the trunk is formed, the attacker can forge other frames and packets that will allow them deeper access into the network similar to having their own switch but without the hassle of having a switch on-site for the attack. ST

Figure 2 – Switch Spoofing

Mitigating DTP attacks:

Just as DTP and the attacks associated with the protocol are simple, so are the steps for mitigating the attacks.

1. Set any port not used as a trunk explicitly as an access port
SW-1 (config)# interface fa 1/0/1
SW-1 (config-if)# description Access Port
SW-1 (config-if)# switchport mode access

2. On ports that are trunks, disable DTP negotiation
SW-1 (config)# interface gig 1/0/1
SW-1 (config-if)# description Trunk to SW-2
SW-1 (config-if)# switchport trunk encapsulation dot1q
SW-1 (config-if)# switchport mode trunk
SW-1 (config-if)# switchport nonegotiate

SW-2 (config)# interface gig 1/0/1
SW-2 (config-if)# description Trunk to SW-1
SW-2 (config-if)# switchport trunk encapsulation dot1q
SW-2 (config-if)# switchport mode trunk
SW-2 (config-if)# switchport nonegotiate
802.1Q:

Unlike Cisco proprietary ISL, standards based 802.1Q does not encapsulate the original frame. Instead it adds a 32-bit field between the source MAC address and the EtherType/length fields. Another difference between ISL and 802.1Q is the concept of a native VLAN. While ISL doesn’t have a native VLAN in 802.1Q a native VLAN will not be tagged when frames for that VLAN are flowing over a trunk link by default.

Attacking the native VLAN:

The use of the native (untagged) VLAN allows for an attack called VLAN hopping. This attack allows for an attacker to craft frames that are “double tagged” which have two 802.1Q tags in the frame. The attack itself would be performed in the following manner:

DT

Figure 3 – Double Tagging

1. The attacker crafts a frame with two 802.1Q tags, the first tag will be for the native VLAN 1 (in this case the default VLAN 1) and the second tag will be for the target VLAN (in this case VLAN 10).

2. SW-1 receives the frame on a port set as the native VLAN and strips the first 802.1Q header. Next, it will forward the frame out any trunk links it has that are set for native VLAN 1. In this case the frame will be forwarded to SW-2 over its trunk link.

3. SW-2 receives the frame on its trunk and see that it is destined for a device in VLAN 20. Assuming the target’s MAC address is already in the MAC table, the frame has its second 802.1Q header removed (because its going to be forwarded over an access port which doesn’t allow 802.1Q headers) and forwarded to the target.

As can be seen above, the attack does require two switches to be trunked together in order to allow for it to be successful.

Protecting the native VLAN:

There are three easy ways to protect against VLAN hopping attacks, only one is required but the use of all three is highly recommended.

1. Do not use the native VLAN on any access port
SW-1 (config)# interface fa 1/0/1
SW-1 (config-if)# description Access Port
SW-1 (config-if)# switchport access vlan 20

2. Set the native VLAN to an unused VLAN (must be configured on both switches of a trunk)
SW-1 (config)# interface gig 1/0/1
SW-1 (config-if)# description Trunk to SW-2
SW-1 (config-if)# switchport trunk native vlan 999

SW-2 (config)# interface gig 1/0/1
SW-2 (config-if)# description Trunk to SW-1
SW-2 (config-if)# switchport trunk native vlan 999

3. Tag native VLAN traffic (must be configured on both switches of a trunk)
SW-1 (config)# interface gig 1/0/1
SW-1 (config-if)# description Trunk to SW-2
SW-1 (config-if)# switchport trunk native vlan tag

SW-2 (config)# interface gig 1/0/1
SW-2 (config-if)# description Trunk to SW-1
SW-2 (config-if)# switchport trunk native vlan tag

 

While defaults are wonderful to have and make certain tasks easier, it must be taken into consideration what those defaults actually enable what type of holes could be opened in a security plan when used. My next post will go into greater detail of using these vulnerabilities as a jumping off point on gaining access to other systems on a network.