Wednesday, November 23, 2016

IPv6 Intro: Access Control Lists

Way back in CCNA Lesson 13, we introduced Access Control Lists (ACL's) on Cisco routers. Since Cisco has re-vamped the CCNA test to include IPv6, it is probably worth adding another lab to revisit ACL's when using IPv6. The good news is, ACL's in IPv6 are very similar to IPv4 ACL's, but not quite as complicated. Forget all of that jazz about named ACL's, numbered ACL's, standard ACL's and extended ACL's -- in IPv6, you get named ACL's...period. Ready to take a peek? Let's get started!

Suppose you have two routers, R1 and R2. R1 has two clients connected to it, Clone 1 and Clone 2. R2 has two servers connected to it, CentOS and CentOS_Clone. Since I happen to like coffee, and I don't like remembering long strings of hexadecimal digits, I have based my addressing scheme in this lab on the base address 2001:C0:FFEE::x/y :


Since we are using SLAAC to configure our host IP addresses, we will still have to deal with some ugly addressing, but at least the routers won't be too terribly bad.

So...suppose we want to allow Clone 2 to log in to our routers, but we don't want any other network hosts to log in. Just as we would do in IPv4, we will create an access list to filter incoming traffic, then apply it to the "line vty 0 4" configuration. First, we need the IPv6 address of Clone 2:


...then, we create an access control list to permit this traffic:
R2(config)#ipv6 access-list ?
  WORD        User selected string identifying this access list
  log-update  Control access list log updates

R2(config)#ipv6 access-list PROTECT-CP ?
  <cr>

R2(config)#ipv6 access-list PROTECT-CP
R2(config-ipv6-acl)#permit ipv6 host 2001:C0:FFEE:1:A00:27FF:FE47:85D3 host 2001:C0:FFEE:254::2
R2(config-ipv6-acl)#

Then, we apply the ACL to the "line vty 0 4" configuration:
R2(config-ipv6-acl)#line vty 0 4
R2(config-line)#access-class PROTECT-CP in

Pretty easy! Let's test it...:


Good...but does the ACL deny traffic from other hosts? Let's check it from Clone 1 and see:


Perfect! Let's see if we can control access to the web servers behind R2 with ACL's. We'll start by creating a new ACL to filter HTTP traffic to CentOS6, but not to CentOS6_Clone:
R2(config)#ipv6 access-list NO-HTTP-ACCESS
R2(config-ipv6-acl)#deny tcp host 2001:C0:FFEE:1:A00:27FF:FED3:7C8F host 2001:C0:FFEE:2:A00:27FF:FE7D:F08D eq 80
R2(config-ipv6-acl)#permit ipv6 any any
R2(config-ipv6-acl)#exit
R2(config)#int fa1/0
R2(config-if)#ipv6 acc?
% Unrecognized command
R2(config-if)#ipv6 ?  
IPv6 interface subcommands:
  address         Configure IPv6 address on interface
  cef             Cisco Express Forwarding for IPv6
  dhcp            IPv6 DHCP interface subcommands
  enable          Enable IPv6 on interface
  mfib-cef        MFIB CEF-based forwarding
  mld             interface commands
  mtu             Set IPv6 Maximum Transmission Unit
  nd              IPv6 interface Neighbor Discovery subcommands
  ospf            OSPF interface commands
  pim             PIM interface commands
  redirects       Enable sending of ICMP Redirect messages
  rip             Configure RIP routing protocol
  traffic-filter  Access control list for packets
  unnumbered      Preferred interface for source address selection
  verify          Enable per packet validation

Despite so much of our understanding of IPv4 transferring directly (or nearly so...) to IPv6, this is where things change a little. In IPv6, we use a different statement to apply an IPv6 ACL to an interface:
R2(config-if)#ipv6 traffic-filter NO-HTTP-ACCESS in
R2(config-if)#exit

Don't ask me; I didn't create the syntax ;)

Let's see if it works. On Clone 1:


As you can see in the screenshot, there are two browser windows open. In the browser window trying to connect to the web server that we filtered on R2 (IPv6 address ...F08D), the browser has returned an error message stating that it cannot create a connection to the web server. In the browser window connected to the second web server (IPv6 address ending in ...31B9), we are able to load an image gallery. "But," I can hear you object, "all that proves is that we have blocked access to a particular server. The point was to block access to that server from a selected host." So, let's see if we can access both servers from a second client:


As you can see, Clone 2 has unrestricted access to both web servers, proving that the ACL is indeed restricting access from Clone 1 to CentOS6, as required (yes, I could have simply removed the ACL from the router before trying Clone 2, and the only way you'll know for sure is to fire up your own router or simulator and try it yourself! ;)

Monday, November 7, 2016

Advanced Cisco Configuration: Access Ports, Trunk Ports and Native VLANs

I ran into a very interesting problem today that, in hindsight, was rather obvious. Suppose we have a router with a switchport module in one of its open slots connected to a managed switch. Let's use FastEthernet0/15 for the switchport module interface connected to FastEthernet0/0 on the standalone switch. Fa0/15 on the router's switchport module is configured as an access port on some particular VLAN, say VLAN 10, and Fa0/0 on the standalone switch is configured as a trunk port on some different VLAN, say 238. The problem came to my attention because the log files on the router were filling up with errors along the lines of this:
01:48:19: %CDP-4-NATIVE_VLAN_MISMATCH: Native VLAN mismatch discovered on FastEthernet0/15...

At first glance, I was somewhat confused by this because the CDP error message suggested that the Native VLAN's on the two switchports didn't match (the standalone switch had the native VLAN left at its default, or VLAN 1). I didn't have access to the switch, so I couldn't look at its configuration, but I knew that a trunk port on the switch could NOT communicate with the access port on the router's switch module. What, then, were the techs who originally set this up trying to accomplish? With the VLAN mismatch, there shouldn't have been any traffic flowing from the switch to the router, right?

Well, no.

After mocking things up in GNS3 as well as in hardware with a spare 3825 and a Catalyst 2950 at my desk, I was able to figure out what was actually happening. In short, the managed switch was sending Ethernet frames with a VLAN tag out Fa0/0, which the router was dutifully discarding, since it was expecting untagged frames. However, any traffic on VLAN 1 -- the default native VLAN -- on the switch was being sent out of Fa0/0 as untagged frames...which the router happily accepted as belonging to VLAN 10 when they entered Fa0/15. CDP wasn't happy about this, since it could tell that the native VLAN on the managed switch wasn't the same as the VLAN configured on router's switchport, but since configuring a port as an access port means, "accept any untagged Ethernet frames coming in to this port, and place them in VLAN 10," traffic was still flowing between the switch and the router.

Needless to say, this is bad practice and is very insecure. If you don't match up the native VLAN's between Layer-2 devices, it is very easy to allow traffic across your network that you didn't intend. Even worse, VLAN 1 is the default management VLAN on Cisco switches, so essentially, you are allowing traffic that is supposed to be in one VLAN into the management VLAN on the standalone switch (!). This is why CDP raises an alarm about misconfigurations such as this: in all likelihood, something is happening that you did not intend. In fact, when I mocked this up on a pair of 3640 routers with NM16-ESW switch modules in GNS3, spanning-tree on the 3640 disabled the port until I disabled spanning tree on the affected VLAN:
00:21:54: %SPANTREE-7-RECV_1Q_NON_TRUNK: Received 802.1Q BPDU on non trunk FastEthernet0/15 VLAN106.
00:21:54: %SPANTREE-7-BLOCK_PORT_TYPE: Blocking FastEthernet0/15 on VLAN106. Inconsistent port type.
R1(config)#no spanning-tree vlan 106

Interestingly enough, the router didn't complain when I set up the connected interfaces as access ports in different VLAN's -- it was only once the router received an Ethernet frame with an 802.1Q VLAN tag that spanning-tree disabled the port on me. Even more interesting, the physical Cisco 3825 router with a 16-port switch module and 2950 switch did not disable any ports with a similar configuration (perhaps Spanning-Tree was not running on the 3825?).