By this time you probably heard that Azure Firewall Premium is now GA which is a tremendous achievement to help customers secure their Azure workloads using native cloud security with advanced security features like TLS inspection, advanced threat protection with IDPS and URL/Web filtering

Following up with my previous article about deploying and managing an Azure WAF with Terraform and Azure DevOps, I am writing now about Azure Firewall Premium and how to manage it similarly. You can clone the code from my github repository

Terraform has a module to manage Azure Firewall and this time we will need to use firewall policy and firewall module with the SKU set to ‘Premium‘. Using Terraform and Azure DevOps you have a tool to do CI/CD and manage your firewall policies directly from pipelines. The rule collection groups are created under a specific module called ‘firewall policy rule collection group’.

Any new change you make to your Terraform code will trigger CI/CD within Azure DevOps. This is how the initial roll out of the Firewall Policies looks like in Azure DevOps. In my case I use Visual Studio code and those changes can be staged/committed and then push to your github repository:

We start by creating the Firewall Policy resource with SKU set to Premium and DNS Proxy enabled

resource "azurerm_firewall_policy" "fwpolicy" {
  name                = "fwpolicy"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  sku                 = "Premium"

  dns {
      proxy_enabled = "true"

  }
}

My NAT collection rules will allow RDP traffic to a virtual machine created in the file createVM.tf and port 80 traffic to go the OWASP JuiceShop WebApp fronted by the Application Gateway

You could send malicious traffic against the Public IP address assigned to the Firewall, which is used for DNAT to access the JuiceShop and after enabling IDPS feature in the Firewall Policy you could see the list of SignatureIDs detected

resource "azurerm_firewall_policy_rule_collection_group" "example" {
  name               = "example-fwpolicy-rcg"
  firewall_policy_id = azurerm_firewall_policy.fwpolicy.id
  priority           = 500
  application_rule_collection {
    name     = "app_rule_collection1"
    priority = 500
    action   = "Allow"
    rule {
      name = "app_rule_collection1_rule1"
      protocols {
        type = "Http"
        port = 80
      }
      protocols {
        type = "Https"
        port = 443
      }
      source_addresses  = ["*"]
      destination_fqdns = ["*"]
    }
  }

  network_rule_collection {
    name     = "network_rule_collection1"
    priority = 400
    action   = "Allow"
    rule {
      name                  = "network_rule_collection1_rule1"
      protocols             = ["Any"]
      source_addresses      = ["*"]
      destination_addresses = ["*"]
      destination_ports     = ["*"]
    }
  }
//RULE COLLECTION
  nat_rule_collection {
    name     = "nat_rule_collection1"
    priority = 300
    action   = "Dnat"
    rule {
      name                = "nat_rule_collection1_rule1"
      protocols           = ["TCP"]
      source_addresses    = ["*"]
      destination_address = azurerm_public_ip.fwpip.ip_address
      destination_ports   = ["80"]
      translated_address = azurerm_public_ip.example.ip_address
      translated_port     = "80"
    }
    rule {
      name                = "nat_rule_collection1_rule2"
      protocols           = ["TCP"]
      source_addresses    = ["*"]
      destination_address = azurerm_public_ip.fwpip.ip_address
      destination_ports   = ["3389"]
      translated_address = azurerm_windows_virtual_machine.example.private_ip_address
      translated_port     = "3389"
    }    
  }
}

Then we create the Firewall resource with Premium SKU

resource "azurerm_firewall" "firewall" { 
  name                = "firewall"
  sku_tier            = "Premium"
  firewall_policy_id  = azurerm_firewall_policy.fwpolicy.id
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  ip_configuration {
    name                 = "configuration"
    subnet_id            = azurerm_subnet.fwsubnet.id
    public_ip_address_id = azurerm_public_ip.fwpip.id
  }
}

There is a new terraform file which creates the firewall resources createFirewall.tf

In addition, I created a new terraform file to create a WebApp that has private endpoint and private link enabled. The idea is to use the virtual machine to access the WebApp through the private link and private endpoint. You can test how public access to the private webapp is disabled

createPrivateWebApp.tf

Your Firewall rule collection group will look like this:

and your DNAT rules:

If you browse using the Destination address on the DNAT rule you will access the JuiceShop webapp

Also, its great to have a view of your Azure Firewall Policies from Azure Security Center, so you can manage associations and policies from a global security tool like ASC

Categories: Uncategorized

0 Comments

Leave a Reply

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