More than one year ago I had written a blog post about Setting up a DMZ in Azure.
At that time Azure networking did not have features necessary to implement a DMZ.
At Tech Ed Barcelona there were many significant announcements related to Azure networking.
You can read a summary of all the announcements made at Tech Ed Barcelona here:
Networking improvements that were announced at Tech Ed were:
- Network Security Groups: This is a key feature that allows you to create access control roles at VM or subnet level. You can control these rules independent of the life cycle of the VM. Before Network Security Groups were available the only option to restrict access to virtual machines inside of a virtual network was with Access Control Lists that were applied at individual virtual machine end points.
- Multi NIC Support: This is another feature that is required by most network appliance. Now you can have up to 4 NIC’s in a virtual machine based on the size of the virtual machine. This is will allow many partners to deploy their virtual network appliance on Azure platform.
- Forced Tunneling: This is a requirement for many enterprise grade applications. This feature allows you to force internet bound traffic from your cloud application running in a Azure virtual network to on premises network via site to site VPN. This allows your security team to inspect this traffic.
- Express Route Enhancements: This will allow 1 express route connection to be shared among multiple Azure subscriptions. One Site to Site VPN can also connect with multiple Express route circuits.
I will now attempt to create a DMZ in Azure virtual network. I will be able to leverage many of the improvements made to Azure networking stack with in the last 15 months since I wrote the original blog post about creating a DMZ.
On Premise Application
Here is a typical application running on premises. It has a web front end with 2 web servers. It has an application server tier with 2 application servers. It also has a highly available database tier. The two web servers are in DMZ. All the inbound HTTP/HTTPS traffic can only come to the Port 80/443 of the Web Servers. The application servers are in a App VLAN and they only accept traffic from Web Servers. Database Servers are in DB VLAN and it only accepts traffic from the servers in App VLAN.
Azure Application
Here we will attempt to implement the application application in Microsoft Azure Platform.
We will create an Azure virtual network. It will have 3 subnets.
WebSubnet will have two web server virtual machines. All the requests coming to the web servers will be load balanced by Azure public load balancer.
AppSubnet will have two application servers. All the requests coming to application servers will be load balanced by Azure internal load balancer. This load balancer is only accessible to the virtual machines in the virtual network. AppSubnet is secured with a Network security group which only allows requests from WebSubnet.
DBSubnet will have two database servers. All the requests coming to the database servers will be received by Azure internal load balancer. This is used to configure always on configuration of SQL Server 2012 or higher versions.
We will use Azure Management Portal and PowerShell to create this environment.
1. Create Azure Virtual network.
Log into Azure management portal at http://manage.windowsazure.com
Create New Virtual Network as shown below.
This will open a wizard. On page 1 of the wizard you will enter the virtual network name and location and press next
On this page we will typically enter DNS Server and VPN connectivity information. Active Directory and DNS Server is required by virtual machines running in a Virtual Network. However in our scenario we will skip this step. Press next arrow.
On this page we need to define Virtual network address space.
You need to carefully plan the virtual network address space. It should be appropriately sized.
In the example below we have a virtual network address space of 192.168.0.0/24.
We defined 3 subnet:
WebSubnet will contain the web servers
AppSubnet will contain the application servers
DBSubnet will contain the database sergvers
You can use the Export command in the Azure management portal to export the configuration of all virtual networks in your subscription. Here is how the XML configuration for the above virtual network looks.
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 |
<NetworkConfiguration xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration”>
<VirtualNetworkConfiguration> <Dns /> <VirtualNetworkSites> <VirtualNetworkSite name=”TypicalAppVnet” Location=”Central US”> <AddressSpace> <AddressPrefix>192.168.0.0/24</AddressPrefix> </AddressSpace> <Subnets> <Subnet name=”WebSubnet”> <AddressPrefix>192.168.0.0/28</AddressPrefix> </Subnet> <Subnet name=”AppSubnet”> <AddressPrefix>192.168.0.16/28</AddressPrefix> </Subnet> <Subnet name=”DBSubnet”> <AddressPrefix>192.168.0.32/27</AddressPrefix> </Subnet> </Subnets> </VirtualNetworkSite> </VirtualNetworkSites> </VirtualNetworkConfiguration> </NetworkConfiguration> |
Creating Virtual Machines
It is assumed that you already created a storage account and set the current storage account using Set-AzureSubscription PowerShell cmdlet.
Web Servers
Web Servers are created in WebSubnet. They are capable of receiving requests from public so they have a public load balanced end point.
Web server 1 will be assigned an IP address of 192.168.0.4
Web server 2 will be assigned an IP address of 192.168.0.5
You can use the following PowerShell script to create these web servers in WebSubnet
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 |
#Configure the virtual machines to be created
$vm11 = New-AzureVMConfig -Name $WebServer1 -InstanceSize $InstanceSize -ImageName $image.ImageName -AvailabilitySetName $WebAvailabilitySetName | ` Set-AzureSubnet $WebSubnet | ` Add-AzureEndpoint -Name “HttpIn” -Protocol “tcp” -PublicPort 80 -LocalPort 8080 -LBSetName “WebFarm” -ProbePort 80 -ProbeProtocol “http” -ProbePath ‘/’ | ` Add-AzureProvisioningConfig -Windows -AdminUsername $credential.GetNetworkCredential().username -Password $credential.GetNetworkCredential().password $vm12 = New-AzureVMConfig -Name $WebServer2 -InstanceSize $InstanceSize -ImageName $image.ImageName -AvailabilitySetName $WebAvailabilitySetName | ` Set-AzureSubnet $WebSubnet | ` Add-AzureEndpoint -Name “HttpIn” -Protocol “tcp” -PublicPort 80 -LocalPort 8080 -LBSetName “WebFarm” -ProbePort 80 -ProbeProtocol “http” -ProbePath ‘/’ | ` Add-AzureProvisioningConfig -Windows -AdminUsername $credential.GetNetworkCredential().username -Password $credential.GetNetworkCredential().password # Make an array of the virtual machine configuration so we can create them with 1 call $vms = @($vm11, $vm12) #check to see if the cloud service for these virtual machines already exists |
Once the web servers have been created you need to log into these servers, configure IIS and update the firewall rules to allow traffic over port 80.
You can use the following PowerShell script to create the application servers in AppSubnet. Application servers are load balanced using internal load balancer. So the only server in the same virtual network can send requests to the load balanced end point for applications servers.
Application server 1 will be assigned IP address of 192.168.0.20
Application server 2 will be assigned IP address of 192.168.0.22
Azure Internal Load Balancer will be assigned an IP address of 192.168.0.21
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 |
#create the two application servers with Internal Load balancer
#Configure the virtual machines to be created $vm11 = New-AzureVMConfig -Name $AppServer1 -InstanceSize $InstanceSize -ImageName $image.ImageName -AvailabilitySetName $AppAvailabilitySetName | ` Set-AzureSubnet $AppSubnet | ` Add-AzureProvisioningConfig -Windows -AdminUsername $credential.GetNetworkCredential().username -Password $credential.GetNetworkCredential().password $vm12 = New-AzureVMConfig -Name $AppServer2 -InstanceSize $InstanceSize -ImageName $image.ImageName -AvailabilitySetName $AppAvailabilitySetName| ` Set-AzureSubnet $AppSubnet | ` Add-AzureProvisioningConfig -Windows -AdminUsername $credential.GetNetworkCredential().username -Password $credential.GetNetworkCredential().password # Make an array of the virtual machine configuration so we can create them with 1 call $vms = @($vm11, $vm12) #check to see if the cloud service for these virtual machines already exists # Add Internal Load Balancer to the service if (!($?)) # Add load balanced endpoints to ILB if (!($?)) Get-AzureVM -ServiceName $AppServiceName -Name $AppServer2 | Add-AzureEndpoint -Name “intappep” -LBSetName “intappeplb” -Protocol tcp -LocalPort 80 -PublicPort 80 -ProbePort 80 -ProbeProtocol tcp -ProbeIntervalInSeconds 10 -InternalLoadBalancerName AppILB | Update-AzureVM if (!($?)) |
Once the application servers have been created you need to log into these servers, configure IIS and update the firewall rules to allow traffic over port 80.
You can use the following PowerShell script to create the database servers in DBSubnet. In real world scenario I would have used SQL Server Always on and internal load balancer but in this example I just create 2 VM’s from the Microsoft supplied SQL Server 2014 image.
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 |
############################ Provision SQL VM’s ##########################################################
$vm11 = New-AzureVMConfig -Name $DBServer1 -InstanceSize $InstanceSize -ImageName $sqlimage -AvailabilitySetName $DBAvailabilitySetName | ` Set-AzureSubnet $DBSubnet | ` Add-AzureProvisioningConfig -Windows -AdminUsername $credential.GetNetworkCredential().username -Password $credential.GetNetworkCredential().password $vm12 = New-AzureVMConfig -Name $DBServer2 -InstanceSize $InstanceSize -ImageName $sqlimage -AvailabilitySetName $DBAvailabilitySetName | ` Set-AzureSubnet $DBSubnet | ` Add-AzureProvisioningConfig -Windows -AdminUsername $credential.GetNetworkCredential().username -Password $credential.GetNetworkCredential().password # Make an array of the virtual machine configuration so we can create them with 1 call $vms = @($vm11, $vm12) #check to see if the cloud service for these virtual machines already exists |
Database Server 1 will be assigned an IP address of 192.168.0.36
Database Server 2 will be assigned an IP address of 192.168.0.37
Even though these virtual machines are created in different subnets there is nothing preventing these VM’s from communicating with each other. Database Servers are running SQL Server you need to open the open the port 1433 on the firewall to allow inbound connections.
Log into your web server and application server and install Telnet client on web and application servers using Server Manager –> Add Roles and Features->Telnet Client to test the connectivity between web/application and database servers.
From command windows run the command
telnet 192.168.0.36 1433
Here 192.168.0.36 is the internal IP address of the SQL Server VM where I had opened the firewall rule to allow inbound 1433 TCP connections. If the connection is successful you will see the cursor move to the top left corner of the command windows. If your connection fails you will get an error.
You will see that you can connect to the database server from both web server and application servers. If you want to only allow application servers to connect to database servers you have a few options:
1. You can use host firewall to only allow connections from application servers
2. You can use Azure Access Control Lists and only allow connections from application servers
3. You can use Network security groups at the VM level to only allow connections from application servers
4. You can use Network security groups at the subnet level to only allow connections from servers in the AppSubnet.
I prefer option 4 for ease of management. It is cumbersome to apply ACLs and Network Security groups at the VM level. If you create Network Security groups at the subnet level any new virtual machines will automatically inherit the security groups.
Network Security Groups
Here are the default inbound and outbound rules in an Network Security Group.
Default Inbound Rules
Name | Priority | Source IP | Source Port | Destination IP | Destination Port | Protocol | Access |
ALLOW VNET INBOUND | 65000 | VIRTUAL_NETWORK | * | VIRTUAL_NETWORK | * | * | ALLOW |
ALLOW AZURE LOAD BALANCER INBOUND | 65001 | AZURE_LOADBALANCER | * | * | * | * | ALLOW |
DENY ALL INBOUND | 65500 | * | * | * | * | * | DENY |
Default Outbound Rules
Name |
Priority |
Source IP |
Source Port |
Destination IP |
Destination Port |
Protocol |
Access |
ALLOW VNET OUTBOUND |
65000 |
VIRTUAL_NETWORK |
* |
VIRTUAL_NETWORK |
* |
* |
ALLOW |
ALLOW INTERNET OUTBOUND |
65001 |
* |
* |
INTERNET |
* |
* |
ALLOW |
DENY ALL OUTBOUND |
65500 |
* |
* |
* |
* |
* |
DENY |
To protect the servers in DBSubnet you need to create these rules to only servers in the AppSubnet to communicate with DBSubnet over port 1433.
Name |
Priority |
Source IP |
Source Port |
Destination IP |
Destination Port |
Protocol |
Access |
DBDENY |
100 |
192.168.0.0/28 |
* |
192.168.0.32/27 |
* |
TCP |
DENY |
DBALLOW |
101 |
192.168.0.16/28 |
* |
192.168.0.32/27 |
1433 |
TCP |
ALLOW |
RDPALLOW |
65500 |
INTERNET |
* |
192.168.0.32/27 |
3389 |
TCP |
DENY |
To protect the servers in AppSubnet you need to create these rules to only allow servers in WebSubnet to send requests to the AppSubnet.
Name |
Priority |
Source IP |
Source Port |
Destination IP |
Destination Port |
Protocol |
Access |
APPDENY |
100 |
192.168.0.32/27 |
* |
192.168.0.16/28 |
* |
TCP |
DENY |
RDPALLOW |
101 |
INTERNET |
* |
192.168.0.16/28 |
3389 |
TCP |
ALLOW |
WEBALLOW |
102 |
192.168.0.0/28 |
* |
192.168.0.16/28 |
80 |
TCP |
ALLOW |
The following script creates network security groups and assigns them to DBSubnet and AppSubnet. It implements the rules shown in the tables above.
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 |
#Only allow traffic from AppSubnet to come to DBSubnet
#Create a Network Security Group New-AzureNetworkSecurityGroup -Name “DBSG” -Location $DataCenter -Label “Security group for DBSubnet in virtual network $VNetSiteName in Central US” #Add a rule to deny WebSubnet access to DBSubnet #Only allow traffic from WebSubnet to come to AppSubnet |
Once you have applied Network Security Groups you will be unable to RDP to the virtual machine because default Network Security Groups do not allow traffic from the internet. I created rules to allow RDP into AppSubnet and DBSubnet.
RDP into a web server and try to access IIS over an internal ILB address 192.168.1.21 and you will see the default IIS web page.
Test connectivity from web server to a DBServer using telnet IP_Address 1433 and the connection will fail because DBSubnet only allows traffic from AppSubnet.
Log into an Application Server VM and test connectivity to DB Server using telnet IP_Address 1433 and you will be able to successfully connect.
In this blog post you have seen how you can leverage features like Azure virtual network, public and internal load balancer and network security groups to securely deploy an on premise application to Azure platform. Network security groups can control both inbound and outbound traffic at VM or subnet level. You can have up to 200 rules in a Network Security Group. You cannot apply both an Access Control List(ACL) and Network Security Group(NSG) to the same virtual machine. A virtual machine/subnet can be only be controlled by 1 Network Security Group. Priority of NSG starts at 100 which is the lowest priority. Rules with the lower priority get executed first.
References
http://azure.microsoft.com/blog/2014/11/04/network-security-groups/
http://msdn.microsoft.com/en-us/library/azure/dn848316.aspx
http://msdn.microsoft.com/en-us/library/azure/dn655058.aspx
http://azure.microsoft.com/blog/2014/05/20/internal-load-balancing/
http://msdn.microsoft.com/en-us/library/azure/dn690121.aspx
The post Creating DMZ in Azure Part II appeared first on Raj's Cloud Musings.