This post will show you how to use Azure Resource Manager (ARM) or a CSP subscription to deploy network security and policy enforcement in the form of network security groups (NSGs).
I recently wrote another post, “What Are Network Security Groups in Azure Resource Manager?” I went into great detail about what an NSG is and how it works, but here is a quick reminder.
An NSG is a collection of rules that describe what traffic is allowed in our out. The rules specify source and destination address, the protocol, and the source and destination port. We can associate an NSG with a subnet (best practice) which affects all virtual machines on a subnet. Or we can associate an NSG with a virtual NIC (not a virtual machine), which affects that connection of a virtual machine.
I have configured a small environment in Azure with a single subnet in a virtual network in a resource group called web-rg. There are two virtual machines, each with a single virtual NIC. Both machines will be web servers. I am going to create an NSG that I will assign to the subnet that will:
- Allow TCP 80 (HTTP) in
- Allow TCP 443 (HTTPS) in
- Allow TCP 3389 (remote desktop) in
- Prevent all traffic from the web servers to the Internet
Create an NSG
Open the Azure Portal (https://portal.azure.com) and sign in. Click New, search for “network security group”, select Network Security Group (published by Microsoft in Networking), and click Create. A blade will open to allow you to create a new NSG.
You will have to enter some information:
- Name the new NSG
- Select your Azure subscription (usually the current one)
- Either create or select an existing resource group
- Select a region to deploy the NSG into
Note that you can create an NSG in one resource group and deploy it to resources in another resource group. Maybe larger organizations might do this to allow IT security to manage NSGs in their own little environment. But you must ensure that the NSG is deployed into the region that contains the networks or virtual machines that you want to secure.
Inspecting Default Rules
The NSG should be ready to work with after a couple of minutes. Open the NSG and go to All Settings. There you can see options for Inbound Security Rules (inbound traffic) and Outbound Security Rules (outbound traffic). Click on Inbound Security Rules.
It appears that there are no rules, but click Default Rules. Now you will see the default rules that affect inbound traffic to all machines affected by the NSG. Repeat this will Outbound Security Rules.
Associate the NSG
In the settings of the NSG you can see options for associating the policy with network interfaces (machine virtual NICs) or (virtual network) subnets. It is a best practice to associate NSGs with subnets, so I will do that. Click Subnets, click Associate, choose a virtual network, and then select the subnet that you want to associate the NSG with.
The NSG is now affecting the default network policy on the subnet and thus all of the virtual machines in the subnet.
Create Inbound Rules
The default DenyAllInBound rule is preventing my webservers from being accessible on the Internet. I need to allow access for HTTP and HTTPS traffic from the Internet.
Open the settings of the NSG, click Inbound Security Rules, and click Add. You can configure a new inbound security rule with the blade that opens.
My first rule will allow all TCP traffic from the Internet that is destined to TCP 80 (HTTP) on my virtual network. Note how Source and Destination allow options to:
- Allow any source/destination
- Put in a CIDR block or network address
- Enter a tag such as Internet, VirtualNetwork, or AzureLoadBalancer (a probe for machine health detection)
I give the rule a weight of 100, which is the highest priority and outweighs and overrides the default rules. This means that TCP 80 is allowed in (under the above conditions), but all other inbound traffic is blocked.
I then repeat the process to allow TCP 443 in, but with a weight of 200. And finally, I add a rule with a priority of 300 to allow TCP 3389 (remote desktop) in to the virtual network from any source.
Create Outbound Rules
Return to the settings of the NSG, click Outbound Security Rules, and click Add to create an outbound rule to control what traffic can leave the web server subnet. I will use this kind of rule to prevent traffic leaving the web servers, for example, data leakage after an attack or browsing by admins from the servers.
Note: this rule is a sledge hammer and you should evaluate, test, and question the usage of this kind of rule.
The rule (priority of 100) overrides the default AllInternetOutBound rule (priority of 65001). The destination (tag of Internet) to all ports from the source (tag of VirtualNetwork) on all ports and protocols is denied, as shown below.
Testing the Solution
The NSG has been associated with the subnet that the web servers are connected to. If I browse to the web servers using HTTP or HTTPS (if the servers are configured for HTTPS), then I can still browse the website, despite blocking all traffic from the web servers to the Internet (stateful inspection).
I can still, thanks to my TCP 3389 inbound rule, remote desktop into my virtual machines. But when I do log in, I quickly find out that I cannot access the Internet from my virtual machines. I tried to browse the Internet from one of the web servers in the below screenshot.
This means that admins cannot bypass policy by browsing the Internet from production servers, malware cannot communicate with a controller, and data leakage is not possible from these machines. The only traffic to/from the Internet that is allowed is web traffic, and remote desktop is allowed from all sources. This shows how powerful an NSG can be at enforcing network policies.