Isolation without firewalling - private vlans

This is a very exciting topic. I recently observed a conversation where sysadmins talked about network problems. Well, go figure :) But anyway, instead of joining, I just listened and as the conversation progressed, I was more and more confident that I had my next article to write about. It seemed that these folks had a serious problem understanding the concept of vlans. I don't really see why, as there is another post about vlans right here, how come they never read it? Getting past that, I have decided to take this a step further and confuse them even more by introducing them to private vlans. And why wouldn't I do the same to readers here? So let's get to it.

We all know what vlans are, how they operate, what they are for etc. Those are normal vlans. This post today is about private vlans. Private vlans are like nested vlans or sub-vlans. A vlan in a vlan if you will. Don't get lost, it's going to be quite simple in just a minute. Suppose you're a netadmin and you have a bunch of servers, all within a vlan. Say this is the backup vlan. All of your servers have a second, dedicated interface that belongs to the same vlan which is for backup purposes only. Meaning, that the only IP address you're supposed to reach in this vlan is the backup server, so every host can transfer its own backup to a central storage. No other communication is allowed. The hosts can't talk to one another except for the central storage, there is no internet access (remember: this is a second NIC in every host). Now: how would you isolate the traffic? You'd use port-based ACLs on the switchport? As this is a layer 2, switched network only, there are no routed interfaces on the switch. With a few servers, this may even be feasible. What if there are not ten or twenty, but five hundred servers? What if MAC addresses changed? Would you still use layer 2 ACLs? Let's explore this idea for a bit.

If you knew the MAC address of the central storage server, you could create an ACL, say:

mac access-list extended backupserver-only
 permit any host 1111.1111.1111
!

where the 'all-ones' MAC is the known address and you could apply this ACL onto each and every switchport like:

interface FastEthernet0/1
 switchport mode access
 mac access-group backupserver-only in
 spanning-tree portfast
!

The above would probably work. It would be a nightmare to maintain though. If the MAC address changes, every switch has to be reconfigured. If the port-based ACL is missed from several switch ports, you have an insecure network. Also, this solution is everything but scalable. What if by tomorrow you have not one, but ten central storage servers? What if not ten but a hundred? How long will it take you to update the ACLs? What if different servers back up to different storage units and they are only supposed to talk to their designated storage? I think by now you have realized that I wouldn't have started this post if port based ACLs were the solution. So let's see something more advanced! Private vlans!

As I have said, private vlans are like nested vlans. Think about private vlans as a subset of the original vlan. Say you have vlan 1, with an address range of 1.1.1.0/24. Without private vlans, all stations having an access port in this vlan with a valid IP address wil be able to address any other station configured in the same way. This is the traditional vlan approach. However, switchports that belong to different private vlans within the same original vlan will not be able to talk to one another. Furthermore, switchports in the same private vlan may not even be able to talk to one another. What? How is this possible?

Switchports that are configured to belong to a private vlan can have three ways of operating. They can belong to an isolated private vlan, or a community private vlan, or a promiscuous private vlan. A promiscuous port is able talk to anyone. That's simple. A community port can talk to other community ports and the promiscuous port. Isolated ports can talk to nobody, but the promiscuous port. This is the three layers of segmentation that we can have, within the same vlan, without any firewalls. This meaning, that while everybody would have an IP address from the same subnet: 1.1.1.0/24, they won't necessarily be able to talk to each other. This is because although we still use the same ip range, we now have split the vlan up into multiple smaller segments (nested or sub-vlans) that share the same IP addressing scheme, but are isolated from each other. Warning: this can drive sysadmins crazy! :) Let's see how can we enable private vlans.

For this demonstration, I'm going to use three devices that I happen to have on my desk today. The private vlan capability will be demonstrated on a Cisco 3650 switch. For two communicating stations I'll be using another two catalyst switches (a desktop 2940 and also another desktop 2960). These two will represent hosts who - given the scenarios - need to or need not to be able to talk to each other. Please see the topology below.



This is a pretty basic topology with all the devices included. This is where we start from and our first goal is to prevent the C2940 switch and the C2960 router from talking to one another. We'll do this by putting them into different private vlans. The two sub-vlans will be 101 (community) and 201 (also community). But for us to be able to start, we'll have to disable VTP first. VTP and private vlans don't mix. So let's get to it:

c3650#conf t
c3650(config)#vtp mode transparent
Setting device to VTP TRANSPARENT mode.
c3650(config)#exit
c3650#sh vtp status | i Operating
VTP Operating Mode              : Transparent
c3650#

Let's also verify that as a starting point, everyone can reach everyone else:

c3650#ping 1.1.1.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/8 ms
c3650#ping 1.1.1.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/9 ms
c3650#

Now that we have VTP out of the way and have done some basic checks, let's create the two sub-vlans, 101 and 201. For this, we define the existing vlan (vlan 2 that is) as a primary vlan and then create the two additional sub-vlans.

c3650#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
c3650(config)#vlan 2
c3650(config-vlan)#private-vlan primary
c3650(config-vlan)#vlan 101
00:24:27: %LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan2, changed state to down
c3650(config-vlan)#private-vlan community
c3650(config-vlan)#exit
c3650(config)#vlan 201
c3650(config-vlan)#private-vlan community
c3650(config-vlan)#exit
c3650(config)#vlan 2
c3650(config-vlan)#private-vlan association add 101,201
c3650(config-vlan)#end
c3650#

As you can see, vlan 2 is re-defined as a primary vlan (after which point soon the vlan 2 SVI goes down). The two new vlans are created (101, 201) and immediately defined as community vlans. And then both are associated with the 'normal' vlan, vlan 2. Let's check what we just did:

c3650#show vlan private-vlan

Primary Secondary Type              Ports
------- --------- ----------------- ------------------------------------------
2       101       community
2       201       community

So, at this point it looks like that we have all the ingredients: the primary vlan and two secondary vlans. We're not done yet, but just to see where we are: the two desktop switches can still ping one another, as we haven't done anything with the brand new vlans. The only change so far is that the SVI went down on the 3650, so let's keep on going and configure the two switchports on the multilayer switch:

c3650#conf t
c3650(config)#int gi 0/1
c3650(config-if)#switchport mode private-vlan host
00:33:58: %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet0/1, changed state to down
c3650(config-if)#switchport private-vlan host-association 2 101
00:34:24: %LINEPROTO-5-UPDOWN: Line protocol on Interface GigabitEthernet0/1, changed state to up
c3650(config-if)#exit
00:34:54: %LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan2, changed state to up
c3650(config)#int fa 0/48
c3650(config-if)#switchport mode private-vlan host
00:34:58: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/48, changed state to down
c3650(config-if)#switchport private-vlan host-association 2 201
c3650(config-if)#end
00:35:10: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/48, changed state to up
c3650#

As you can see from the console messages above, all interfaces have flapped at some point during configuration. This is normal. Now, let's look at what we've done:

c3650#show interfaces gi 0/1 switchport
Name: Gi0/1
Switchport: Enabled
Administrative Mode: private-vlan host
Operational Mode: private-vlan host
[...]
Access Mode VLAN: 2 (primary)
Trunking Native Mode VLAN: 1 (default)
[...]
Administrative private-vlan host-association: 2 (test) 101 (VLAN0101)
[...]
Operational private-vlan:
  2 (test) 101 (VLAN0101)

Looks allright. Now it's time to test. We'll switch to either desktop switch, will try to ping the other and will fail, although both are in the same subnet and there are no firewalls in between. Then, just to see that this is all caused by the private vlan configuration, we'll put them both into the same community vlan 101, to see that after this they will be able to talk to one another.

c2960-8tc-s>ping 1.1.1.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms
c2960-8tc-s>ping 1.1.1.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.3, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
c2960-8tc-s>

The first ping is to the switch itself to ensure that layer 3 is up and running. The second ping demonstrates the lack of connectivity. Now, to do a counter test: going back to the multilayer switch and assigning them both to the same private vlan which has type set to community.

c3650#sh int status | ex disable
Port      Name               Status       Vlan       Duplex  Speed Type
Fa0/48                       connected    2,201      a-full  a-100 10/100BaseTX
Gi0/1                        connected    2,101      a-full a-1000 10/100/1000BaseTX SFP
c3650#conf t
c3650(config)#int fa 0/48
c3650(config-if)#no switchport private-vlan host-association 2 201
00:45:58: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/48, changed state to down
c3650(config-if)#switchport private-vlan host-association 2 101
00:46:02: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/48, changed state to up
c3650(config-if)#end
c3650#sh int status | ex disable
Port      Name               Status       Vlan       Duplex  Speed Type
Fa0/48                       connected    2,101      a-full  a-100 10/100BaseTX
Gi0/1                        connected    2,101      a-full a-1000 10/100/1000BaseTX SFP
c3650#

And now it's time for the same test to ensure that we have restored connectivity.

c2960-8tc-s>ping 1.1.1.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/3/8 ms

Now, let's see what would happen if the private vlan type wasn't community, but isolated? We'd expect the pings to timeout again, although they are in the same private vlan, but that's not a community vlan anymore. Let's configure this:

c3650#conf t
c3650(config)#vlan 101
c3650(config-vlan)#private-vlan isolated
c3650(config-vlan)#end
c3650#

Again, with nothing else changed, let's test connectivity, using the very same test as before:

c2960-8tc-s>ping 1.1.1.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.3, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
c2960-8tc-s>

No surprise here, it all works as expected. Now, let's tweak it again a bit: let's make the other switchport a promiscuous port. As mentioned earlier in this post, my example scenario was a backup system where all hosts were to talk to a central storage, but not to each other. So we've seen that the two switch ports are not able to talk if they are associated to an isolated private vlan. Let's make one of them a promiscuous port and see if that achieves our goal? The configuration is simple:

c3650#conf t
c3650(config)#int fa 0/48
c3650(config-if)#switchport mode private-vlan promiscuous
00:52:38: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/48, changed state to down
c3650(config-if)#no switchport private-vlan host-association 2 101
c3650(config-if)#switchport private-vlan mapping 2 add 101
c3650(config-if)#end
00:54:23: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/48, changed state to up
c3650#

Testing time again, see if this works, can the 2960 now ping 1.1.1.3?

c2960-8tc-s>ping 1.1.1.3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 1.1.1.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/9 ms
c2960-8tc-s>

Boom! Well, no surprise here! All tests above have confirmed that private vlans work as we'd hoped. Now: why is this good? What can we benefit from this? Well, there can be multiple valid scenarios here. My favourite is the backup server, where the storage would be on a promiscuous port, that can talk to anyone, but everyone else would be an isolated switchport. All would have the same IP range, subnet mask etc, but still, there would be a pretty good level of isolation in between. As an additional layer of security. Another valid scenario can be a DMZ architecture. Imagine where in a DMZ there are several servers. These all need to talk to their router (default gateway) but definitely not to each other. So if one server is compromised, the rest can still remain intact - nobody can use your server as a jumphost. A third example would be an enterprise environment, where you need to provide your clients IP addresses from the same vlan, but still, prefer to keep them separated. Private vlans to the rescue!

This is the end my friends. Now you know all about private vlans and their usage. Yes, I know. It's pretty confusing. So take your time, read it through once more. Or even better: use your equipment and lab it all out. Then feel free to go and impress your sysadmin friends :)