Creating DMZ in Azure Part II

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:

https://weblogs.asp.net/scottgu/azure-new-marketplace-network-improvements-new-batch-service-automation-service-more

 

Networking improvements that were announced at Tech Ed were:

  1. 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.
  2. 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.
  3. 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.
  4. 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.

 

 

typical app

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.

image

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.

createvnet

This will open a wizard. On page 1 of the wizard you will enter the virtual network name and location and press next

vnetdetail-1

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.

vnetdetail-2

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

image

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
$service = Get-AzureService -ServiceName $WebServiceName -ErrorAction SilentlyContinue            
    
if ($service -eq $null) 
{ 
    # Create a new cloud service and Deploy Virtual Machines to Virtual Network
    New-AzureVM -ServiceName $WebServiceName -Location $DataCenter -VMs $vms -VNetName $VNetSiteName -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null
} 
else 
{ 
    #Deploy Virtual Machines to Virtual Network
    New-AzureVM -ServiceName $WebServiceName -VMs $vms -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null
} 
 
if (!($?)) 
{ 
    throw “Unable to create virtual machines $WebServer1 and $WebServer2. Error detail is: $errorVariable” 
} 
else
{
    Write-Verbose “Successfully created virtual machines $WebServer1 and $WebServer2” 
}

 

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
$service = Get-AzureService -ServiceName $AppServiceName -ErrorAction SilentlyContinue            
    
if ($service -eq $null) 
{ 
    # Create a new cloud service and Deploy Virtual Machines to Virtual Network
    New-AzureVM -ServiceName $AppServiceName -Location $DataCenter -VMs $vms -VNetName $VNetSiteName -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null
} 
else 
{ 
    #Deploy Virtual Machines to Virtual Network
    New-AzureVM -ServiceName $AppServiceName -VMs $vms -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null
} 
 
if (!($?)) 
{ 
    throw “Unable to create virtual machines $AppServer1 and $AppServer2. Error detail is: $errorVariable” 
} 
else
{
    Write-Verbose “Successfully created virtual machines $AppServer1 and $AppServer2” 
}

# Add Internal Load Balancer to the service
Add-AzureInternalLoadBalancer -InternalLoadBalancerName AppILB -SubnetName AppSubnet -ServiceName $AppServiceName -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null

if (!($?)) 
{ 
    throw “Unable to create internal load balancer on Service Name $AppServiceName. Error detail is: $errorVariable” 
} 
else
{
    Write-Verbose “Successfully created internal load balancer on Service Name $AppServiceName” 
}

# Add load balanced endpoints to ILB
Get-AzureVM -ServiceName $AppServiceName -Name $AppServer1 | Add-AzureEndpoint -Name “intappep” -LBSetName “intappeplb” -Protocol tcp -LocalPort 80 -PublicPort 80 -ProbePort 80 -ProbeProtocol tcp -ProbeIntervalInSeconds 10 -InternalLoadBalancerName AppILB | Update-AzureVM

if (!($?)) 
{ 
    throw “Unable to add internal load balanced endpoint to $AppServiceName and VM: $AppServer1.” 
} 
else
{
    Write-Verbose “Successfully added internal load balanced endpoint to $AppServiceName and VM: $AppServer1.” 
}

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 (!($?)) 
{ 
    throw “Unable to add internal load balanced endpoint to $AppServiceName and VM: $AppServer2.” 
} 
else
{
    Write-Verbose “Successfully added internal load balanced endpoint to $AppServiceName and VM: $AppServer2.” 
}

 

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
$service = Get-AzureService -ServiceName $DBServiceName -ErrorAction SilentlyContinue            
    
if ($service -eq $null) 
{ 
    # Create a new cloud service and Deploy Virtual Machines to Virtual Network
    New-AzureVM -ServiceName $DBServiceName -Location $DataCenter -VMs $vms -VNetName $VNetSiteName -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null
} 
else 
{ 
    #Deploy Virtual Machines to Virtual Network
    New-AzureVM -ServiceName $DBServiceName -VMs $vms -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null
} 
 
if (!($?)) 
{ 
    throw “Unable to create virtual machines $DBServer1 and $DBServer2. Error detail is: $errorVariable” 
} 
else
{
    Write-Verbose “Successfully created virtual machines $DBServer1 and $DBServer2” 
}

 

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
Get-AzureNetworkSecurityGroup -Name “DBSG” | Set-AzureNetworkSecurityRule -Name DBDENY -Type Inbound -Priority 100 -Action Deny -SourceAddressPrefix ‘192.168.0.0/28’  -SourcePortRange ‘*’ -DestinationAddressPrefix ‘192.168.0.32/27’ -DestinationPortRange ‘*’ -Protocol TCP
#Add a rule to allow AppSubnet to the DBSubnet
Get-AzureNetworkSecurityGroup -Name “DBSG” | Set-AzureNetworkSecurityRule -Name DBALLOW -Type Inbound -Priority 101 -Action Allow -SourceAddressPrefix ‘192.168.0.16/28’  -SourcePortRange ‘*’ -DestinationAddressPrefix ‘192.168.0.32/27’ -DestinationPortRange ‘1433’ -Protocol TCP
#Add a rule to allow RDP Connections into the DBSubnet. Only do this if you want to allow RDP connections from internet
Get-AzureNetworkSecurityGroup -Name “DBSG” | Set-AzureNetworkSecurityRule -Name RDPALLOW -Type Inbound -Priority 102 -Action Allow -SourceAddressPrefix ‘INTERNET’  -SourcePortRange ‘*’ -DestinationAddressPrefix ‘192.168.0.32/27’ -DestinationPortRange ‘3389’ -Protocol TCP
#Assign the network security group DBSubnet
Get-AzureNetworkSecurityGroup -Name “DBSG” | Set-AzureNetworkSecurityGroupToSubnet -VirtualNetworkName $VNetSiteName -SubnetName $DBSubnet

#Only allow traffic from WebSubnet to come to AppSubnet
#Create a Network Security Group
New-AzureNetworkSecurityGroup -Name “APPSG” -Location $DataCenter -Label “Security group for APPSubnet in virtual network $VNetSiteName in Central US”
#Add a rule to deny DBSubnet access to AppSubnet
Get-AzureNetworkSecurityGroup -Name “APPSG” | Set-AzureNetworkSecurityRule -Name APPDENY -Type Inbound -Priority 102 -Action Deny -SourceAddressPrefix ‘192.168.0.32/27’  -SourcePortRange ‘*’ -DestinationAddressPrefix ‘192.168.0.16/28’ -DestinationPortRange ‘*’ -Protocol TCP
#Add a rule to allow WebSubnet access to AppSubnet
Get-AzureNetworkSecurityGroup -Name “APPSG” | Set-AzureNetworkSecurityRule -Name APPALLOW -Type Inbound -Priority 103 -Action Allow -SourceAddressPrefix ‘192.168.0.0/28’  -SourcePortRange ‘*’ -DestinationAddressPrefix ‘192.168.0.16/28’ -DestinationPortRange ’80’ -Protocol TCP
#Add a rule to allow RDP from internet to AppSubnet. Only do this if you want to allow RDP connections from internet
Get-AzureNetworkSecurityGroup -Name “APPSG” | Set-AzureNetworkSecurityRule -Name RDPALLOW -Type Inbound -Priority 103 -Action Allow -SourceAddressPrefix ‘INTERNET’  -SourcePortRange ‘*’ -DestinationAddressPrefix ‘192.168.0.16/28’ -DestinationPortRange ‘3389’ -Protocol TCP
#Assign the network security group AppSubnet
Get-AzureNetworkSecurityGroup -Name “APPSG” | Set-AzureNetworkSecurityGroupToSubnet -VirtualNetworkName $VNetSiteName -SubnetName $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

Posted in DevOps, Virtual Machines, Virtual Networks | Tagged , | 1 Comment

Azure Cross platform Command Line Tools on Mac OSX

Windows Azure cross platform command line tools are a great way to manage your Azure infrastructure. These tools were developed in Node.JS. These tools can be used on Windows, MAC and Linux. However primary audience for these is MAC and Linux. Most Windows users will be better off leveraging Windows Azure Powershell cmdlets.

I want to show you how simple it is to setup these tools on MAC OSX.

From the terminal window you first install brew as shown in step 1 below. You can learn more about brew here http://brew.sh/

Steps 2 and 3 update brew and verify the installation

Step 4 install node which is required for Azure tools

Step 5 installs Azure cross platform command line tools

Step 6 verifies the install of the tools and returns version 0.7.4 or higher

   1: ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"

   2: brew update

   3: brew doctor

   4: brew install node

   5: npm install -g azure-cli

   6: azure -v

 

You can use azure –h to get help on all the commands that are available.

Authenticate using Certificate

The development machine will use a certificate (self-signed) to authenticate against Windows Azure Management services.

   1: $ azure account download

   2: info:    Executing command account download

   3: info:    Launching browser to http://go.microsoft.com/fwlink/?LinkId=254432

   4: help:    Save the downloaded file, then execute the command

   5: help:      account import <;file>

   6: info:    account download command OK

 

Copy the URL in line 3 above and paste it into browser. This will allow you to download the publishsettings file.

   1: azure account import <Path to publishsettings file>

If the import is successful you will be able to view output for the following command.

It should show you your subscription name, subscription id and current status.

   1: azure account list

You can learn more about these tools here:

http://www.windowsazure.com/en-us/documentation/articles/command-line-tools/

The source code of cross platform is open source. You can join the community here.

https://github.com/WindowsAzure/azure-sdk-tools-xplat

Posted in Linux, Open Source, Windows Azure | Leave a comment

Installing Gnome desktop on CentOS running in Windows Azure VM

I recently tried to setup Gnome Desktop on CentOS 6.3 running in a Windows Azure virtual machine. It turned out to be a bit harder than expected so I thought I will document this for other who may attempt to do this in future.

Preconditions

You have access to Windows Azure and have already created a Linux virtual machine with CentOS 6.3 Image provided in the image gallery. You also need to have root access to the virtual machine.

Install Gnome Desktop

Every Linux VM has WALinuxAgent Package. Gnome desktop has a dependency NetworkManager package which conflicts with WALinuxAgent package. Before installing Gnome desktop you can disable NetworkManager with these steps.

Edit /etc/yum.conf and add the following line to the end of the file:

Installing xrdp

   1: exclude=NetworkManager*

   2: sudo yum clean all 

   3: sudo yum groupinstall basic-desktop desktop-platform x11 fonts 

xrdp was not available on CentOS so you can use the following steps to download it. 

   1: su root 

   2: rpm -Uvh http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm 

   3:  

   4: sudo rpm -Uvh http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el6.rf.x86_64.rpm 

   5:  

   6: sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm 

   7:  

   8: sudo yum -y update 

   9: sudo yum repolist 

 

Install xrdp, tigervnc-server

   1: sudo yum install -y xrdp tigervnc-server autoconf automake libtool 

   2: openssl-devel pam-devel libX11-devel libXfixes-devel 

Download the latest xrdp to update it

   1: wget http://sourceforge.net/projects/xrdp/files/latest/download?source=files 

   2:  

   3: tar -zxf xrdp-v0.6.0.tar.gz 

   4: mv xrdp-v0.6.0 /usr/xrdp-v0.6.0 

   5: sudo mv xrdp-v0.6.0 /usr/xrdp-v0.6.0 

   6: sudo cd /usr/xrdp-v0.6.0/ 

   7: cd /usr 

   8: cd xrdp-v0.6.0/ 

   9: ./bootstrap 

  10: ./configure 

  11: make 

  12: make install 

  13: sudo make 

  14: sudo make install 

Setup user groups

   1: groupadd tsusers 

   2: sudo groupadd tsusers 

   3: sudo groupadd tsadmins 

   4: sudo nano -w /etc/group 

Edit the following lines to look like this.

   1: tsusers:x:501:YOURUSERNAME 

   2: tsadmins:x:502:root 

Now to setup VNC Password for the user that you want to use XRDP Services

   1: su YOURUSERNAME 

   2: vncpasswd 

 

Edit VNC Server configuration

   1: sudo nano -w /etc/sysconfig/vncservers 

   2: #Insert at the end of file 

   3: VNCSERVERS="1:YOURUSERNAME" 

   4: VNCSERVERARGS[1]="-geometry 1024x768 -depth 16" 

 

Update rc.local file so vncserver starts even after reboots

   1: sudo nano -w /etc/rc.local 

   2: #Add the following to the end of the file 

   3: /etc/xrdp/xrdp.sh start 

 

Start the services

   1: sudo chkconfig vncserver on 

   2: sudo service vncserver on 

   3: sudo service vncserver start 

   4: sudo /etc/xrdp/xrdp.sh start 

 

Create Remote Desktop Endpoint allow RDP connection to the virtual machine 

You can either use Azure command line tools and run this command line tools

azure vm endpoint create mylinuxtemplate 3389 3389

 

You can also use the Windows Azure Portal.

Select the virtual machine and navigate the “endpoints” tab.

Select “Add” button from the bottom tool bar and select Port 3389 as internal and external port.

Use the connect button from the bottom toolbar in the portal to connect to Gnome desktop

 

References

I couldn’t have done this setup without these blog posts.

    http://channel9.msdn.com/Series/Windows-Azure-Virtual-Machines-and-Networking-Tutorials/Running-a-Remote-Desktop-on-a-Windows-Azure-Linux-VM

    http://social.msdn.microsoft.com/Forums/windowsazure/en-US/b2902dfd-ad29-48a1-b317-30e8f62c496b/installing-gnome-on-centos-walinuxagent-conflict?forum=WAVirtualMachinesforWindows

    http://habeebperk.wordpress.com/2012/10/28/install-xrdp-server-on-centos-6-3-x86_64/

     

Posted in Azure, Cloud, IAAS, Linux, Virtual Machines, Windows Azure | 8 Comments

Deleting orphan disks in Windows Azure

Microsoft updated Windows Azure Portal yesterday to make it easier to delete all Virtual Machines for a Cloud Service along with its associated VHD’s. Previously when you deleted virtual machines you had to manually delete the disks associated with this VHD. This led to situations where you had a large number of unattached disks in your Azure storage account.

You can find out if you have unattached disks by running the following PowerShell commands.

Get-AzureDisk | Where {! $_.AttachedTo } | Select DiskName

You can also delete the disk and the VHD using the following command.

Get-AzureDisk | Where {! $_.AttachedTo } | Select DiskName | Remove-AzureDisk –DeleteVHD

 

Posted in IAAS, PowerShell, Storage, Windows Azure | Leave a comment

Setting up DMZ in Windows Azure

Microsoft released many enhancements to Windows Azure Platform at TechEd last week. You can find a good summary of these enhancements below:

http://weblogs.asp.net/scottgu/archive/2013/06/03/windows-azure-announcing-new-dev-test-offering-biztalk-services-ssl-support-with-web-sites-ad-improvements-per-minute-billing.aspx

 

They also released a new feature that will allow you to set Access control lists on public end points for compute resources running in Windows Azure. You cannot configure Access Control Lists(ACL’s) via Portal at this time. Portal updates are coming soon. If you want to configure ACL’s the only option available right now is to use PowerShell.

First you need to download the latest Windows Azure PowerShell cmdlets

http://www.windowsazure.com/en-us/downloads/

 

Best resource to learn about Access Control Lists is the following session at TechEd.

http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/MDC-B360#fbid=yYpOapL8pq0

Other resource for updates to PowerShell cmdlets is the following post from Michael Washam.

http://michaelwasham.com/windows-azure-powershell-june-2013-update-for-iaas-and-paas/

Here are the ACL related cmdlets:

1. New-AzureAclConfig : It creates a empty new ACL configuration object

2. Get-AzureAclConfig: Gets ACL configuration object from a VM

3. Remove-AzureAclConfig: Removes ACL configuration from a VM

4. Set-AzureAclConfig: Sets the ACL Configuration object on an existing Azure VM Configuration

5. Set-AzureEndpoint: Updates an existing endpoint assigned to an existing Azure virtual machine.

6. Set-AzureLoadBalancedEndpoint: Updates all of the endpoints in a given load balancer set within a Windows Azure Service

If you need more information about this cmdlets you can use get-help cmdletname -full for examples and description of the cmdlet.

Most organizations use DMZ in their on premise environments. As they start leveraging public cloud like Windows Azure they have a need to establish DMZ like environment in public cloud as well.

I investigated using ACL’s to create a DMZ like environment in Azure Virtual Network. To keep this simple I assumed that cross premise connectivity is not established. So the VM’s in the virtual network has their own Active Directory Domain Controller and DNS.

Here are the steps at a high level:

1. I created Azure Virtual network called funwithvnetacl. It has 3 subnets: FrontEndSubnet has web servers(web1, web2), Backend Subnet has application servers(appsvr1, appsvr2) and DomainSubnet(DC01) has the domain controller.

<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>            
      <DnsServers>            
        <DnsServer name="DC01" IPAddress="192.168.3.4" />            
      </DnsServers>            
    </Dns>            
    <VirtualNetworkSites>            
      <VirtualNetworkSite name="funwithvnetacl" AffinityGroup="funwithnetacl">            
        <AddressSpace>            
          <AddressPrefix>192.168.0.0/16            
        </AddressSpace>            
        <Subnets>            
          <Subnet name="FrontEndSubnet">            
            <AddressPrefix>192.168.1.0/24            
          </Subnet>            
          <Subnet name="BackEndSubnet">            
            <AddressPrefix>192.168.2.0/24            
          </Subnet>            
          <Subnet name="DomainSubnet">            
            <AddressPrefix>192.168.3.0/28            
          </Subnet>            
        </Subnets>            
        <DnsServersRef>            
          <DnsServerRef name="DC01" />            
        </DnsServersRef>            
      </VirtualNetworkSite>            
    </VirtualNetworkSites>            
  </VirtualNetworkConfiguration>            
</NetworkConfiguration>

 

2. I created on load balanced end point for the two web servers. It uses Port 80 or external and private port. This is where one can host a public web site. End Point for RemoteDesktop is also configured on both web1 web2 servers.

web1

3. Appsvr1 and Appsvr2 also have RemoteDesktop port open.

Since FrontEndSubnet and BackEndSubnet are in the same virtual network the web servers can access application servers over private endpoint.

We only want to allow RemoteDesktop from your corporate network. This means that we will need to use Access Control Lists to secure every public Remote Desktop endpoint on servers web1, web2, appsrv1 and appsvr2.

It was easy to apply ACL’s on the endpoints. The script I used is shown below.

You can only apply ACL on public endpoints.

RemoteSubnet argument in Set-AzureAclConfig only accepts public IP addresses. If you provide private IP addresses the cmdlet will run without error but will not apply the rule.

Azure Virtual network does not currently offer load balancing over internal endpoints. The only way to get load balancing to work is to create a public endpoint. In my example I chose not to load balance the app servers and just connected the web1 to appsvr2 and web2 to appsvr2.

#Create DMZ            
#Create a new ACL config            
$acl1 = New-AzureAclConfig            
#Add a rule that allows my Home PC to RDP into web1, web2, appsvr1, appsvr2             
#Keep in mind we RemoteSubnet only accepts public IP addresses             
Set-AzureAclConfig -AddRule -ACL $acl1 -Action Permit -RemoteSubnet XX.XX.XXX.XXX/YY -Order 100 -Description "Allow my home Servers in Frontend subnet to access rdp endpoint on web1,web2, appsvr1, appsvr2"            
Get-AzureVM -ServiceName "web-acldemo" -Name "web1" | Set-AzureEndpoint -ACL $acl1 -Name "RemoteDesktop" -Protocol tcp -LocalPort 3389 -PublicPort 56180  | Update-AzureVM            
Get-AzureVM -ServiceName "web-acldemo" -Name "web2" | Set-AzureEndpoint -ACL $acl1 -Name "RemoteDesktop" -Protocol tcp -LocalPort 3389 -PublicPort 61176  | Update-AzureVM            
Get-AzureVM -ServiceName "appsvr1-acldemo" -Name "appsvr1" | Set-AzureEndpoint -ACL $acl1 -Name "RemoteDesktop" -Protocol tcp -LocalPort 3389 -PublicPort 56180  | Update-AzureVM            
Get-AzureVM -ServiceName "appsvr1-acldemo" -Name "appsvr2" | Set-AzureEndpoint -ACL $acl1 -Name "RemoteDesktop" -Protocol tcp -LocalPort 3389 -PublicPort 61176  | Update-AzureVM            

Get-AzureVM -ServiceName "web-acldemo" -Name "web1" | Get-AzureEndpoint            
Get-AzureVM -ServiceName "web-acldemo" -Name "web2" | Get-AzureEndpoint            
Get-AzureVM -ServiceName "appsvr1-acldemo" -Name "appsvr1" | Get-AzureEndpoint            
Get-AzureVM -ServiceName "appsvr1-acldemo" -Name "appsvr2" | Get-AzureEndpoint

DMZ

Access Control Lists are a big improvement as they allow you to control access to your public endpoint at the infrastructure layer. You can also use Windows Firewall on the servers to control access but I prefer infrastructure layer access control.

If you are interested in implementing internal load balancing solution in Windows Azure Virtual network you should look at http://techlib.barracuda.com/display/BWAFv76/Deploying+the+Barracuda+Web+Application+Firewall+Vx+-+Windows+Azure

ACL’s currently work on Virtual Machines only. They work in Virtual Machines in Azure Virtual Network and on Virtual Machines that are not in Virtual Network. ACL’s don’t work on Cloud Services(Web Roles/Worker Roles) yet.

Updated on 11/7/2013

Windows Azure Management Portal was recently updated to allow you to create ACL’s using the portal. For those of you who prefer using Portal over writing PowerShell scripts this is a welcome improvement.

Select the virtual machine that has public endpoint where you need to apply an ACL.

Select the tab for end points.

You will see a new button at the bottom called “MANAGE ACL”

acl-1

Press the button and you will see a popup that will allow you to create the ACL.

You will need to enter a description for the rule. Action that is Permit or Deny and finally a place to enter IP address range in CIDR notation. In my example below I wanted to only allow my Home PC to access the virtual machine so I used “External IP Address of my Home”/32

You can find your external IP address using http://www.whatismyip.com

acl-2

 

 

Posted in PowerShell, Virtual Networks, Windows Azure | Leave a comment