Jason Haley

Ramblings from an Independent Consultant

Talk: Securing Your Web Application in Azure with a WAF

Last night I spoke at the Boston Azure User Group. The slides are available here: Securing Your Web Application in Azure with a WAF

As I mentioned last night, this is the first edition of the talk, I plan on giving it to my user group next month (October) and again at the Boston Code Camp in November – so if you have any feedback please let me know I’d love to improve the content.

I want to work more demos into the presentation next time … and of course get them all to work (1 demo didn’t work last night).

Here are some of the useful links mentioned last night:

Next time for the demos I’m going to look at using the OWASP Juice Shop webapp

Talk: Design Azure Web Apps and Mobile Apps

Wednesday and Thursday of this week (Sept 27 – 28) I helped out with the second round of 70-534 Architecting Azure Solutions Event in NYC (the Boston event was Sept 14 - 15).  Microsoft is organizing these events in many cities currently in the mid-west and east coast.

My talk was on Web and Mobile Apps.  There were about 40 – 50 people in the room and around 200 on the simulcast.

BTW: if you are interested in having an event streamed you should check out Nelco Media.

One of the links I mentioned for people who are studying for the exam: Exam prep for Architecting Microsoft Azure Solutions, 70-534 it has the exam OD’s linked to the corresponding landing area in the Azure documents.

My presentation can be downloaded on github here and here are links to the labs for the Web Apps and the Mobile Apps

Azure Help: Traffic Manager–PowerShell Script to Add Traffic Manager Probe IP Addresses

If you are using Traffic Manager to route traffic between two data centers and the endpoints are inside of a VNET, you’ll need to add network security group rules for Traffic Manager’s probe IP Addresses or your endpoints will always show as degraded.

image

Once you think of the purpose of the probe … then it makes total sense why the endpoint shows as being “Degraded” – if traffic manager can’t get to the endpoint then it can’t make a decision of whether it should send traffic to it or not.

So in order to fix the, you need to add the Traffic Manager probe IP Addresses to the inbound NSG rules of you VNET.  That is simple to do in the portal (or via PowerShell) but – there are 23 of them!  Who really wants to manually enter 23 of them? … and don’t forget there are 2 data centers, so that is really 46 of them.

I certainly don’t enjoy entering that many NSG rules (even though it is easy) – so I created a script to do it.

In my case, I had east and west coast data center locations.  You’ll need to plug in your subscription, resource groups, nsg names and maybe change the probe port and the number to start the priority at (I have 150 – 173).

You should also verify the IP Addresses have not changed from the listing on this page: https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-faqs under the question “What are the IP addresses from which the health checks originate?” about 3/4 the way down the page.

The source code can be found here: https://github.com/JasonHaley/AzureHelp/blob/master/TrafficManager/AddTrafficManagerProbeRules.ps1

#Verify latest Probe IP Addresses at https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-faqs

$subscriptionId = "YourSubscriptionId"
$resourceGroupEast = "EastCoastResourceGroup"
$resourceGroupWest = "WestCostResourceGroup"
$nsgEast = "EastCoastNSG"
$nsgWest = "WestCoastNSG"
$probePort = 80 
$rulePriorityStart = 150
$rulePriority = $rulePriorityStart

$trafficManagerProbeIPs = @("40.68.30.66",`
                             "40.68.31.178", `
                             "137.135.80.149", `
                             "137.135.82.249", `
                             "23.96.236.252", `
                             "65.52.217.19", `
                             "40.87.147.10", `
                             "40.87.151.34", `
                             "13.75.124.254", `
                             "13.75.127.63", `
                             "52.172.155.168", `
                             "52.172.158.37", `
                             "104.215.91.84", `
                             "13.75.153.124", `
                             "13.84.222.37", `
                             "23.101.191.199", `
                             "23.96.213.12", `
                             "137.135.46.163", `
                             "137.135.47.215", `
                             "191.232.208.52", `
                             "191.232.214.62", `
                             "13.75.152.253", `
                             "104.41.187.209",`
                             "104.41.190.203")

Login-AzureRmAccount

Set-AzureRmContext -SubscriptionId $subscriptionId

$groupEast = Get-AzureRMNetworkSecurityGroup -ResourceGroupName $resourceGroupEast `
     -Name $nsgEast
$groupWest = Get-AzureRMNetworkSecurityGroup -ResourceGroupName $resourceGroupWest `
     -Name $nsgWest


For($i=0; $i -lt $trafficManagerProbeIPs.Length; $i++) {
    $ruleName = "Inbound-TMProbe" + $i.ToString() + "-Https-Allow"

    $rulePriority = $rulePriorityStart + $i

    $groupEast | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleName `
        -Description "Allow Traffic Manager Probe HTTPS" `
        -Access Allow -Protocol Tcp -Direction Inbound -Priority $rulePriority `
        -SourceAddressPrefix $trafficManagerProbeIPs[$i] -SourcePortRange * `
        -DestinationAddressPrefix * -DestinationPortRange $probePort

    $groupWest | Add-AzureRmNetworkSecurityRuleConfig -Name $ruleName `
        -Description "Allow Traffic Manager Probe HTTPS" `
        -Access Allow -Protocol Tcp -Direction Inbound -Priority $rulePriority `
        -SourceAddressPrefix $trafficManagerProbeIPs[$i] -SourcePortRange * `
        -DestinationAddressPrefix * -DestinationPortRange $probePort
}
$groupEast | Set-AzureRmNetworkSecurityGroup
$groupWest | Set-AzureRmNetworkSecurityGroup

This script has saved me a lot of time.

References

Traffic Manager routing methods

Traffic Manager Frequently Asked Questions (FAQ)

Manage network security groups using PowerShell

Create network security groups using PowerShell

Add/Set/Remove NSG rules in ARM mode Azure Powershell

Azure Help: WebApps–Copying and Exporting Connection Strings and App Settings

When you create a WebApp in Azure’s App Service, you get a couple of important features with Application Settings:

  1. The ability for your developers not know the production app settings or connection strings values … or just the option to develop with settings that are not used once deployed (such as working with a local database)
  2. The ability to override values in the web.config that is deployed with the application

The first item is important for security reasons.  It makes it possible to control access to the production credentials.  The second item is really useful for changing settings for different environments – such as a staging db for a staging slot and a production db for the production slot.

I am a big fan of using Application Settings in my WebApps.

If you are not familiar with them, just look for the Application Settings menu item in your Web App (shown below).  The App settings and Connection strings sections are what I want to discuss below.

imageimage

I’ve included some reference links at the bottom of this entry for you to learn more (if you are interested).

Problem 1:  Get a list of all the App Settings and/or Connection Strings of a deployed WebApp

The Azure portal will allow you to view all the settings, but sometimes you need the values for several app settings and/or connection strings – so viewing the values in the portal isn’t enough.

To solve this problem, I have created a PowerShell script that exports the values to two csv files (if I want both AppSettings and ConnectionString).  Usually it is just the AppSettings that I need, but you never know.

The source code can be found here:https://github.com/JasonHaley/AzureHelp/blob/master/WebApps/ExportConnectionStringsAndAppSettings.ps1

$subscriptionId = "<subscriptionId>"
$resourceGroupSource = "<source resource group>"
$webAppsource = "<source web app name>"
$slotSource = "<source slot>"

$appSettingsFileName = "appSettings.csv"
$connectionStringsFileName = "connectionStrings.csv"

Login-AzureRmAccount

Set-AzureRmContext -SubscriptionId $subscriptionId

# Load Existing Web App settings for source and target
$webAppSource = Get-AzureRmWebAppSlot -ResourceGroupName $resourceGroupSource `
   -Name $webAppsource -Slot $slotSource

# Create csv files if file names are set
If ($appSettingsFileName -ne "") {
    $webAppsource.SiteConfig.AppSettings | Select-Object -Property Name, Value | `
       Export-Csv -Path $appSettingsFileName -NoTypeInformation
}

If ($connectionStringsFileName -ne "") {
    $webAppsource.SiteConfig.ConnectionStrings | Select-Object -Property Name, Type, `
ConnectionString | Export-Csv -Path $connectionStringsFileName -NoTypeInformation }

The generated csv files look like this:

image

Problem 2:  Copy all the App Settings and/or Connection Strings to another WebApp

Once in awhile I need to move WebApps from one place to another or lately I’ve been upgrading clients from ASEv1 instances to ASEv2 instances – which means a new build of an environment (not an upgrade).  ASE stands for App Service Environment.

If I already have the values of the AppSettings and ConnectionStrings in a deployed WebApp … it would be nice to copy the values to the new one and not have to enter them one-by-one.

The important thing to note: AppSettings and ConnectionStrings are not in source control (unless you have complete ARM templates stored … which you wouldn’t want your secrets in – so that complicates matters) … so deploying the latest code to the new WebApp is only part of the solution of spinning up a new environment.

To solve this problem, I have created a PowerShell script that will copy over all the AppSettings and/or ConnectionStrings of one WebApp to another WebApp.

The source code can be found here: https://github.com/JasonHaley/AzureHelp/blob/master/WebApps/CopyConnectionStringsAndAppSettings.ps1

$subscriptionId = "<subscriptionId>"
$resourceGroupSource = "<source resource group>"
$resourceGroupTarget = "<target resource group>"

$webAppsource = "<source web app name>"
$webAppTarget = "<target web app name>"

$slotSource = "<source slot>"
$slotTarget = "<target slot>"

Login-AzureRmAccount

Set-AzureRmContext -SubscriptionId $subscriptionId

# Load Existing Web App settings for source and target
$webAppSource = Get-AzureRmWebAppSlot -ResourceGroupName $resourceGroupSource `
    -Name $webAppsource -Slot $slotSource

# Get reference to the source Connection Strings
$connectionStringsSource = $webAppSource.SiteConfig.ConnectionStrings

# Create Hash variable for Connection Strings
$connectionStringsTarget = @{}

# Copy over all Existing Connection Strings to the Hash
ForEach($connStringSource in $connectionStringsSource) {
    $connectionStringsTarget[$connStringSource.Name] = `
         @{ Type = $connStringSource.Type.ToString(); `
            Value = $connStringSource.ConnectionString }
}

# Save Connection Strings to Target
Set-AzureRmWebAppSlot -ResourceGroupName $resourceGroupTarget -Name $webAppTarget `
    -Slot $slotTarget -ConnectionStrings $connectionStringsTarget

# Get reference to the source app settings
$appSettingsSource = $webAppSource.SiteConfig.AppSettings

# Create Hash variable for App Settings
$appSettingsTarget = @{}

# Copy over all Existing App Settings to the Hash
ForEach ($appSettingSource in $appSettingsSource) {
    $appSettingsTarget[$appSettingSource.Name] = $appSettingSource.Value
}

# Save Connection Strings to Target
Set-AzureRmWebAppSlot -ResourceGroupName $resourceGroupTarget -Name $webAppTarget `
   -Slot $slotTarget -AppSettings $appSettingsTarget

These two scripts save me a lot of time due to the reality of there being several AppSettings that I need to work with (when I need to work with them).

References

Using App Settings in Azure Web Apps

Windows Azure Web Sites: How Application Strings and Connection Strings Work

Azure App Service Web Config Vs Application Settings

Easily Manage Azure Web App Connection Strings using PowerShell

Using Powershell to manage Azure Web App Deployment Slots

Azure Help Series

Today I’m starting a new series of blog entries – Azure Help.  There are many people who do “Tips and Tricks” and “Lessons Learned”, which I like and find useful – the idea with this series is the same, but I needed to come up with a unique name.

I want to cover real scenarios and lessons I’ve learned the past 5 or so years in using Azure on a day to day basis.

Entry List

This is a list of the blog entries I have for Azure Help.

Idea List

This is a list of ideas that I’m planning future entries about:

  • WebApps – Maintenance and Logging
  • Cloud Services – Using VSTS Release Management to Change ConfigurationSettings
  • VSTS - Add and Remove NSG to Publish a Release to VNet in Azure

Source Code

AzureHelp - a repo for code used in these Azure Help entries.

Suggestions?

Do you have a suggestion for future a future entry?  If so, feel free to email or tweet me your idea … as long as it makes sense, chances are good it will make it on the list Smile

North Boston Azure Cloud User Group–August 29

Last night was the NBA group in Burlington.  We had a great turn out!

The main event was: Bill Pratt: Application Insights can be Your Best Friend

Last night was the first meeting that I tried a new format of having a shorter talk before the main talk (like Bill Wilder does for the Boston Azure Cloud User Group).

For the opening talk I did a walk through of Azure Tips and Tricks – (all inspired by Michael Crump) - He came up with the tips, I just did the live demoing and added a little color to it Smile

Here are the tips and links to his blog entries that I covered:

For Bill’s talk, we had a lot of interaction and questions – which is always nice to see.  We also have some positive feedback in the comments on the meetup site about the event.

On another note

It is hard to believe the group will be one year old next month.  I skipped December (due to meeting on the last Tuesday of the month) but have more than made up for it with other events and double meeting months – a total of 14 events since September 2016.

The membership is now up to 369 which is hard to believe … seems like it was just hitting the 200 number a few months ago.

Nice to see the user group community growing well at the Microsoft Burlington office.

Talk: WebApps and WebJobs

Last month (December 14, 2016) I presented at the Western Mass Development Technology User Group.  The group meets in Agawam, MA about two hours west of Salem, MA – if you are in the area you should check out their meetup site: https://www.meetup.com/Western-Mass-Development-Technology-Users-Group/

I was a fun time and a great group of people interested in learning more about Azure. 

I split the time between WebApps and WebJobs and tried not to make too many comparisons with Cloud Services (since only one person was familiar with them).  We spent most of the time in either the Azure portal or in Visual Studio, but for anyone interested my power point presentation files can be downloaded from this link: https://jhaleyfiles2016.blob.core.windows.net/public/Western%20Mass%20Dev%20Tech.zip

Late November 2016 Update on Azure Cloud Certification Studying

The day after I posted my last update (November 2016 Update on Azure Cloud Certification Studying) I found out the 70-534 exam (the one I am studying for) was going to have some major changes on November 22 - Azure Architecture Exam (70-534) Gets ARM Refresh.

So I had two choices: Cram for the exam and take it before Nov 22 or Step back and widen the material I’ve got to learn to pass it.

Since then, I’ve decided to postpone taking the exam this year.  I am not really doing this to just get the certificate (ie. pass the exam) I want to know that I know the material … and right now I don’t know some of the new things they are adding to the exam.

Also, I’ve been meaning to get back to blogging and have decided to start writing about some of the topics I am learning while studying for the 70-354 exam – so this week I am planning my first blog post (or set of blog posts) … still in the planning stage.