Archive for the ‘Azure’ Category

Recently i had request to invite external user to Azure Application but not to send invitation to user email address

Open Powershell:

Connect-AzureAD -credential

New-AzureADMSInvitation -InvitedUserEmailAddress "" -SendInvitationMessage $false -InvitedUserType "Member" -inviteRedirectUrl ""


InvitedUserType: Member or Guest



Then copy InviteReedemUrl and send it to requester





Create user in Azure AD and give him read rights over subscription and Site recovery contributor role over Azure Recovery Vault


Encrypt password file and install Azure module:

$username = ""
$pwdTxt = Get-Content "C:\ExportedPassword.txt"
$securePwd = $pwdTxt | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $securePwd
Login-AzureRmAccount -Credential $cred | out-null
$vault = Get-AzureRmRecoveryServicesVault -Name "Vault"
$VaultFileLocation = Get-AzureRmRecoveryServicesVaultSettingsFile -SiteRecovery -Vault $vault
Import-AzureRmRecoveryServicesAsrVaultSettingsFile -Path $VaultFileLocation.FilePath
$Fabrics = Get-AzureRmRecoveryServicesAsrFabric
$Containers = Get-AzureRmRecoveryServicesAsrProtectionContainer -Fabric $Fabrics
$items = Get-AzureRmRecoveryServicesAsrReplicationProtectedItem -ProtectionContainer $Containers
$filename = "C:\trapper.imports";
write-host $filename;
foreach ($item in $items)
'"{0}" {1}' -f "server",'replication['+$item.RecoveryAzureVMName+']',""""+$item.ReplicationHealth+"""" | Add-Content -LiteralPath $filename -Encoding "Default" -Force;
cd "C:\Program Files\Zabbix Agent\bin\win64"
.\zabbix_sender.exe -z zabbix_server -p 10051 -c "C:\Program Files\Zabbix Agent\conf\" -i $filename -vv
rm -Path $VaultFileLocation.FilePath
rm -Path $filename


Create zabbix item:


Type of infomation:Text


Create Trigger:
{server:replication[VM1].str(“Critical”)}=1 or {server:replication[VM01].nodata(180m)}=1

Schedule it by Task Scheduler:

Program/Script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

Add argument: (Optional): “C:\azure_replication.ps1”

Strart in (Optional): C:\

I used this powershell script as starting point.

Install powershell in Zabbix server.

Copy azure_rss.ps1 to /opt/zabbix/azure_rss (make that folder if it doesn’t exists,give zabbix user ownership)




$a= $hsg.Content
[xml]$ret = $hsg.Content.TrimStart("")
#$ | Select-Object *
#write-host ""
if($ -eq $null){
        #write-host $
        #write-host $ " On : "  $
        write-output "All services are working properly" > /tmp/out.txt
    $c = $ + " On : " + $"Issue Category : " + $ + $ + " On : " + $ + " Details : " + $ + $
    write-output $c > /tmp/out.txt
    #write-host $ " On : "  $
    #Write-Host "Issue Category : " $
    #write-host ""
    #write-host ""
rv hsg, ret


I had to redirect output to text file because some hex symbols in output.

copy to /opt/zabbix/azure_rss (“azure” is zabbix host)

pwsh /opt/zabbix/azure_rss/azure_rss.ps1
var=$(cat "/tmp/out.txt")
zabbix_sender -z localhost -p 10051 -s "azure" -k -o "$var"

Create cron job to run script on interval you predefined



On Zabbix server, create item:

Type:Zabbix trapper

Type of information:Text


Create Trigger:

Expression: {“Issue Category”)}=1

Because full string output will be lengthy , full error message won’t be visible so we must click-Monitoring-latest data-specify host to see full script output.

Monitoring Azure resources with Zabbix

Posted: August 21, 2018 in Azure

I used this post as starting point.

Creating Azure application

(ID/keys will be used for authentication to Azure)

In Azure portal click Azure Active directory-App registrations-new App registration



In App registrations select All apps from drop-down menu-click on Zabbix application


Write down application ID (we’ll use it on scripts)


Click Settings-Keys-set a name,duration and click Save


Write down key


Write down TenantID


Write down Subscription ID-from Azure dashboard,click Cost Management + Billing under my subscription write subscription ID


Give application read rights to resource group

click on resource group-Access control (IAM)


click Add-select Reader role-Assign access to Azure AD user,group or application and select Zabbix application


Install powershell on Zabbix server (CentOS)

# Register the Microsoft RedHat repository
curl | sudo tee /etc/yum.repos.d/microsoft.repo
# Install PowerShell
sudo yum install -y powershell

Extract and copy all files in to /usr/lib/zabbix/externalscripts, make sure *.sh files are executable

Supported services are SQL,storage account,Virtual Machines and Virtual Network gateway

All available services and metric:

Time periods (monitoring intervals) are called timegrains

time_grains = {
"PT1M" => "1 Minute",
"PT5M" => "5 Minutes",
"PT1H" => "1 Hour",
"PT12H" => "12 Hours"

In trapper.ps1 and azure.ps1 substitute TenantID,applicationID, application key in appropriate sections/

Files can be downloaded from here


For VM:

./ resource group subscription vm

For SQL:

./ resource group subscription sql

For network gateway:

./ resource group subscription vng

For Storage account

./ resource group subscription storage

[root@ip-172-31-27-77 externalscripts]# ./ RG  subscriptionD storage
"{#ID}": "/subscriptions/111-222-333/resourceGroups/RG/providers/Microsoft.Storage/storageAccounts/storageaccount",
"{#STORAGEACCOUNT}": "storageaccount"
"{#ID}": "/subscriptions/111-222-333/resourceGroups/RG/providers/Microsoft.Storage/storageAccounts/storageaccount",
"{#STORAGEACCOUNT}": "storageaccount"
"{#ID}": "/subscriptions/111-222-333/resourceGroups/RG/providers/Microsoft.Storage/storageAccounts/storageaccount",
"{#STORAGEACCOUNT}": "storageaccount"

give ownership of azure.json to zabbix user:

chown zabbix:zabbix azure.json

create dummy host and attach template, specify resource group and subscription ID


Test zabbix trapper:

./ zabbix-dummy-host

if no issues,create cron job for trapper (for example to run it every 15 minutes):

*/15 * * * * /usr/lib/zabbix/externalscripts/ dummy-host

On Amazon side:

Create new elastic IP

Select Virtual Private Cloud-Elastic IPs-Allocate new address


Click allocate


I used default VPC if you need to create new VPC,take a look here

Create EC2 instance and assign VPC (default or custom one and subnet)


Allocate Elastic IP to instance-in EC2 select instance-Actions-Associate address


Resource Type-instance-select instance and  Private IP


Azure portal

Create Virtual Network Gateway (details here)

Create Local Network Gateway


IP Address:Amazon Elastic IP (created earlier)

Address Space (Amazon VPC subnet to which EC2 instance is assigned)



Once Local network gateway is created go to Connections-Add


Select Virtual Network gateway,local network gateway and shared key


Copy Virtual network gateway IP


find out Azure VM network

Click on Azure VM-Networking to find out subnet name


write down subnet, it will be needed for Powershell script


On AWS EC2 instance install RRAS and configure IPSec VPN.In this case is Azure Virtual Network Gateway IP, Azure VM subnet and 123456 Secret Key

# Windows Azure Virtual Network

# This configuration template applies to Microsoft RRAS running on Windows Server 2012 R2.
# It configures an IPSec VPN tunnel connecting your on-premise VPN device with the Azure gateway.

# !!! Please notice that we have the following restrictions in our support for RRAS:
# !!! 1. Only IKEv2 is currently supported
# !!! 2. Only route-based VPN configuration is supported.
# !!! 3. Admin priveleges are required in order to run this script

Function Invoke-WindowsApi(
[string] $dllName,
[Type] $returnType,
[string] $methodName,
[Type[]] $parameterTypes,
[Object[]] $parameters
## Begin to build the dynamic assembly
$domain = [AppDomain]::CurrentDomain
$name = New-Object Reflection.AssemblyName 'PInvokeAssembly'
$assembly = $domain.DefineDynamicAssembly($name, 'Run')
$module = $assembly.DefineDynamicModule('PInvokeModule')
$type = $module.DefineType('PInvokeType', "Public,BeforeFieldInit")

$inputParameters = @()

for($counter = 1; $counter -le $parameterTypes.Length; $counter++)
$inputParameters += $parameters[$counter - 1]

$method = $type.DefineMethod($methodName, 'Public,HideBySig,Static,PinvokeImpl',$returnType, $parameterTypes)

## Apply the P/Invoke constructor
$ctor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([string])
$attr = New-Object Reflection.Emit.CustomAttributeBuilder $ctor, $dllName

## Create the temporary type, and invoke the method.
$realType = $type.CreateType()

$ret = $realType.InvokeMember($methodName, 'Public,Static,InvokeMethod', $null, $null, $inputParameters)

return $ret

Function Set-PrivateProfileString(
## Prepare the parameter types and parameter values for the Invoke-WindowsApi script
$parameterTypes = [string], [string], [string], [string]
$parameters = [string] $category, [string] $key, [string] $value, [string] $file

## Invoke the API
[void] (Invoke-WindowsApi "kernel32.dll" ([UInt32]) "WritePrivateProfileString" $parameterTypes $parameters)

# Install RRAS role
Import-Module ServerManager
Install-WindowsFeature RemoteAccess -IncludeManagementTools
Add-WindowsFeature -name Routing -IncludeManagementTools

# !!! NOTE: A reboot of the machine might be required here after which the script can be executed again.

# Install S2S VPN
Import-Module RemoteAccess
if ((Get-RemoteAccess).VpnS2SStatus -ne "Installed")
Install-RemoteAccess -VpnType VpnS2S

# Add and configure S2S VPN interface
Add-VpnS2SInterface -Protocol IKEv2 -AuthenticationMethod PSKOnly -NumberOfTries 3 -ResponderAuthenticationMethod PSKOnly -Name -Destination -IPv4Subnet @("") -SharedSecret 123456

Set-VpnServerIPsecConfiguration -EncryptionType MaximumEncryption

Set-VpnS2Sinterface -Name -InitiateConfigPayload $false -Force

# Set S2S VPN connection to be persistent by editing the router.pbk file (required admin priveleges)
Set-PrivateProfileString $env:windir\System32\ras\router.pbk " " "IdleDisconnectSeconds" "0"
Set-PrivateProfileString $env:windir\System32\ras\router.pbk " " "RedialOnLinkFailure" "1"

# Restart the RRAS service
Restart-Service RemoteAccess

# Dial-in to Azure gateway
Connect-VpnS2SInterface -Name

Test connection



Connection from EC2 to Azure






In this example we’ll connect virtual networks located in different Azure regions.This connections is called VNet to VNet.VNet-to-VNet connectivity utilizes the Azure virtual gateways to connect two or more virtual networks together.



Creating Gateway subnet-West Europe

Before deploying Virtual Network Gateway we need first to deploy gateway subnet

In subnet properties click + Gateway subnet



Creating Virtual network gateway

In Azure portal click new resource-Virtual network gateaway



Gateway type:VPN

VPN Type:route-based




Creating virtual network in North Europe



Creating Gateway subnet



Defining subnet


Creating Virtual Gateway




In similar way Virtual Network gateway is created in west europe (gateway subnet-


Creating virtual machine in North Europe region

VM is created in North Europe and assigned to vnet-northeurope network



Creating VM in West Europe

similar for Virtual machine in West Europe


Creating VNet peering

in NorthEurope Virtual network gateway click Connections-Add




Specify shared key and opposite network gateway-Virtual network gateway from west-europe (as second gateway)




Create VNet peering from opposite side-from west europe virtual gateway click-connections-add connection-for second virtual gateway specify north europe virtual gateway-same shared key



On both sides, on Virtual network gateway-under connections,connection state should be connected





Connection from north europe VM to VM in west europe using private IP and vice-versa




Web application firewall (WAF) is a feature of Application Gateway that provides centralized protection of  web applications from common exploits and vulnerabilities.

Web Application Firewall work differently from a standard IP firewall. A normal firewall is designed to block individual TCP or UDP ports, or to restrict the type of traffic that’s allowed to flow across a particular port. However, WAFs are designed to monitor HTTP or HTTPS traffic that’s being sent to a Web application. The firewall’s job is to determine whether the traffic is normal user traffic, or if it’s something malicious. An example of a malicious request might be a hidden field manipulation attack. If malicious traffic is detected, then the WAF will block the request to prevent it from reaching the Web application server, and will typically also terminate the session.

In Azure portal click new resource-Application Gateway


Select WAF (SKU size needs to be minimum medium)


Choose network and subnet

Firewall modes:

Detection-malicious access will be allowed and logged

Prevention:malicious access will be denied


Creating Backend pool

On Application gateway properties click Backend Pools-add your web servers to pool


Test access:



Simulating atack

Access will be denied



We can allow specific traffic based on OWASP 3.O rule set, in example below ATTACK-XSS and ATTACK-SQLI will be allowed (script above)

On Web application firewall click on Advanced rule configuration