In an earlier article, I covered what the basics of the NSX Distributed Firewall allow you to accomplish. Now let's take a deeper look at those concepts and figure out the best way to apply them in a real life scenario. If you do a good enough job and you're a little lucky too, you can end up with a easily manageable firewall configuration that you very rarely need to touch, even when adding new components. The target is set, let's get started on our journey to Distributed Firewall nirvana.
First of all, most of the concepts discussed in this article come from a great free book you should read on micro-segmentation called VMware NSX Micro-segmentation Day 1. It's a great resource and a must read if you're serious about implementing the distributed firewall in a production environment. One concept from that book that will come back over and over in this article (it'll come back so often, that it will be annoying!) is that of preferring the use of higher level constructs, rather than lower level constructs. For example, in our case, a low level construct would be Network Based, such as an IP Address. A mid level construct would be Infrastructure based, such as a VM. A high level construct would be Application based, such a Security Tag tied to an application, such as a web server. The higher level the construct is, the more flexible that makes your DFW configuration and the easier that configuration becomes to maintain on the short and long term. In a way, using lower level constructs eliminates a lot of the flexibility that you could attain by tying you down to concepts that are very fixed. Here is a visual representation of this principle, from the book :
Before we go any further, let's do a quick recap of what NSX concepts you'll need to be familiar with.
Security Groups : Security Groups can contain many types of vSphere or NSX object (clusters, VMs, Port groups, Security Groups, Security Tags, IP sets, MAC sets etc.), that makes them very flexible. My first suggestion would be to tie Firewall rules exclusively to Security Groups, not VMs, not IP sets or ranges, etc. If logically, you absolutely need to tie a firewall rule to a range of IPs, you can still put that IP range in an NSX IP Set and put that IP Set in a Security Group. That makes your firewall rules a little more generic and might prevent you from constantly needing to modify them every time a slight change in your network is needed. You can statically include objects in a Security Group, or use their dynamic membership capabilities using hostnames, VM Names or Security Tag names. What I like to do is to have a single Security Tag as a member of a Security Group and assign those tags to VMs. For example, Security Group SG-WebServers has a member Security Tag called ST-WebServers and you assign that Tag to all your web servers.
Security Tags : Tags are metadata objects that can be assigned to a VM. There is nothing simpler than a Security Tag, you just create them assign them to VMs. As much as possible, create Tags that relate to higher level constructs and assign those to your VMs.
IP Sets : Can contain IP addresses, IP Address ranges or IP Address subnets. This is a low level construct, for those firewalling cases that isn't covered by virtual machine traffic. IP Sets can be members of Security Groups. So don't bind firewall rules to these, use Security Groups instead!
Services : A Service is essentially a mapping to a Protocol (TCP, UDP, ICMP, etc.) and to one or many ports. For example, there is an existing service for the HTTP protocol, it is mapped to protocol TCP and port 80. NSX comes with hundreds of pre-existing Services and you can create your own custom Services. I strongly suggest this, because you don't want your firewalls binded to static ports and have to ask yourself what port 5487 is used for, months from now. Also, a Service is a higher level construct than a port/protocol pair.
Service Groups : Service Groups are just… groups… of Services… The principle of tying your firewall rules to higher level constructs applies here as well, it's nearly always better to use Service Groups rather than Services, but as always, exceptions might apply.
Security Policies : Security Policies are basically a set of Guest Introspection (which is out of scope for this article) and Firewall rules. You can also give every policy a weight, which will determine in which order your Policies are applied on the Distributed Firewall.
Firewall tab in the vSphere Web Client's "Networking and Security" plugin : This view will contain every rule that is applied to the distributed firewall, whether it is applied through a Security Policy or directly in this tab as a "global" rule. You will also see rules that are applied to "All Edge Gateways", which is not enforced by the distributed firewall, but by the NSX Edges' stateful firewall.
How do I use all these objects to build a Distributed Firewall configuration?
There are hundreds of different ways of combining these objects to get a "working" distributed firewall configuration. Here is the recipe I used, after consulting with many experts, getting feedback from those managing it, affected by it and also having to maintain this configuration for a period of time. By no means is this the only potential solution to your distributed firewall problems, but hopefully it can be a solid starting point for you to build your configuration.
- The key here is to use the right approach to building your firewall rules. As much as possible think in terms of application server "types" or similar concept, not in terms of IP networks.
- Slice your Security Policies by Application server "types" for example, you can have a Policy for "web" servers, another Policy for "app" servers, another for "db" servers and so on. That will give you many different granularly managed Security Policies. This is just one way of slicing the policies, there are many other options, but I found that this approach works great so far for my environment.
- Pick a traffic flow direction to start building your firewall rules, either inbound or outbound. Personally, I find it a lot simpler to say that server type "web" needs to talk to server type "app" and server type "search" on port 3454, rather than doing it the other way around and thinking "ok, so what needs to talk to my web servers?". My vote goes to building exclusively outbound firewall rules in Security Policies. It also makes documenting the rules very easy.
- Using this logic, I've found that Security Policies "weights" don't carry much importance, but still keep an eye out for that, it might be different for your environment.
- Always tie your firewall rules to Security Groups.
- Security Group membership should preferably use Security Tags tied to a server type, VM Hostname dynamic membership rules for funky/very specific firewall rules , IP Sets, but not much else. A word of caution though : If you find yourself constantly needing to put lower level constructs inside Security Groups, that might indicate that your DFW design needs improvement. Also, if you decide to use VM Naming for Dynamic Membership, make sure you have rock solid naming convention in your environment and that the proper controls are in place to ensure that renaming VMs won't break firewall rules or cause a security risk. Also consider that if you one day decide to change the VM naming convention, that could seriously mess up the entire firewall logic in your environment. That's a pretty hard dependency between two things (VM naming convention and firewalling) that should NOT exist. That's why it is a good practice to use a higher level construct than a VM's name.
- Create 1 Security Group and 1 Security Tag per server type and attach the Tags to the VMs. This very simple logic can cover a huge chunk of the firewall rules in your environment, maybe even 100% of your VM-to-VM traffic.
- Create IP Sets for any in/out non-VM traffic.
- Always tie your firewall rules to Security Groups.
- Did I mention this? Always tie your firewall rules to Security Groups. This makes things much more flexible in the long run.
So what's the right way to do it? I'm going to be boring and say it depends on your use case. But as long as you stick to high level constructs as much as possible, and that your logic is sound, you should be fine.
Distributed Firewall VS. Edge Gateway Firewall
After all this Distributed Firewall talk, let's not forget that there is probably a valid use case for both the DFW and the Edge firewalls in your environment. As it is often mentioned, Edge Gateways should be used when dealing with North-South traffic, that can still apply here. In one case I've seen where each customer had a single edge gateway that they would use for many different services, we'd use that edge's firewall simply to segregate customers amongst themselves and to filter traffic coming in and out from the internet. The rest of the internal (East-West) network traffic is what the Distributed Firewall handles. You can always decide to give more or less responsibility to each of these 2 types of firewalls, depending on your use case. It often depends on what you use your Edge Gateways for and conversely how heavily you are willing to be tied to the distributed firewall.
One more tip I can give is that like I briefly mentioned earlier, you can set Edge Gateway firewall rules in the "Firewall" section of the Networking and Security plugin in the vSphere Web Client, as opposed to going Edge by Edge and applying them directly there, this can save you a lot of time if you have rules that apply to ALL of your Edges. When creating the rule, you just have to modify the "Applied To:" field from "Distributed Firewall" to "All Edge Gateways".
The bottom line
If you're building a new environment that includes VMware NSX in the picture, the distributed firewall deserves your consideration. NSX allows you to automate your firewall configuration, not using fancy orchestration, but by using simple policy-based logic that is configure once and forget. You'll enjoy all the free time!