{"id":21145350,"url":"https://github.com/jsa2/azureautodiagnostic","last_synced_at":"2025-09-11T09:38:32.426Z","repository":{"id":46959208,"uuid":"408300361","full_name":"jsa2/AzureAutoDiagnostic","owner":"jsa2","description":null,"archived":false,"fork":false,"pushed_at":"2022-08-09T04:37:54.000Z","size":78,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"project","last_synced_at":"2025-07-09T07:45:50.128Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jsa2.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-20T03:35:21.000Z","updated_at":"2023-03-16T14:25:55.000Z","dependencies_parsed_at":"2022-08-12T13:11:21.268Z","dependency_job_id":null,"html_url":"https://github.com/jsa2/AzureAutoDiagnostic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jsa2/AzureAutoDiagnostic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsa2%2FAzureAutoDiagnostic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsa2%2FAzureAutoDiagnostic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsa2%2FAzureAutoDiagnostic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsa2%2FAzureAutoDiagnostic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsa2","download_url":"https://codeload.github.com/jsa2/AzureAutoDiagnostic/tar.gz/refs/heads/project","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsa2%2FAzureAutoDiagnostic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274609467,"owners_count":25316622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T08:39:39.586Z","updated_at":"2025-09-11T09:38:32.384Z","avatar_url":"https://github.com/jsa2.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Azure Auto-diagnostic solution\r\n\r\n## Disclaimer\r\nRead [License](#license) before proceeding\r\n- Do not use this solution in any environment that has sensitive or valuable data. This is a tool meant for security research. \r\n\r\n## Solution description\r\nOne of the top issues in detecting and investigation of security incidents (or suspicion of incident) is the fact that logs are often not simply enabled. \r\n\r\nThere are multiple ways to enable diagnostic logs in Azure: Built-in and recommended option is to use Azure Policy and to create individually diagnostic deployment for different resource types. \r\n\r\n**Alternative for security research**\r\n\r\n✅ This solution removes the requirement for creating individual Azure policies per resource type. As long as the resource type supports the [Diagnostic settings](https://docs.microsoft.com/en-us/rest/api/monitor/diagnostic-settings/create-or-update) API in Azure Resource Manager. The goal of this tool is to gather diagnostic data of resources for security research with fire \u0026 forget mechanism.\r\n\r\n**Solution image**\r\n\r\n![img](https://securecloud188323504.files.wordpress.com/2021/09/image-38.png)\r\n\r\n\r\n\r\n\r\n\r\n## Table of contents\r\n- [Azure Auto-diagnostic solution](#azure-auto-diagnostic-solution)\r\n  - [Disclaimer](#disclaimer)\r\n  - [Solution description](#solution-description)\r\n  - [Table of contents](#table-of-contents)\r\n  - [Prerequisites](#prerequisites)\r\n  - [Installation](#installation)\r\n    - [CLI script](#cli-script)\r\n  - [- Ensure that you have run ``` NVM Install 14```](#--ensure-that-you-have-run--nvm-install-14)\r\n  - [Confirming the solution works](#confirming-the-solution-works)\r\n  - [Notes](#notes)\r\n  - [Debugging](#debugging)\r\n  - [License](#license)\r\n\r\n\r\n\r\nService | Description\r\n-|-\r\n|Azure Functions | Enables diagnostic settings on resources \r\n|Azure Event Hub | Signals the function on new deployments\r\n|Azure Monitor | Source for the activityLog \r\n|Azure Log Analytics | Destination for log export\r\n\r\n\r\n\r\n\r\n## Prerequisites \r\n\r\nRequirement | description | Install\r\n-|-|-\r\n✅ Bash shell script | Tested with WSL2 and Ubuntu on windows | [CLI script](#cli-script)\r\n✅ [p7zip](https://www.7-zip.org/) | p7zip is  used to create the zip deployment package for package deployment | ``sudo apt-get install p7zip-full`` \r\n✅ AZCLI | Azure Services installation |``curl -sL https://aka.ms/InstallAzureCLIDeb \\| sudo bash``\r\n✅ Node.js runtime 14 | Used in Azure Function, and to create local function config |[install with NVM](https://github.com/nvm-sh/nvm#install--update-script)\r\n\r\n\r\n\r\n## Installation\r\n\r\n### CLI script\r\nThe CLI script below will use current subscription context to setup the solution after user has performed \r\n- Ensure you are running this script in Linux Shell (Bash)\r\n- Ensure you have selected a single subscription context\r\n\r\n``` az login; az account set --subscription \"6193053b-408b-44d0-b20f-4e29b9b67394\"``` \r\n\r\n- Ensure you have permissions on the WSL folder to create directories, and have permissions on those created directories ``chmod 700 /home/user``\r\n   - If you cloned this project with windows client, it is recommended to clone it to Linux filesystem `` /home/user/projectName `` \r\n- Ensure that you have run ``` NVM Install 14```\r\n--- \r\n\r\n```shell\r\n# clone the project\r\ngit clone https://github.com/jsa2/AzureAutoDiagnostic; cd AzureAutoDiagnostic\r\n# Install the node project\r\nnpm install\r\n#Define starting variables\r\nrnd=$RANDOM\r\nautodg=autodiag-$rnd\r\nfnName=function-autodiag-eh-$rnd\r\nrg=RG-ehsolution-$rnd\r\nlocation=westeurope\r\n# You can ignore the warning \"command substitution: ignored null byte in input\"\r\nstorageAcc=storage$(shuf -zer -n10  {a..z})\r\n# KV with random name\r\nkvName=kv-autodiag2$rnd-$RANDOM\r\n\r\n# Create Resource Group\r\naz group create -n $rg \\\r\n-l $location \\\r\n--tags=\"svc=autoDiag\"\r\n\r\n\r\n# use existing wsID\r\nwsid=\"/subscriptions/3539c2a2-cd25-48c6-b295-14e59334ef1c/resourcegroups/rg-laws/providers/microsoft.operationalinsights/workspaces/hublaws\"\r\n\r\n#Create new WS\r\nwsid=$(az monitor log-analytics workspace create --location $location -g $rg  -\r\nn laws${autodg}1 -o tsv --query \"id\")\r\n\r\n# Create storageAcc Account \r\naz storage account create -n $storageAcc  -g $rg --kind storageV2 -l $location -t Account --sku Standard_LRS\r\n\r\n# Create Key Vault\r\naz keyvault create --location $location -g $rg  -n $kvName\r\n\r\n# Create EH\r\naz eventhubs namespace create -n eh-${autodg} -g $rg -l $location \r\n\r\naz eventhubs eventhub create -n hub-${autodg} -g $rg --namespace-name eh-${autodg}\r\n#Rule for function\r\nmonitorRuleId=$(az eventhubs eventhub authorization-rule create -g $rg --namespace-name eh-${autodg} --eventhub-name hub-${autodg} --name auth${autodg} --rights Listen -o tsv --query \"id\")\r\n\r\n#Rule for Azure Monitor\r\n\r\n\r\nauthRuleForDiagnosticSetting=$(echo $monitorRuleId | cut -d \"/\" -f1,2,3,4,5,6,7,8,9)/authorizationrules/RootManageSharedAccessKey\r\n\r\nehConstring=$(az eventhubs eventhub authorization-rule keys list -g $rg --namespace-name eh-${autodg} --eventhub-name hub-${autodg} --name auth${autodg} -o tsv --query \"primaryConnectionString\")\r\nsaConstring=$(az storage account show-connection-string -g $rg  -n  $storageAcc -o tsv --query \"connectionString\")\r\n\r\n## Create SUB\r\nsub=$(echo $wsid | cut -d \"/\" -f3);\r\n\r\n\r\nsubs=$(az account list --query [].id -o tsv)\r\n\r\nfor subbie in $subs\r\n   do\r\n   az account set --subscription $subbie\r\n   az monitor diagnostic-settings subscription create -n diag-$rnd \\\r\n   --event-hub-auth-rule $authRuleForDiagnosticSetting \\\r\n   --location $location \\\r\n   --subscription $subbie \\\r\n   --event-hub-name hub-${autodg} \\\r\n   --logs '[\r\n      {\r\n      \"category\": \"Administrative\",\r\n      \"enabled\": true\r\n      }\r\n      ]'\r\n   done\r\n\r\n## Deploy FN\r\n#kvRefEh=$(az keyvault secret set --name ehsecret --vault-name $kvName --value $ehConstring -o tsv --query \"id\"| cut -d \"/\" -f1,2,3,4,5)\r\nkvRefEh=\"@Microsoft.KeyVault(SecretUri=$(az keyvault secret set --name ehsecret --vault-name $kvName --value  $ehConstring -o tsv --query \"id\" | cut -d \"/\" -f1,2,3,4,5))\"\r\n\r\n\r\n\r\nnode createConf.js hub-${autodg} $wsid $ehConstring $saConstring\r\n\r\n## Create Function App\r\naz functionapp create \\\r\n--functions-version 3 \\\r\n--consumption-plan-location $location \\\r\n--name $fnName \\\r\n--os-type linux \\\r\n--resource-group $rg \\\r\n--runtime node \\\r\n--storage-account $storageAcc\r\n\r\nsleep 10\r\n\r\n# Scope for web app\r\nscope=$(echo $wsid | cut -d \"/\" -f1,2,3)\r\n# Enable Managed Identity and required permissions for key vault and monitor\r\nidentity=$(az functionapp identity assign -g  $rg  -n $fnName --role 749f88d5-cbae-40b8-bcfc-e573ddc772fa --scope $scope -o tsv --query \"principalId\")\r\n\r\n#Set kv permissions for KV references\r\naz keyvault set-policy --name $kvName --object-id $identity --secret-permissions get -g $rg\r\n\r\nfor subbie in $subs\r\n   do\r\n   az account set --subscription $subbie\r\n   az role assignment create --assignee $identity --role 749f88d5-cbae-40b8-bcfc-e573ddc772fa --scope \"/subscriptions/${subbie}\"\r\n   done\r\n\r\naz account set --subscription $sub\r\n\r\nsleep 20\r\n\r\nsleep 20\r\n\r\n## Enables KV REF and Disables the MSI endpoint for testing that function can get access tokens (Enable for debugging)\r\naz functionapp config appsettings set \\\r\n--name $fnName \\\r\n--resource-group $rg \\\r\n--settings AzureEventHubConnectionString=$kvRefEh  workspaceId=$wsid WEBSITE_RUN_FROM_PACKAGE=1 AzureWebJobs.testmsi.Disabled=true\r\n\r\n#Create ZIP package \r\n7z a -tzip deploy.zip . -r -mx0 -xr\\!*.git -xr\\!*.vscode \r\n\r\n# Force triggers by deployment and restarts\r\n\r\ni=0\r\nwhile [ -z \"$fnTrues\" ] ; do\r\n((i++))\r\naz functionapp deployment source config-zip -g $rg -n $fnName --src deploy.zip\r\nsleep 10\r\naz functionapp restart --name $fnName --resource-group $rg \r\nsleep 10\r\nfnTrues=$(az functionapp function show -g $rg -n $fnName --function-name ehdiag -o tsv --query \"id\")\r\necho \"$fnTrues\"\r\necho \"attempting to sync triggers $C/$E\"\r\n if [[ $i -eq 6 ]]; then\r\n    break  \r\n    fi\r\ndone\r\n\r\n#\r\nrm deploy.zip\r\n\r\n\r\n# Create Resource Group\r\nrnd=$(az group create -n \"testRg-$RANDOM\" -l $location --tags=\"svc=autoDiag\" -o \"tsv\" --query \"name\")\r\n\r\n#Create rnd resources to confirm the diagnostic setting\r\naz network public-ip create --location $location -g $rnd  -n pip-$RANDOM\r\naz network lb create --location $location -g $rnd  -n lb-$rnd\r\naz keyvault create --location $location -g $rnd  -n ${kvName}1\r\n\r\naz group delete -n $rnd\r\n```\r\n\r\n## Confirming the solution works\r\nAfter deployment is created: \r\n1. confirm that both functions are visible in the portal \r\n\r\n![img](https://securecloud188323504.files.wordpress.com/2021/09/image-40.png)\r\n\r\n   - If none of the functions are visible in the portal restart the function, this will force resync of the triggers. If that does not help delete the resource group, and redeploy the solution (remember to delete the diagnostic setting created by the automation manually)\r\n\r\n\r\n2. Create new resource in the **same subscription** the solution was deployed on, for example Azure Key Vault:\r\n   \r\n   ``az keyvault create --location $location -g $rg  -n $kvName`` \r\n\r\n3. Approx 15 mins since resource was created you should see the following diagnostic setting enabled\r\n![img](https://securecloud188323504.files.wordpress.com/2021/09/image-43.png)\r\n\r\n\r\n## Notes\r\n- If you do not have all the solution providers registered for the solution the installation might fail.\r\n- Keyvault registration is usually slow, register the provider before running the script, refer to the https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/resource-providers-and-types to register provider for subscription.\r\n- If the installation fails, it is better to delete the resource group\r\n\r\n## Debugging\r\n- When the function is starting, you might see some transient errors in the logs. These errors seem to be related to propagation delay for some of the resources in scope. Sometimes the managed identity is unable to receive tokens immediately after deployment\r\n\r\n**No triggers?**\r\n- As always, you might see a situation with functions where the triggers are not getting synced. At this point you can try to restart the function from the portal, or just delete the resource-group, and deploy it again.\r\n![img](https://securecloud188323504.files.wordpress.com/2021/09/image-39.png)\r\n\r\n**Tracing errors**\r\n\r\n\r\n\r\nUse the appInsights created in the resource group to trace errors. Look for messages in traces and exceptions.\r\n\r\n```\r\ntraces\r\n| distinct message\r\n```\r\n\r\n```\r\nexceptions\r\n```\r\n\r\n![img](https://securecloud188323504.files.wordpress.com/2021/09/image-41.png)\r\n\r\n\r\n**1. Illegal connection string**\r\n- This signals, that the function does not have permission to the Key Vault. This can happen if there is propagation error with Key Vault Permissions\r\n`` Illegal connection string parameter name '@Microsoft.KeyVault(SecretUri' (Parameter 'connectionString') `` \r\n2. Propagation delay in AAD\r\n``WARNING: Retrying role assignment creation: 3/36``  \r\n\r\n---\r\n\r\n## License\r\nCopyright 2021 Joosua Santasalo\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsa2%2Fazureautodiagnostic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsa2%2Fazureautodiagnostic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsa2%2Fazureautodiagnostic/lists"}