Using NSX Service Composer to create a more elegant ruleset

Using NSX Service Composer to create a more elegant ruleset

I help a lot of customers across verticals and segments spitball how they are going to lay out their rules when they implement NSX Distributed Firewall.  For some reason, many of them don’t seem to appreciate how much simpler Service Composer can make the management of these rules via nested Security Policies vs. just doing raw rules directly in the Distributed Firewall.

Example Customer Requirements

Let’s take a simple example of a hypothetical customer who must be PCI DSS compliant, and has three basic environments: Prod, Test, and Dev.  All applications are replicated in all three environments to support their software development lifecycle.  Each application lives in what we’ll call a “zone” that represents the PCI Scope they fall under, and there are 4 such zones:  PCI Issuer, PCI Merchant, PCI Hybrid, and Non PCI (i.e. not in scope at all).  Then, within these zones, there are tiers:  Web Servers, Application Servers, and Database Servers.

Therefore, each VM is going to be a member of an Environment, a Zone, and a Tier.

For instance, a VM could belong to “Prod / PCI Merchant / Database Tier” OR “Test / Non-PCI / Web Tier”.

Let’s also assume this customer has decided to automate the deployment of VMs so they can be sure that appropriate NSX Security Tags are affixed to each VM.  They want to base their Security Groups on NSX Security Tags because they don’t want to care about IP addresses.  Right now let’s say they just have everything randomly distributed on a few big /16s for historical reasons, and they can’t guarantee that one App Server will be on the same VLAN as another App Server from the same Environment/Zone/Tier combination – therefore we wouldn’t want to use rules that involved IP ranges or subnets.

The figure below illustrates the traffic we want to block

*edit: yes, I forgot to include the NON-PCI Zones in the figure.  Sorry.

conceptual blocks

Any of the servers in a particular “Circle of Trust” (i.e. Environment/Zone/Tier combo) should be able to talk on all ports at this stage of the game.  It is common to “tighten the noose” in multiple steps to get to Zero Trust with NSX Distributed Firewall in a brownfield environment – most orgs don’t do it in one shot.  A totally greenfield environment you’re building out, on the other hand…

The following figure shows inter-tier traffic we want to allow.  Note we want to allow this same traffic pattern for each Web-App-DB combination because its the same apps over and over in each of the three environments.


conceptual allows

Flat Schema Using Native DFW Firewall Rules

Their first instinct will likely be to create what we’ll call a “Flat Schema” – one that creates an NSX Security Group for every permutation of Environment, Zone, and Tier.  As you can see below, this requires us to create 36 Security Groups to represent all of these permutations.  Then, they will create 73 native Distributed Firewall Rules that govern how these Security Groups can talk to each other.

In this case, the customer needs to implement firewall rules that make it so only certain ports talk between tiers, but within a given Environment/Zone/Tier combination, we want to allow free communication.  In other words, all web servers can talk freely to other web servers, and all DB servers can talk freely to other DB servers, but between the tiers, we only allow specific ports.

Again, this is a common approach when deploying DFW into a brownfield environment that currently has only VLAN-level security as a first step.  Phase 2 (not shown in this article) is where we “tighten the noose” around intra-tier traffic.

The figure below shows the 36 Security Groups we would create to support the Flat Schema approach:



The next figure shows the 73 Distributed Firewall Rules we would create to support the traffic patterns the customer has specified:


The upside to this approach is that it is relatively easy to understand.  Every allowed traffic pattern is spelled out in an individual firewall rule, and we have a Deny Any at the bottom to prevent any traffic patterns not specifically authorized.  Great stuff.  The downside is, its a lot of rules to create and manage.  This is just a simple example, BTW, most customers that I deal with wind up having many more permutations of Environment/Zone/Tier, so they can easily wind up with several hundred rules.  There’s nothing wrong with this approach, per se.  It still beats the heck outta having to do traditional 5 tuple IP based rules, but it can be overwhelming to a customer new to NSX.

Nested Schema using Service Composer Security Policies

We don’t have to do things that way.  Using what we’ll call the “Nested Schema” can greatly reduce the number of “things” we have to manage – both Security Groups and Firewall Rules.  Using this method, we will create a total of 10 Security Groups, and 14 Security Policies.  This is ~75% fewer “things” we have to manage. 

The table below shows the 10 Security Groups we need to create. 


Note that in this situation, each VM will have 3 security tags and be a member of three Security Groups simultaneously.  I usually group them with labels that show what level of nesting a given group is at.  In this case, Level 1 is the distinction between Prod, Test, Dev.  Level 2 is the difference between PCI Issuer, PCI Merchant, PCI Hybrid, and Non PCI application classes.  Finally, Level 3 represents the App Tier a given VM belongs to.

The table below shows the 14 Security Policies you would create in Service Composer:


Notice how this looks like the inverse of how we lay the rules out in the Flat Schema/Direct DFW rule method.  We use rules to Deny traffic between the Security Groups, and use targeted Allow rules to poke the needed holes between the “circles of trust”.  This has the net effect of enforcing the same security architecture the customer wants where within Environment/Zone/Tier combinations there is free communication, but all communication is blocked by default to other Environment/Zone/Tier combinations – without having to explicitly address each permutation of Environment/Zone/Tier.  BTW in case you weren’t already aware – the NSX Distributed Firewall uses a typical “fall through” algorithm for the firewall rules where the first rule it finds which is applicable to that traffic, it either does an Allow or Deny, then stops there.

When you create these Security Policies in Service Composer, it will dynamically generate the NSX Distributed Firewall rules for you.  You no longer directly edit those rules, just let Service Composer handle that.

Below is a screenshot of what the rules Service Composer creates on your behalf look like.  Its pretty much like any other DFW rules you might create by hand – with a “::NSX Service Composer” suffix appended to the Rule Section it creates so you know SC “owns” that rule.  Again, I didn’t actually create these rules in this part of the interface – Service Composer did it for me once I created the appropriate Security Policies (this is often a point of confusion).


Firewall Rules View

NOTE: it is actually supported to do a combination of both where some rules are “hard specified” straight in the DFW Firewall Rules table, and others are dynamically generated by Service Composer – but I personally don’t recommend this because it gets confusing.

How to actually do this within the vSphere Web Client interface

The Security Groups are created in the same place regardless of whether you are doing direct/native DFW rules or Security Policies.  I put L1, L2, L3 in the Description field, because it will make things easier later.  A Security Group in this model only ever exists on one Level, so don’t worry about nesting the groups themselves.


Security Groups View

I create the Security Policies on the next tab in Service Composer.  I try to have verbose descriptions here to make it easier on the guy who takes over when I get hit by a bus.  Notice that I also use the description field here to denote what kind of rule it is – L1, L2, L3 – is it a standard Deny?  Or a Inter-Tier Exception?


Service Composer View


When you Edit the Security Policies, there are actually multiple things you can have the policy do.  For instance, under Network Introspection Services, you could have it punt the traffic to, say, the Palo Alto VM-1000-HV service for Layer 7 IDS or what have you.  BTW, if you’re using PAN or any other partner based IDS/IPS/Firewall/etc to punt traffic to – you MUST use Service Composer. 

In this case, we will only be messing with Step 3 (firewall rules) in the Policy Wizard. One key thing to understand about Security Policy Firewall Rules – either the Source or Destination must be “Policy’s Security Groups”.  In our case, we are “hard specifying” the Source Security Group, but letting Service Composer dynamically figure out what the destination(s) should be by looking at what Security Groups are associated to this policy.  Note that you do this association in a different screen.


Security Policy Firewall Details - PCI-ISSUER to other L2 SGs

Here’s how you associate a Security Policy with the groups it affects.  In my case, I chose to statically select the Source, so I would therefore need to specify the Security Groups that represent the Destination via Association.  You do this by right-clicking on the policy in Service Composer and choosing Apply Policy – as shown below:




The Apply Policy dialog allows you to choose which of the Security Groups are the Destination (in this case).  Notice that because I put L1, L2, L3, etc in the description field of the Security Groups, I can now filter for what level of SG I want to display.  In the model we’re using, you would pick all Security Groups that are on the same Level as the Source SG.  Do not select the SG that represents the Source when you do this association.  The following image shows what I mean:


Security Policy Apply To Details - PCI-ISSUER to other L2 SGs


Wrapping up

That’s pretty much it.  We’ve already shown what the advantages of this approach are – to the tune of 75% fewer objects to manage (between rules and SGs).  Let me tell you, this makes the rollout of NSX microsegmentation much easier.

A few things to watch out for when you implement what I’ve outlined here:

  1. Slightly steeper initial learning curve for the people who will be managing the rules – but once they get the hang of it, they love it because it saves them so much time
  2. In this specific example, the Web->App->DB allow rules wind up being identical for all Environment/Zone combinations.  For instance, the way I have things laid out in this example all applications involved will have to work similarly – they will need to take 443 from the internet, use 8080/rev proxy to get to the app tier, then use mySQL on the DB.  Since most companies have a variety of application types, in reality, there will likely be a greater number of “Inter-Tier Exception” L3 rules against a greater number of L3 SGs – not just simple WEB/APP/DB.  It would likely be more like App1Web, App1App, App1DB and so forth down the line.
  3. You cannot do L2 rules within Service Composer’s Security Policies.  If you were using L2 FW rules, those would need to be hard specified.  Normally I say don’t mix and match between Service Composer and direct/native DFW rules, in this case its ok because the L2 rules are a totally different class of thing on a different tab – you’re not as likely to get confused.
  4. You must be certain your VMs always have the three appropriate tags.  I generally write a VRO workflow that scans the environment every night/hour/whatever and emails a report to the admins showing what VMs don’t have three tags of the correct type.  If the environment doesn’t currently use some sort of automation to deploy VMs, this is a good time to start – and if you can’t even do basic deployment automation, but still want to use DFW, I’d consider using something other than NSX Security Tags as the basis of your rules.




7 thoughts on “Using NSX Service Composer to create a more elegant ruleset

    1. Ed SHallow

      I noticed your Default Rule is an Any-Any-ALLOW. This obliges you to explicitly include DENY combinations within each level. Is there an alternate way to reduce the rule count even further by drop threw to a catch-all Any-Ant-DENY? Thanks for the article.

  1. Ed Shallow

    Another question if I may. You show 3 levels and include which level a given SG is at in the description. But do you actually nest the SGs in Service Composer? Is nesting of SGs required in your approach?
    Thanks, Ed

  2. Igor Zecevic

    Really nice blog post.
    I have a question: The last SP (Default Allow) is an Allow for any to All SG

    How did you deal request External request to WEB (SG), any will have access on every ports ?
    Because your first rule (SP-1) Allow 80/443 but there is no block rule after that in order to block others services.

    Or maybe you have the last default (DFW) rule set to block?

  3. Bryan Salek

    I’ve got to bookmark this post! I talk customers through this process all the time, usually via whiteboard in a workshop, but I never get to this level of detail and it would be great to sent them here to review your example after that discussion.


Leave a Reply

Your email address will not be published. Required fields are marked *