Pages

Thursday, November 17, 2022

Configuring an Azure Function App that uses a system managed identity to execute Az.Compute module cmdlets that will retrieve all Azure VMs with their Status then use a Logic App run the app and email the report

In this post, I would like to demonstrate the following using an Azure Function App and Logic App.

Function App:

Use the Az.Compute module to execute Get-AzVM to get the list of virtual machines and store it in an array

  1. Loop through the virtual machines and retrieve the name, resource group, location, vmsize, and os type
  2. Retrieve the VM status
  3. Store all fields in an array
  4. Create an HTML header, body
  5. Convert data into HTML format
  6. Return a HTML formatted email for delivery
  7. The Function App will use a System Assigned Managed Identity for authentication and authorization

Logic App:

  1. Set up a recurring Logic App that runs everyday
  2. Executes the Function App to retrieve the HTML formatted email report
  3. Send an email with the HTML formatted email report

Step #1 – Create a Function App that will retrieve the list of Virtual Machines, generate and return an HTML email report

Begin by creating a Function App that will retrieve Cylance Device List and return it in HTML format. This Function App collects the data that will in turn be call by a Logic App to generate an email and send the report off to an email address.

image

Proceed to create a Function App with the following parameters:

Publish: Code

Runtime stack: PowerShell Core

Version: 7.2

Operating System: Windows

Configure the rest of the parameters as required by the environment.

image

image

With the Function App created, proceed to create the function trigger:

image

Select HTTP trigger as the template and provide a meaningful name:

image

With the trigger created, navigate to Code + Test and paste the following code into run.ps1:

https://github.com/terenceluk/Azure/blob/main/Function%20App/Get-AzureVMs.ps1

image

The following are changes you’ll need to apply to the code:

The client name:

image

Save the Function App and navigate back out to the Function App > App files, switch to the requirements.psd1, then add the following line to load the Az.Compute module, which will allow Get-AzVM to be executed:

'Az.Compute' = '5.*'

image

Save the file and navigate to the Identity blade then turn on the System assigned identity:

image

image

Once the system assigned managed identity is created, you should see the Function App created in the Enterprise applications:

image

Click on Azure role assignments while still in the Identity blade of the Function App:

image

Configure Reader permissions on the subscription containing the VMs:

image

With the Reader role granted, navigate back to the Function App and execute the Test/Run feature with HTTP method POST and without any body submitted:

image

You should see a HTTP response code 200 OK with the contents of your report displayed:

image

Step #2 – Create a Logic App that is scheduled to run every day to call the Azure Function App to retrieve the device list report and then send an email report out

With the Azure Function App created and tested, proceed to create the Logic App that will be scheduled to run every day to call the Azure Function App to retrieve the device list report and then send an email report out.

image

Navigate to the Logic app designer blade and begin to configure the steps for the Logic App. The following are the steps we’ll be configuring:

The first is the Recurrence step that will schedule this logic app to run at 9:00a.m. EST every day:

image

Create an additional step by clicking on the + button, select Add an action then type in Function, select the Function that was created:

image

We won’t need to pass a parameter so leave it unconfigured:

image

Proceed to create two additional steps:

  1. Initialize variable
  2. Set variable

These two steps will place the retrieved HTML report into the body of the email:

Initialize variable

Name: EmailBody
Type: String
Value: <leave blank>

image

Set variable

Name: EmailBody
Value: Select the Body

image

Configure the last step as Send an email (V2) that will email this report to the email address required:

image

Save the logic app and proceed to use the Run Trigger feature to execute the Logic App and confirm that the report is generated and sent:

image

One of the steps I did not include in this post is to secure the Function App to require authentication so allow the Logic App can execute it. Please see one of my previous posts for the steps:

Securing Azure Function App to require authentication and granting access to a Logic Apps’ Managed Identity
http://terenceluk.blogspot.com/2022/09/securing-azure-function-app-to-require.html

I hope this helps anyone who may be looking for instructions on how to configure automated reports with virtual machine details.

Setting up BitTitan to migrate mailboxes from O365 to another O365 tenant fails source authentication with the error: "Your migration failed while checking source credentials. The request failed. The remote server returned an error: (401) Unauthorized."

It has been a while since I’ve been involved with Office 365 mail migrations but I was recently contacted by a colleague who was setting up BitTitan’s MigrationWiz for a migration and could not figure out why he was not able to authenticate so I hopped on to help. The search results from Google directed me to various documentation provided by BitTitan but none of them lead me to the right solution. I don’t usually use YouTube for troubleshooting as most of us probably feel it takes too long to watch a video as compared to reading a blog post like this but the following video is where I eventually found the answer:

How to solve BitTitan MigrationWiz Error 401 Unauthorized in 2022
https://www.youtube.com/watch?v=iI35AJrGYiw

This blog post serves to help anyone who might encounter the same problem quickly find the answer.

Problem

You attempt to use the Verify Credentials feature in MigrationWiz after setting up the source and destination tenants but receive the status: Failed (Verification)

image

Navigating into one of the accounts display the following error message:

Your migration failed while checking source credentials. The request failed. The remote server returned an error: (401) Unauthorized.

image

Solution

The reason why the environment I was troubleshooting in has this failure is because Microsoft had started disabling basic authentication for Office 365 that affects the EWS service that MigrationWiz relies on (3 minute mark in the video). This can be confusing because if you navigate to Settings > Org Settings > Modern Authentication, you’ll see that it states basic authentication is enabled for various services (including Exchange Web Services). The problem here is that this only applies to the modern Outlook client, which MigrationWiz isn’t.

image

To remediate this, click on the Help & support button at the bottom right corner of the administration console:

image

Then type in the following string to search:

diag: enable basic auth in exo

imageimage

Proceed to click on the Run Tests button:

image

Assuming basic authentication is disabled, we should be provided with a drop down menu box to select a service to enable:

image

Select Exchange Web Services (EWS) to enable the MigrationWiz dependent service, then click on Update Settings:

image

The following message will be displayed:

Run diagnostics
Basic authentication has been re-enabled for the selected protocol.

The Basic authentication blocked applications setting has been updated. You should be able to use Basic authentication with the selected protocol within the next hour.

image

Proceed to try and verify the credentials in an hour or so and the process should complete successfully.

Hope this helps as it took me a bit of time to figure this out.

Tuesday, October 18, 2022

Troubleshooting traffic blocked by Azure Front Door WAF Policy in Prevention mode

I recently had to troubleshoot an issue with an Azure Front Door WAF policy we had just changed from Detection to Prevention and thought I’d share some steps I used to troubleshoot and have this blog post for me to reference in the future as I’m bound to forget some of the steps.

Before you begin, have a look at the following Microsoft documentation to understand how to use Log Analytics to review WAF logs in a Log Analytics workspace:

Use Log Analytics to examine Application Gateway Web Application Firewall (WAF) Logs
https://learn.microsoft.com/en-us/azure/application-gateway/log-analytics

With that, let’s have a look at the process I went through.

Scenario

The developer notified me after the Front Door WAF Policy was switched from Prevention from Detection:

image

To troubleshoot, we used a browser’s Developer Tools to review the Network traffic and noticed the following error:

Request Method: Post
Status Code: 403
Referrer Policy: strict-origin-when-cross-origin

image

The above error was thrown when we opened up the website and navigated to sit.domain.com that presented a login page, entered our credentials into the form, clicked login, which would then send us to sitapp.domain.com. Clicking on the login button did not do anything as we would receive the 403 error as shown above.

Below is a screenshot of the log showing the origin and referrer URL, which is the login site we tried to log into:

image

Troubleshooting 

The first thought I had was that the referrer policy did not allow sit.domain.com to send a successful login to sitapp.domain.com so what we needed to do was whitelist the domain but this actually the wasn’t the case when we look into the logs.

There are no custom rules configured so we needed to determine which one of the managed rules has blocked the traffic:

image

In order to troubleshoot, Diagnostics must be turned on to capture the WebApplicationFirewall logs:

image

Verify that you are sending the FrontDoor WebApplicationFirewall Log to a log analytics workspace as shown here:

image

Once logging is turned on, wait 10 to 15 minutes for the log capturing to begin then proceed to replicate the issue. Note that you should see AzureDiagnostics displayed when logging has come into effect:

image

We should see entries with the following query when the WAF logs are captured:

AzureDiagnostics
| where Category == "FrontDoorWebApplicationFirewallLog"

image

Use the following query to retrieve all the entries representing blocks by a WAF rule:

AzureDiagnostics
| where action_s == "Block"

**Note that Block is case sensitive so “block” will not return any results.

image

Since we know have the information we collected from the browser network trace, we can use the information in there to look for the entry representing the block we’re experiencing. The values I usually use are requestUri_s or host_s but note that when using the requestUri_s, the URL will need to have a colon and port number after the domain as shown in the screenshot below:

https://sitapp.domain.com:443/webapi/api/account/login

image

Here is an example of adding the requestUri_s in the query:

AzureDiagnostics

| where action_s == "Block" and requestUri_s == https://sitapp.domain.com:443/webapi/api/account/login

With the entry located, review the ruleName_s value and note the ending number:

image

In this example, the rule that is blocking the traffic is 949110. However, this may not be locatable in the Managed rules of the WAF policy:

image

Although this is the rule that results in the traffic being blocked, it could be triggered by another rule. To determine the other related rules, we can locate the trackingReference_s value to look up the other logs related to this:

image

Use the following query to retrieve the entries:

AzureDiagnostics

| where trackingReference_s contains "0viJPYwAAAAD2qxqM/l3+QJ3xvYLEO0hYQ0hJMzBFREdFMDUxMwA0MzRlN2MwNC02M2NmLTRjMjMtYjFhOS00NDNjYmViZTJmNTg="

image

Expand the results and you should see another rule with the number 200002 that contains the same trackingReference_s as shown in the screenshot below:

image

Scrolling further down in the log will display more details about the reason why the traffic is blocked and in this case they are:

details_msg_s: Failed to parse request body.

details_data_s: %{reqbody_error_msg]

image

Searching for the 200002 number in the Managed rules will display the following rule with the description Failed to parse request body:

image

Unsure of what to make of the details, a case was opened with Microsoft but the engineer was unable to find any additional information for this error but was able to suggest that the following is what was happening:

When a request to sign into the https://sit.domain.com/ portal, the webpage directing the traffic to sitapp.domain.com is sending some strange or malformed data in the request body which causes the Front Door’s WAF policy to think there may be an attack. Their suggestion was to check the request body for any formatting error that would be triggering front door.

Workaround

I’ve requested the developer to look into this and for the time being changed the action for rule 200002 to log rather than block on anomaly so the portal login would start working:

imageimage

Not the best solution but serves as a workaround. Hope this helps anyone looking for information on how to troubleshoot Azure Front Door WAF policy prevention blocks.