CLOUDSEC – Securing Cloud Networks with Hub-N-Spoke and Azure Firewall (Azure Lab 1)

This lab builds a foundation Azure virtual to later test the Microsoft suite of security products in Azure. With the code examples and a few manual changes you can deploy one hub, four spokes with an advanced firewall appliance, jump hosts and IPSEC tunnel all within an hour using Azure ARM automation.

Although Microsoft has been the laggard in the cloud game, they are emerging with with an intriguing integrated security suite across Azure Defender, Azure 365, Azure Endpoint, Azure AD, In-Tune and Sentinel. Testing these and other features is the end goal and this post is just a stepping-stone on the way there.

As I set-up the lab environment, this post will journal architectural notes and findings around building out an entire virtual hub and spoke network with IPSEC integration to office and jump hosts.

There are other architectural alternatives to the hub and spoke design, such as more complex and “dedicated” isolated virtual networks which are not peered (think compliance/risk adverse driven designs) or complete mesh topology that are logically flat. Those design patterns are not the end goal of this lab, so we’ll just explore the the hub-and-spoke pattern and a number of other Azure features along the way.

What is the hub-n-spoke design

An Azure VNET hub virtual network acts like the central choke point of connectivity between many spoke Azure virtual networks within the cloud (East-West traffic) and the hub VNET can also be used as the connectivity point to your on-premises networks and the internet as well (North-South traffic). The Azure virtual network essentially deploys a virtual L3 network with virtual routers and gateways which manage your L3 local routes tables and encapsulates the traffic so an overlay network enabled by VXLAN or NVO3 protocols can run multiple customer networks on “shared hardware”. There are pros and cons to the hub design and other architectural design considerations and we’ll uncover all that stuff later.

Microsoft’s Reference Architecture

Example of a hub and spoke network topology

An Azure HUB network design is created with the use of VNET peering to a centralized VNET while avoiding a mesh topology and interconnected VNET peers. Azure achieves this design with something called service chaining where a virtual appliance (Azure or Self-Managed) is hosted in the external virtual network and network routes are updated to direct all traffic to the virtual appliance to create a “transit network”.

Azure documentation is deceptive, because by default VNET peering does not supporting transitive peering, however with service chaining and using virtual appliances you essentially NAT/Proxy traffic between virtual networks, which creates a centralized network routing point and security enforcement and monitoring point. Or depending on your philosophy, VNET peering also increases the attack surface for lateral movement within your cloud network.

the logical Azure services consumed

For those new to Azure or familiar with AWS or GCP but not familiar with Azure lingo, I’ve included this logical illustration to help communicate the various Azure service and resources that are configured in this lab. This illustration does not cover the network topology which is provided later in the article.

Essentially, I give you some code template in json, you can upload those json files and the Azure resource Manager (ARM) will help deploy some of the basic infrastructure and configurations explored in this article.

what is the azure firewall

The Azure firewall is an Azure managed PaaS firewall appliance that we’ll host inside the HUB VNET. Azure manages the lower level “hardware” and “installation” parts of this firewall, so you don’t have to install any virtual appliances. Azure Firewall is a statefull firewall and the “premium tier” option offers other Azure integrations such as TLS interception + deep packet inspection and integration into Microsoft security center threat intelligence for malicious IPs/domains and IDSIPS for anomalous rule based detection. I’ll pen test these features later once we have some assets hosted and running.

The Azure firewall goes beyond the concept of Network Security Group (NSG) or Application Security Group (ASG) which are typically used apply packet filtering on the more granular “cloud service” and “virtual network IP ranges”… they offer limited integration with external security products and are not “routable” or “transitive” like the Azure firewall appliance is. Think of “Security Groups” more like a host ACL… applied at the cloud server or subnet level… but you cannot re-route all packets a “centralized” NSG or ASG per se ….. they only apply to the logical subnet or group of servers you choose…

Alternatively, to avoid the in-line appliance design, you could have a “big mesh” of peered networks with open routing and a security group baseline with additional security group ACLs applied on top of the baseline. This alternative design creates complexity of managing many peering + routes + micro segments and you lose the benefits of emerging AI/ML and rules based security signature detection and prevention technologies in the native cloud appliance.

We’ll also be using the Azure Firewall Manager which is Azure’s take on a centralized policy management engine that allows the management of multiple deployments of virtual firewall, web application firewall, DNS filtering etc. across regions. There is a steep additional charge for this product based on per policy and it’s best to tear this service down and re-deploy with code to reduce your lab costs

just give me the executive summary

Sorry, you have to exercise those brain muscles and read . ..

Show me the code …

Okay, as long as you abide by the rule of my creative commons licenses and MIT licenses.


Azure Firewall: The Azure Firewall can get expensive in terms of personal Lab environments making the barrier to entry very high unless you’re personally and financially committed. It looks like I’m being charged Standard ($1.25) + ($0.875) for premium an hour or around $44/day and $1,300+ /mo. Thanks Microsoft )-8 ….

Compare that to the Azure Market Place Palo Altos VMs which range from $1.00/hr to $3.00/hr and you have to pay for the additional scale, fault tolerance and operations that you get for free with Azure plus they miss all the AI/ML security bells and whistles.

For the lab, I tear down the firewall everyday when I’m not using it and re-deploy it with the deployment.json templates in my Github. This will save you around 70% compared to running the platform 24×7 during labs, so it might cost around $200 to $400 to learn the platform working everyday for a month straight.

Azure Network VPN Gateway: The basic VPN Gateway is $.04/hr or $30/month, which is more reasonable and tearing this platform down and re-deploying will take around 20 minutes to redeploy every day. As a side note, the Azure standard VPN option does not support BGP… to test the BGP supported machine then you’re talking about paying 5x more. I found a bug when you choose the Basic SKU Gateway option which defaults to a 5x more expensive gateway appliance…. Thanks Microsoft … )-8

Azure Firewall Manager pricing is somewhat deceptive much like the Azure Firewall. You’re not required to use this service and you can use the native “classic” firewall feature. There is a $100 /mo per policy per region and other pricing tiers based on “how” you use the product such as in a HUB. I’m uncertain whether the design specific pricing tiers is “in addition” to the $100 so proceed at you’re own risk. I tear it down daily when not in use.

Virtual Machines: I use A-series general purpose with HDD which range around 0.091/hour or $65.00 /mo when running 24/7 and they perform well in lab. I only run them around 70% of the time reducing the total lab cost.

In total, you could be in the spend somewhere around $200-$500 a /month to learn all these services if you tear them down and redeploy them as-needed. Typical Microsoft to target the corporate clients and not the developers who build, market and sell the product for them. The above costs don’t cover bandwidth usage and storage costs but because this this is small lab, there isn’t much cause for concern.

building the environment

Resource Groups and Subscriptions

You will need to create a Azure management groups and Azure subscriptions to eventually configure the lab resource groups and deploy virtual resources. In Azure, management groups and superscriptions act like abstracted folders that allow you “group” cloud assets together while billing them separately and applying security and IT policies more centrally at a higher level. The way in which you “group” and “organize” your cloud assets may be a function of your specific organizational model, your IT operating model, purchasing model etc. etc. and is beyond the scope of this lab.

I personally used a single subscription in my lab but ideally you’d create separate subscriptions for each Tenant’s VNET then you can cleanly map Azure AD groups to subscriptions and ultimately the resources within that subscription and that network. You’d end up up with something like an “App-Team AD group” and “Network Roles” AD Group, where the network roles manage the subscription assets VNET that we’re building in this exercise.

PowerShell to Create Management Group

New-AzManagementGroupDeployment `
-Name shared-deployment `
-Location centralus `
-ManagementGroupId Demo1 `
-TemplateFile shared-subscription.json `
-subscriptionAliasName Shared-Infrastructure `
-billingScope "/providers/Microsoft.Billing/BillingAccounts/<long code found in your billing>/enrollmentAccounts/<short code with dashes found in billing>"

Deployment.json to create a Management Group

    "$schema": "",
    "contentVersion": "",
    "parameters": {
        "subscriptionAliasName": {
            "type": "string",
            "metadata": {
                "description": "Provide a name for the alias. This name will also be the display name of the subscription."
        "billingScope": {
            "type": "string",
            "metadata": {
                "description": "Provide the full resource ID of billing scope to use for subscription creation."
    "resources": [
            "scope": "/", 
            "name": "[parameters('subscriptionAliasName')]",
            "type": "Microsoft.Subscription/aliases",
            "apiVersion": "2020-09-01",
            "properties": {
                "workLoad": "Production",
                "displayName": "[parameters('subscriptionAliasName')]",
                "billingScope": "[parameters('billingScope')]"
    "outputs": {}

Azure CLI – Creating the Resource Group


az group create --name hub-spoke --location centralus

microsoft solution vs custom solution

If you Google how to build this solution you’ll find that Microsoft offers a deployment.json template to automate some of the work. Microsoft provides step-by-step instructions but IMO there are some drawbacks to their “easy-to-deploy solution”

Drawbacks to Microsoft deployment.json solution

  • Microsoft provided solution deploys Azure Bastion which I found to be 3x as costly as running a short-lived A-series virtual machine as a jump host and most notably does not work with private DNS zones which will make future windows domain joined machine labs and AD sync labs difficult. Depending on your security philosophy the Bastion solution also enables remote administrative shell access in an internet enabled browser which can be both a feature and a bug.
  • Microsoft deploys and configures a “standard” tier Azure firewall. In future labs, I “standard tier” does not give me access to TLS intercept or the more advanced IDPS and threat intelligence alerts and blocks which is a drawback during future pen testing labs.
  • Microsoft deploys the Remote Access / Jump Hosts and the VPN Gateway inside the HUB VNET. Although their approach may reduce “virtual hops” and processing, IMO the design is not as clean and leads to “filling up the hub” with a bunch of other junk to avoid the default firewall routes. I have a suspicion that the Microsoft provided design has psychological implications … users would be tempted to bundle the HUB under a single subscription, flatten the subnet routes, bypass the FW virtual appliance within the HUB network and manage the entire “HUB” subscription with a single Azure AD Group…. yuck …
  • Microsoft configures the VPN and Bastion remote access subsets without proper User Defined Routes (UDR) and thereby inherit the default permissive routes across the entire HUB VNET, meaning that lateral movement is likely within VNET
  • The Microsoft provided solution is not as “modular” or “de-coupled” meaning you can’t leave some cloud configurations running and temporarily delete other things and redeploy the same template in parts …. You’ll need your own distinct deployment templates anyway if you want to pick and chose what runs and what gets torn down

lab Reference Virtual Network Topology


The topology configures two-types of remote access patterns to demonstrate a few different ideas. The home / office network is integrated using both internet access to a jump box and later site-to-site VPN. After site-to-site is configured and tested, the internet enabled jump hosts and FW rules can be de-provisioned or shut down as they will longer be needed.

Azure firewall DNAT is a destination port forwarding feature in the Azure Firewall. Firstly, you most create a policy collection in the Azure firewall manager and then associate the policy collection with your azure firewall.

Afterwards you can create a firewall rule and NSG rules which allows jump host traffic from the internet client–> firewall–> private subnet. All without provisioning public IPs to private subnet servers which reduces the attack surface to the Azure firewall ingress point.

Azure VPN Gateway are a subset of teh virtual network gateway (VNG) that are deployed in a reserved subnet within your VNET. They act just like physical VPN device and integrate with your local network device i.e. your on-premise VPN gateway.

#1 – Security Architecture Advice

  • In my lab / office integration, I have a physical firewall at the internet edge and a separate inline IDS/IPS/FW devices isolating the client lab machines from DMZ and Azure assets. The inline IDS/IPS runs a standard inline Suricata/Snort rule engine which detects and prevents various attack signatures However, it is blind to most TLS traffic and therefore should be paired with an endpoint IDS/IPS as well. I recommend you deploy a similar capability . You wouldn’t want an insecure Azure server to use your cloud VPN to compromise your local network or an insecure local network IoT device to compromise your Azure network would you?
  • Also notice that direct internet access to the Azure Firewall is possible. All Azure firewalls come with a default “Public IP” and this option cannot be removed at the time of this writing. However, you can wrap NSG rules that block ingress into the Azure Firewall. To enable remote access directly via the Azure Firewall, the Azure Firewall or similar virtual appliances can be configured using DNAT and port forwarding to allow remote access that bypasses the site-to-site VPN. This is both a great break-glass access method and is also a backdoor and attack vector. If you plan on using this option, then lock down the Azure firewall rule to a source which only allows the specific source IP of your SNAT/Proxy public IP.

Deploying the NSGs

In this deployment, Network Security Groups are deployed and attached at the subnet level. A DenyAll is given higher priority by default and some limited RDP and ICMP traffic is allowed from JumpHost subnets for testing purposes.

However, with all traffic routing into the virtual firewall appliance you have multiple options for network segmentation. The NSG here are acting is a secondary line of defense in the event the firewall is incorrectly configured or the route tables are changed to bypass the appliance and simply route (east-west) between subnets within the same virtual network.

NSG rules from the Site-to-Site spoke to a specific jump host/ server group in the network hub

The above examples, explicitly deny all inbound traffic and then only allow RDP traffic at the moment from the VPN Gateway subnet pool. I’ve purposefully left the egress rules relaxed for intra- VNET (East-West )traffic but be aware the risks of data exfiltration and remote command and control scenarios. In this case, assuming the route tables work as expected, the virtual firewall will capture intra-VNET, internet bound and external VNET bound traffic and enforce a separate set of network packet or FQDN filtering rules.

#2 – Security Architecture Advice

  • Default Azure Network Security Groups (NSG) only block traffic from internet ingress and CIDRs outside your virtual network range but are completely open within the virtual network itself … which is important once your internal asset gets popped and lateral movement is possible because of ANY ANY between Azure VirtualNetworks in NSG…
  • Relying on DEFAULT NSG only 5-tuple egress rules would mean you isolate traffic based on Layer-3 which is Dangerous. IP addresses are ephemeral these days in the cloud and if someone de-provisions a public IP it may get re-allocated to someone else creating a “Hanging IP” that can be used in a MiTM attack. It’s better to use trusted and validated domains addresses and FQDNS whitelisting on egress
  • All custom NSGs provided in this deployment Deny ALL by default at a higher priority level and allow some ingress from the Jump subnets by default. The Azure provided DenAll is the lowest priority meaning all other policies are validated first, so I fix that problem and harden the ACLs. Knowing your ports and protocols is pretty straight forward using flowlog traffic, nsg logs and local nstat commands.

Deploying the HUB Network Topology

The sample deployment code can be found below. It may not be 100% updated and may require some manual changes on your part but it will save you some time and you can reverse engineer from there. Essentially, a HUB network is created and multiple other tenant VNETs are created with pairing to the HUB which create a transitive network integration where eventually the virtual firewall appliance will act as the centralized network security device.

A few pointers before you deploy the code ….

  • You’ll need to have previously created a management group and subscription to deploy into
  • You’ll require various network read and create permissions, a Network Admin Role and VM Admin should do, but you don’t need IAM, Billing etc. etc.
  • Create the ROUTES and NSGs first, otherwise the subnet references would fail
  • Finally, deploy the VNET templates

#3 – Security Architecture Advice

  • Default Azure Route tables have wide open default routes that allow egress to internet without any particular FQDN filtering
  • Azure Route tables can be set-up to “split-tunnel” traffic and bypass your virtual appliances in the hub and bypass any FQDN filtering you deploy…
  • Peering by default gets configured both-ways in Azure meaning you must rely on the virtual appliance or the NSG however you can’t limit routing with a one way peering even if you wanted to
  • The custom NSGs are tied to SUBNETs in this deployment but you do not need to isolate east-west traffic between assets this way. In fact, you can use “Application Security Groups” to bucket resources that share similar packet filtering needs which de-couples you from subnet issues and tracking CIDR ranges and running out of IP addresses etc. etc. It also makes other automated security solution such as automating packet filtering based on resource tags possible.

deploying the virtual firewall

The code below will configure and deploy a simple standalone Azure Network Virtual Appliances (NVAs in lab. You could just as well deploy any number of self-manged virtual appliances to act as a transitive virtual appliance between virtual networks.

However, you will likely have to spend more time managing multi-region, fault tolerance, disaster recovery and high availability hosting designs and patch management as oppose to Azure handling all that for you.

    "$schema": "",
    "contentVersion": "",
    "parameters": {
        "azureFirewalls_SandmanFirewall_name": {
            "defaultValue": "SandmanFirewall",
            "type": "String"
        "publicIPAddresses_pip_firewall_externalid": {
            "defaultValue": "/subscriptions/e0d889ac-ee90-47bc-8a23-e6895f056dfc/resourceGroups/hub-spoke/providers/Microsoft.Network/publicIPAddresses/pip-firewall",
            "type": "String"
        "virtualNetworks_vnet_hub_externalid": {
            "defaultValue": "/subscriptions/e0d889ac-ee90-47bc-8a23-e6895f056dfc/resourceGroups/hub-spoke/providers/Microsoft.Network/virtualNetworks/vnet-hub",
            "type": "String"
        "firewallPolicies_RemoteAccess_externalid": {
            "defaultValue": "/subscriptions/e0d889ac-ee90-47bc-8a23-e6895f056dfc/resourceGroups/hub-spoke/providers/Microsoft.Network/firewallPolicies/RemoteAccess",
            "type": "String"
    "variables": {},
    "resources": [
            "type": "Microsoft.Network/azureFirewalls",
            "apiVersion": "2020-11-01",
            "name": "[parameters('azureFirewalls_SandmanFirewall_name')]",
            "location": "centralus",
            "properties": {
                "sku": {
                    "name": "AZFW_VNet",
                    "tier": "Premium"
                "threatIntelMode": "Alert",
                "additionalProperties": {},
                "ipConfigurations": [
                        "name": "pip-firewall",
                        "properties": {
                            "publicIPAddress": {
                                "id": "[parameters('publicIPAddresses_pip_firewall_externalid')]"
                            "subnet": {
                                "id": "[concat(parameters('virtualNetworks_vnet_hub_externalid'), '/subnets/AzureFirewallSubnet')]"
                "networkRuleCollections": [],
                "applicationRuleCollections": [],
                "natRuleCollections": [],
                "firewallPolicy": {
                    "id": "[parameters('firewallPolicies_RemoteAccess_externalid')]"

High Availability

I learned Microsoft supports the following options for HA design of network virtual appliances. These options are important to me because they not only provide an opportunity for HA but also create opportunity to incorrectly route traffic, flatten networks and create security device bypasses.

  • Azure API-managed route tables – This option uses two route tables, one active, one passive to switch the active gateway IP for all services running on a VNet/subnet
  • Azure API-managed floating IP – This option uses a secondary IP address on the FWs that can be moved between an active and a stand-by FW
  • Load Balancer managed – This option uses an Azure Load Balancer to act as the gateway IP for the subnet, which then forwards the traffic to the active FW. It may even forward the traffic active-active to provide true load balancing


Moving onto routing the VPN traffic, user-defined route (UDR) in the VPN gateway subnet blocks all user requests other than those received from your office or on-premises site. The site-to-site VPN route passes allowed requests to the virtual firewall appliance, which are then sent on to the jump hosts if they are allowed by the firewall rules. You can add other routes, but make sure they don’t inadvertently bypass the firewall or block administrative traffic intended for the management subnet.

Routing inbound traffic from the internet to the FW is a bit different. Microsoft recommends adding a Destination Network Address Translation (DNAT) rule to Azure Firewall and connecting to the Azure default public IP. The public IP cannot be removed at the time of this writing.

  • Destination address = Public IP address of the firewall instance.
  • Translated address = Private IP address within the virtual network.

This access option is by Microsoft design to act as a single “converged” device which can isolate both internet traffic paths and private RFC1918 spaces. As a side note, the converged nature of the firewall may create an environment more susceptible to FW rule error and exposure of private systems to public internet. The Azure FW public IP will definitely create a design which relies on a source SNAT IP address, most likely an internet proxy, which will have a broad network egress from many proxy clients. Although the FW rule may read like a 1-to-1 mapping, the implication is more likely to create a bridge between on-premise client networks and the azure the cloud over the internet.

                "ruleCollections": [
                        "ruleCollectionType": "FirewallPolicyNatRuleCollection",
                        "action": {
                            "type": "Dnat"
                        "rules": [
                                "ruleType": "NatRule",
                                "name": "RDP",
                                "translatedAddress": "",
                                "translatedPort": "3389",
                                "ipProtocols": [
                                "sourceAddresses": [
                                    "<YOUR SNAT PUBLIC IP>"
                                "sourceIpGroups": [],
                                "destinationAddresses": [
                                    "<YOUR FW PUBLIC IP>"
                                "destinationPorts": [
                        "name": "DNATs",
                        "priority": 100

You could chose other alternatives, such as deploy two Azure firewall instances with limited communication between them for shared services or deploy a self-managed virtual firewall for RFC1918 traffic separation and the Azure firewall and update the routes between the two firewalls for shared services. Arguably, even with two firewall’s, most IT departments will need routing between the two systems to pull logs, push updates, perform security operations etc. etc which may create a overly complex and burdensome environment that diminishes security isolation as well. Pick your poison.

Internet Egress

By Default, all resources in a VNet can communicate outbound to the internet which can be seen in the default routes and the default NSGs below.

For internet egress, large companies may configure the alternative Force-tunnel all outbound internet traffic through your on-premises network using the site-to-site VPN tunnel, and route to the internet using on-premise network address translation (NAT). Force-tunnel may assist in preventing leakage of any information or command and control communications by allowing inspection and auditing of all outgoing traffic using legacy on-premise systems.

Alternatively, in the cloud you could just as well do a type of “split tunnel” and route cloud internet egress through a cloud hosted centralized proxy virtual appliance which performs FQDN whitelisting, reputation filtering etc. Azure FW can limit outbound HTTP/S traffic or Azure SQL traffic to a specified list of fully qualified domain names (FQDN) … including wild cards unfortunately. If you want to enable FQDN (fully qualified domain name) filtering in network rules, enable DNS proxy and update the virtual machine configuration to use the firewall as a DNS proxy.

D N S proxy configuration using a custom D N S server.

Another emerging concept is simplifying the firewall rule process using “labels” and “service categories” to group and enforce rules in a logical way instead of using IP addresses. For example, Azure service tags can be used to limit network access to only approved Azure API service infrastructure and FQDN tags can be used to allow well-known Azure service network traffic through your firewall. These options could help prevent overly broad “egress” or “ingress” to/from Azure cloud API service endpoints.

#4 – Security Architecture Advice

  • Azure Virtual Firewall comes with public IP by default. If internet ingress is is unacceptable consider implementing a DenyAll policy via NSG on the AzureFirewallSubnet or a deploying a self-managed centralized virtual firewall appliance within your RFC1918 or deploy a mesh-topology with a Deny Internet rule on a golden NSG/ASGs rule set and configuring azure policy enforcing no public IPs.
  • The High Availability design options require ephemeral IPs, ephemeral routes and Load Balancing which if configured can route traffic to alternative more permiscous virtual appliances or no appliances
  • DNAT over the Azure FW public IP is a great option when building from scratch or when building a lab but may also be a backdoor into your administrative network
  • TLS interception option and firewall packet capturing is a powerful tool which can be used to perform Man In the Middle traffic analysis against security threats but should be ran by your privacy team first to ensure you’re not capturing employee or customer PCI, HIPPA, SPI details
  • The cloud network has default egress to the internet on all servers but be configured to “force tunnel” back on-premise or “split tunnel” which may bypass traditional network security controls on-premise. If split-tunneling then using an FQDN and packet filtering on all internet egress is advised.

configuring the IPSEC Tunnel and DNS

To deploy a site-to site VPN in Azure, you configure a reserved GatewaySubnet, deploy a virtual network gateway (VNG) into the reserved subnet and lastly configure the connections details for the local network gateway (on-premise VPN device).

Azure supports one-to-one connections, one-to-many and many-to-many High Availability designs.

Set up and configure IPsec/IKE policies
Diagram shows a Dual Redundancy scenario.

For the initial handshake and cipher agreements, Azure VPN supports both IKEv1 (on all gateways except basic tier) and IKEVv2. As a refresher, because I needed it, here are the key differences between the v1 and v2 protocol versions.

By default, Azure provides a base IKE SA policy which is generally broad, less secure and interoperable but a custom policy should be created and assigned to your connections. Azure VPN gateways also support per-connection, custom IPsec/IKE policy. Custom IPsec/IKE policy is supported on all Azure SKUs except the Basic SKU. In addition, Azure VPN gateway also began supporting perfect forward secrecy.

The following table lists the supported cryptographic algorithms and key strengths configurable by the Azure customers. I’ve made a few of my preferred options bold if your on-premise VPN device supports them and your performance is not significantly degraded.

IKEv2 EncryptionAES256, AES192, AES128, DES3 (AVOID) , DES ((AVOID)
IKEv2 IntegritySHA384, SHA256, SHA1 (AVOID), MD5 (AVOID)
DH GroupDHGroup24, ECP384, ECP256, DHGroup14, DHGroup2048, DHGroup2 (AVOID), DHGroup1 (AVOID), None (AVOID)
IPsec EncryptionGCMAES256, GCMAES192, GCMAES128, AES256, AES192, AES128, DES3 (AVOID), DES (AVOID), None (AVOID)
IPsec IntegrityGCMAES256, GCMAES192, GCMAES128, SHA256, SHA1 (AVOID), MD5 (AVOID)
PFS GroupPFS24, ECP384, ECP256, PFS2048, PFS2, PFS1, None (AVOID)
QM SA Lifetime(Optional: default values are used if not specified)
Seconds (integer; min. 300/default 27000 seconds)
KBytes (integer; min. 1024/default 102400000 KBytes)
Traffic SelectorUsePolicyBasedTrafficSelectors** ($True/$False; Optional, default $False if not specified)

As a side note, IBM explicitly says not to trust the following DH modes when higher levels of assurance are required, so it seams reasonable to avoid them altogether if you can afford it.

  • Do not use Group 1 when the stack is configured for FIPS 140 mode
  • Do not use Group 2 when the stack is configured for FIPS 140 mode.
  • Do not use Group 5 when the stack is configured for FIPS 140 mode.

Don’t forget to configure your local on-premise lab VPN with similar parameters as above so the IKE handshake reaches agreement and establishes a connected tunnel. You will also be asked to use a PSK (pre-shared-key). Ensure you use a very long long randomly generated key. Finally, ensure the VPN GatewaySubnet route direct all on-premise traffic to the Azure Firewall virtual appliance.

BEWARE: There is a bug in the Azure template export that hard-codes the PSK in the JSON template ….

#5 – Security Architecture Advice

  • USE IKEv2
  • USE CUSTOM IKE policy
  • AVOID DH groups 1,2,5 if possible
  • AVOID DES and 3DES
  • Ensure the User Defined Routes (UDR) forward all VPN traffic to the firewall, otherwise you may increase your network attack surface in the virtual network

configuring dns on virtual network

This is a brief note on configuring DNS servers in the Azure virtual networks. At a later date, I’ll be doing this lab end-to-end with some Microsoft DNS services tied to AD. The important takeaway here is that Azure virtual network supports either azure provided or custom private DNS servers.

Notably, when virtual servers are started or deployed they get boost-strapped with these configurations. Making this an extremely powerful permissions which could lead to wide spread virtual machine DNS hijacking.

enforcing “internal” intranet zones

If you don’t want the “spoke virtual networks” to accidentally be deployed with Public IPs exposing them to internet ingress then you can harden the platform using azure policies. This is a setting I personally tested after getting the firewall and VPN set up, but ideally it would be better to have your hub and spoke topology over-layed with these hardening policies firstly.

In this example, I created a separate logical resource group (InternalOnlyTraffic) under a shared SecSandmanDemos subscription and applied the hardening network policy to InternalOnlyTraffic then moved the old VNET into the new resource group so the policy would cover the internal VNET.

However, you could equally isolate assets and apply policies by creating multiple subscriptions and peering VNETS between subscriptions. Both options still apply the policy and also allow you to centrally managed the VNET cloud assets using Azure AD group assignments. Please note that the policy assignment takes around 30 minutes to take effect.

Example Policy Code

  "properties": {
    "displayName": "Network interfaces should not have public IPs",
    "policyType": "BuiltIn",
    "mode": "Indexed",
    "description": "This policy denies the network interfaces which are configured with any public IP. Public IP addresses allow internet resources to communicate inbound to Azure resources, and Azure resources to communicate outbound to the internet. This should be reviewed by the network security team.",
    "metadata": {
      "version": "1.0.0",
      "category": "Network"
    "parameters": {},
    "policyRule": {
      "if": {
        "allOf": [
            "field": "type",
            "equals": "Microsoft.Network/networkInterfaces"
            "not": {
              "field": "Microsoft.Network/networkInterfaces/ipconfigurations[*]",
              "notLike": "*"
      "then": {
        "effect": "deny"
  "id": "/providers/Microsoft.Authorization/policyDefinitions/83a86a26-fd1f-447c-b59d-e51f44264114",
  "type": "Microsoft.Authorization/policyDefinitions",
  "name": "83a86a26-fd1f-447c-b59d-e51f44264114"

Policy mapped to a Subscription and Resource Group


Enabling Flow Logs

Network Security Flow Logs

Network Security Flows are similiar to NetFlow logs and collect all traffic go trough an NSG (regardless if it is allow or deny)

NSG Flow Logs Attribute

  • Time
  • Resourceid (NSG ID)
  • Flow
  • Rule ( NSG Regel)
  • Mac
  • FlowTuple
  • Timestamp
  • SourceIP
  • DestinationIP
  • SourcePort
  • DestinationPort
  • Protocol
  • TrafficFlow (Inboudn or Outbound)
  • Traffic Decision (Allow or Denied)
  • Flow State ( C eller E)

NSG Flow logs can then be enhanced with Traffic Analysis which ingest data from NSG Flow logs which are stored on Storage Accounts, then into Log Analytics and then enriched with more data points.
Some metadata the Traffic Analysis adds to the data that it collects from the NSG Flow Logs.

1: Flow Type
2: Country
3: Use of Azure PaaS services
4: Azure Region
5: Malicious Flow

NOTE: Malicious Flow can be seen in Log Analytics using this query.

| where SubType_s == 'FlowLog' and FlowType_s == 'MaliciousFlow' and (FASchemaVersion_s == '1' or FASchemaVersion_s == '2') 
| where AllowedInFlows_d > 0
| project FlowDirection_s, FlowType_s, FlowCount = max_of(AllowedInFlows_d + DeniedInFlows_d, AllowedOutFlows_d + DeniedOutFlows_d), AllowedInFlows_d, DeniedInFlows_d, AllowedOutFlows_d, DeniedOutFlows_d, InboundBytes_d, OutboundBytes_d, InboundPackets_d, OutboundPackets_d, SrcIP_s, DestIP_s, L4Protocol_s, L7Protocol_s, DestPort_d, NIC1_s, NIC2_s, VM1_s, VM2_s, Subnet1_s, Subnet2_s, Country_s, Region1_s, Region2_s, Subscription1_g, Subscription2_g, NSGRule_s, NSGList_s, TimeGenerated, TimeProcessed_

detecting events and auto responses

As I stumbled through setting up this lab, I’ve mentioned a few cloud configurations and changes that could indicate someone with bad intentions creating a backdoor or even establishing persistence. Or maybe just an employee making a legitimate mistake that’s dangerous.

The following examples are just some very simple down and dirty ways to monitor for those changes manually or automated using Azure native features and APIs but you could also use an expensive cyber security tool or develop more customized server-less monitoring functions based on activity log events.


#1 – Automated Alerts when Network Peering Events Occur

#2 – Automated Alerts when Route Table Events Occur

#3 – Create, Update or Changes to Azure FW manager policies

#4 – Create, Update or Changes Network gateways (VPN gateways)


#5 – Performing MiTM attack on your virtual networks


The Get-AzRouteTable cmdlet gets Azure route tables. You can get a single route table, or get all the route tables in a resource group or in your subscription.

   [-ResourceGroupName <String>]
   [-Name <String>]
   [-DefaultProfile <IAzureContextContainer>]

The Get-AzVirtualNetworkPeering cmdlet gets the virtual network peering.


   -VirtualNetworkName <String>
   -ResourceGroupName <String>
   [-Name <String>]
   [-DefaultProfile <IAzureContextContainer>]

Get Configs on the Firewall Manager


That’s it, one lab led to another lab and I built and learned a bunch along the way. Hopefully some of these notes help anyone else crazy enough to spend the time to read them.

Next time, I’ll redeploy this environment as-code and pen test some of IDS/IPS security controls on my internal network and on the Azure Firewall.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s