In this post I will explain how you can use Azure Network Security Groups (NSGs) to prevent unwanted or dangerous traffic from leaving your Azure virtual machines.
Have you a written policy that prevents administrators from browsing the Internet from servers? Have you found that they find creative ways to bypass your policies? Are you worried that some malware will encrypt the data on your file or database servers? Or worse; is there a chance that some hacker will download sensitive data from your machines in the cloud?
I have a solution for you: Network Security Groups, aka NSGs. An NSG is a policy that contains a number of distributed firewall rules that either allow or block traffic. The rules (featuring stateful inspection) are simple enough:
- Source address/location/ and port range.
- Destination address/location and port range.
- Allow or block.
Using a priority value (low is high, and high is low), we can stack rules to create a granular policy. For example, a low priority rule can block all inbound traffic and a high priority rule can allow TCP 3389 (remote desktop aka RDP) in.
The below rule allows HTTP traffic into a virtual subnet.
We can associate an NSG with:
- A virtual machine (Azure V1 / Service Management / Classic)
- A virtual machine NIC (Azure V2 / Azure Resource Manager / ARM / CSP)
- A subnet in a virtual network
The preferred option is to enforce the rule at the subnet level, therefore a subnet is a security boundary and all machines in a subnet should have the same rules. If you need different rules for different machines, then add subnets. The stated best practice by Microsoft is to associate an NSG with a subnet.
An NSG contains a collection of default rules. For example:
- All inbound traffic from the Internet is blocked, via stacking of inbound rules.
- All traffic to the Internet is allowed.
It’s that last rule that I’m concerned with in this post. You can see the rule with a priority of 65001 below; it allows all traffic, from anywhere, to route via Azure to the Internet.
What does that mean?
- Traffic can leave my Azure virtual machines and go to the Internet.
- If I have ExpressRoute or a VPN, traffic could (if routing is enabled) route via that site-to-site connection from my office to the Internet (through Azure).
That worries me. And here’s why:
- Admins can log into my Azure machines and browse the Internet. I don’t want that. My machines have no need to connect directly to the net; I’m going to proxy/inspect everything or I’m running an ultra-secure environment, WSUS will provide my updates, or I’ll download/upload anything I need via my PC.
- Malware can talk to it’s controller to receive activation orders.
- A hacker that gets onto my servers can initiate a download from my servers.
There’s one great big hammer you can swing to stop all of the above. Warning: this is a hammer and should be evaluated and tested. I can put an additional outbound NSG rule to block all outbound traffic that sources from anywhere and routes to the Internet. This rule has a higher priority (lower number) than the default rules so it will override the “allow all outbound” rule and lock down my environment.
A variation on this approach would be to use a much higher priority, such as 4000, for this new rule, and create other higher priority rules to allow very specific outbound access from the virtual network.
Thanks to stateful inspection, my inbound application traffic can still function via the inbound rules in the NSG, but the above rule denies all traffic from leaving this subnet for the Internet. Me 1, dodgy stuff 0.
A Word of Warning
I did compare the above to a hammer, and hammers can break things. If you follow the above, you will … break things Azure requires that Azure VMs have the ability to reach the “Internet” zone to get updates from … Azure IP addresses (which are regarded as “Internet” by NSGs). The real solution is actually a lot more complex requiring a lot of rules to allow a lot of Azure IP ranges. Microsoft’s Keith Mayer has a solution for identifying these IP addresses (documented by Microsoft) and creating filtered outbound access to just those IP addresses using PowerShell.