Archives mensuelles : mars 2017

Configurer sa première Appliance Kemp dans Azure

J’avais déjà utilisé Kemp par le passé pour DirectAccess : Monitoring DirectAccess with Kemp. Vu que sous certains aspects ça ressemble beaucoup à ce que j’ai connu avec du TMG ou de l’UAG, j’ai décidé de passer un peu de temps avec. Vu que je passe beaucoup de temps dans Azure, cela impliquait de pouvoir monter des labs de manière industrielle. Tout de suite on pense à développer un template ARM. Sur le principe, je suis d’accord, cependant, c’est développer beaucoup d’énergie pour un sujet qui n’apportera pas beaucoup de gain. On ne déploie pas autant de machines virtuelles que d’Appliances virtuelles Kemp.

C’est pour cette raison que j’ai décidé d’explorer la création d’une Appliance virtuelle Kemp en PowerShell. Sur le papier, cela ressemble beaucoup à une machine virtuelle pour un quelconque Linux. Pourtant, il y a quelques subtilités à prendre en compte :

  • Kemp est un fournisseur du MarketPlace, ça change un peu les choses pour la déclaration de l’image source à utiliser (notion de plan)
  • L’Appliance virtuelle aura deux interfaces réseau (les templates mis à disposition sont tous mono-carte)
  • Un peu de sécurité (Network Security Group) est nécessaire pour faire les choses dans les règles de l’art

 

Pour les prérequis, je considère que les éléments existent préalablement :

  • Resource Group
  • Storage Account
  • Virtual Network avec ses deux Subnets

 

Mon objectif est de déployer un Load Balancer Kemp avec deux interface réseau. Ci-dessous les prérequis techniques de mon déploiement :

$LocationIPR = ‘<Azure Region Name>’

$ResourceGN = ‘<Resource Group Name>’

$VnetName = ‘<Virtual Network Name>’

$subscriptionname = ‘<Subscription Name>’

$StorageAccountName = « <storage account name> »

$storageAccountResourceGroupName = « <Storage Account Resource Group> »

$FWName = « <Virtual Machine Name> »

$instanceSize = « Standard_D3_v2 »

$subnetFrontName = « Front »

$frontIP = « 10.1.0.4 »

$subnetBackName = « Back »

$backIP = « 10.2.0.4 »

$reservedIPName = « FrontReservedIP »

$publicNICName = $FWName + « _ » +$subnetFrontName + « NIC »

$privateNICName = $FWName + « _ » + $subnetBackName + « NIC »

$FWPublicIPName = $FWName + « _ »+ « PublicIP »

$diskName = $FWName + « _OSDisk »;

clip_image001

Première subtilité Kemp, le nom du compte « root » de l’Appliance, ce sera « BAL ». On peut spécifier ce que l’on veut, ce sera toujours « BAL » pour le compte par défaut. On ne va donc pas le contrarier et générer un objet de type « SecureString » pour personnaliser le mot de passe initial.

$FWAdminUser = « bal »

$FWPassword = « LeMotDePasseIlaChangé! »

$SecurePassword = ConvertTo-SecureString -String $FWPassword -AsPlainText -Force

$FWSecureCredential = New-Object -TypeName « System.Management.Automation.PSCredential » -ArgumentList $FWAdminUser, $SecurePassword

clip_image002

 

No-Comment, …

$cred = Get-Credential

Login-AzureRmAccount -Credential $cred -SubscriptionName $subscriptionname

clip_image003

 

La première étape, c’est d’identifier le fournisseur nommé « Kemp Technologies » dans la région qui nous intéresse : West Europe :

$publisher = « kemptech »

$publishername = Get-AzureRmVMImagePublisher -Location $LocationIPR | Where {$_.Publishername -eq $publisher}

clip_image004

 

Puis d’identifier la ou les offres proposées par ce fournisseur. Avec Kemp, nous avons deux offres. La solution Kemp 360 Central est une Appliance destinée à centraliser l’administration d’un ensemble d’Appliances Kemp, l’offre qui nous intéresse est donc « VLM-Azure ».

Get-AzureRmVMImageOffer -Location $LocationIPR -PublisherName $publishername.PublisherName

clip_image005

 

$Offer = « vlm-azure »

$ImageOffer = Get-AzureRmVMImageOffer -Location $LocationIPR -PublisherName $publishername.PublisherName | Where {$_.Offer -eq $Offer}

clip_image006

 

Prochaine étape, la SKU ou l’édition en français.

Get-AzureRmVMImageSku -Location $LocationIPR -PublisherName $publishername.PublisherName -Offer $ImageOffer.Offer

clip_image007

 

Celui qui va m’intéresser est l’édition « FreeLoadMaster », c’est pour du test :

$skuname = « freeloadmaster »

$sku = Get-AzureRmVMImageSku -Location $LocationIPR -PublisherName $publishername.PublisherName -Offer $ImageOffer.Offer | Where {$_.Skus -eq $skuname}

$sku

clip_image008

 

Le Marketplace propose toujours les trois dernières versions d’une solution. Il est donc logique de trouver cela :

Get-AzureRmVMImage -Location « West Europe » -PublisherName $publishername.PublisherName -Offer $offer -Skus $sku.skus

$image = Get-AzureRmVMImage -Location « West Europe » -PublisherName $publishername.PublisherName -Offer $offer -Skus $sku.skus | Select -Last 1

$image

clip_image009

 

Seconde subtilité, celle du Marketplace et la manière de référencer l’image à utiliser. Celle-ci vient du Marketplace Azure. Pour un déploiement automatisé, il nous faudra deux choses :

  • Définir la notion de plan (quelle ressource déployer)
  • Autoriser le déploiement automatique pour cette ressource

Pour la notion de plan cela se présente ainsi :

$vm1 = New-AzureRmVMConfig -VMName $FWName -VMSize $instanceSize

Set-AzureRMVMOperatingSystem -VM $vm1 -Linux -Credential $FWSecureCredential -ComputerName $FWName

Set-AzureRMVMSourceImage -VM $vm1 -PublisherName $image[0].PublisherName -Offer $image[0].Offer -Skus $image[0].Skus -Version $image[0].Version

$vm1.Plan = @{« name »= $sku.skus; « publisher »= $image.PublisherName; « product » = $image.Offer}

clip_image010

 

Note : Depuis la version 1.2.2 du module AzureRM, on dispose de la commande Set-AzureRmVMPlan.

Pour le second, cela se passera dans le portail, au niveau de la souscription. Nous avons un menu nommé « Programatic Deployment ». On remarque qu’il n’y a pas de menu pour ajouter / supprimer les fournisseurs du MarketPlace. Pour ajouter le fournisseur Kemp Technologies, j’ai dû réaliser un déploiement en utilisant le portail. Attention, le modèle d’autorisation ne considère pas que le fournisseur mais aussi la solution déployée.

clip_image011

Les bases sont posées. On revient maintenant sur du classique avec la déclaration du disque OS de notre future machine virtuelle.

$storageAccount = Get-AzureRmStorageAccount -ResourceGroupName $storageAccountResourceGroupName -Name $StorageAccountName

$osDiskURI = ($storageAccount.PrimaryEndpoints.Blob.ToString() + $FWName + « / » + $diskName + « .vhd »).ToLower()

Set-AzureRMVMOSDisk -VM $vm1 -Name $diskName -VhdUri $osDiskURI -CreateOption fromImage

$osDiskURI

clip_image012

Ma machine virtuelle devra avoir deux interfaces réseau, dont une avec une adresse IP publique et un nom DNS associé.

$vnet = Get-AzureRMVirtualNetwork -Name $VnetName -ResourceGroupName $ResourceGN

$subnetFront = Get-AzureRMVirtualNetworkSubnetConfig -Name $subnetFrontName -VirtualNetwork $vnet

$subnetBack = Get-AzureRMVirtualNetworkSubnetConfig -Name $subnetBackName -VirtualNetwork $vnet

$publicIP = New-AzureRMPublicIpAddress -name $FWPublicIPName -ResourceGroupName $ResourceGN -Location $LocationIPR -AllocationMethod Dynamic -domainNameLabel ($FWName.ToLower() + (Get-Random -Minimum 1 -Maximum 100))

$PublicIP

clip_image013

 

Déployer une machine virtuelle avec une adresse IP publique sans Network Security Group est criminel. Vu que ça coute pas grand-chose et que cela ne nécessite que quelques lignes de PowerShell, nous allons faire l’effort pour filtrer le trafic réseau entrant pour uniquement deux protocoles :

  • Le portail d’administration de l’Appliance (8443 en HTTPS)
  • Le port SSH d’administration de l’Appliance

 

$NSGrule1 = New-AzureRmNetworkSecurityRuleConfig -Name « KempWebConsole » -Description « Allow Kemp web console Access » -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 8443

$NSGrule2 = New-AzureRmNetworkSecurityRuleConfig -Name « KempSSHConsole » -Description « Allow Kemp SSH Access » -Access Allow -Protocol Tcp -Direction Inbound -Priority 101 -SourceAddressPrefix Internet -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 22

$NSG = New-AzureRmNetworkSecurityGroup -ResourceGroupName $ResourceGN -Location $LocationIPR -Name ($FWName.ToUpper() + « _NSG ») -SecurityRules $NSGrule1, $NSGrule2

$NSG

clip_image014

 

Nous avons maintenant tout ce qu’il nous faut pour créer la première interface réseau et l’associer à notre objet machine virtuelle en cours de construction :

$frontNIC = New-AzureRMNetworkInterface -Name $publicNICName -ResourceGroupName $ResourceGN -Location $LocationIPR -PrivateIpAddress $frontIP -SubnetId $subnetFront.Id -PublicIpAddressId $publicIP.Id

$frontNIC.NetworkSecurityGroup = $NSG

$frontNIC | Set-AzurermNetworkInterface

Add-AzureRMVMNetworkInterface -VM $vm1 -Id $frontNIC.id -Primary

clip_image015

Note : C’est à cette première interface réseau qu’a été associé notre Network Security Group. Une fois la configuration de notre Appliance Terminée, je recommande vivement de reconfigurer les règles pour limiter l’accès à ces protocoles.

Il y a un sujet que je n’aborde pas dans cet article, c’est comment notre Kemp va-t-il pouvoir porter des VIP? Jusqu’à il y a peu, l’utilisation des adresses IP publiques sur les machines virtuelles étaient limitées en deux points :

  • Seule l’interface réseau « primaire » d’une machine virtuelle peut disposer d’adresse IP publique
  • Une interface réseau « primaire » ne peut avoir qu’une seule adresse IP publique

Au moment où j’écris ce billet, ces limitations sont encore d’actualité mais de nouvelles fonctionnalités actuellement en Preview vont permettre d’oublier ces limitations : Step-by-Step: Setup Multiple Public IPs on a VM in Azure.

La démarche pour la seconde carte réseau est identique à deux subtilités près. La première est que cette seconde interface ne sera pas considérée comme « primaire » mais comme « secondaire » et qu’aucune adresse IP publique n’est associée à cette interface.

$backNIC = New-AzureRMNetworkInterface -Name $privateNICName -ResourceGroupName $ResourceGN -Location $LocationIPR -PrivateIpAddress $backIP -SubnetId $subnetBack.Id

Add-AzureRMVMNetworkInterface -VM $vm1 -Id $backNIC.id

clip_image016

Nous en arrivons à la fin. La construction de notre objet machine virtuelle est terminée. Il ne nous reste plus qu’à ordonner son déploiement avec une dernière commande PowerShell :

New-AzureRMVM -ResourceGroup $ResourceGN -VM $vm1 -Location $LocationIPR

clip_image017

 

Après quelques minutes de déploiement, on devrait être en mesure de joindre le portail d’administration de notre Appliance pour s’authentifier. Dans mon cas, il est accessible à l’URL suivante : . Lors de la première connexion authentifiée, on arrive immédiatement à la configuration de la licence. Munissez-vous de votre Kemp-ID pour réaliser l’activation en ligne et vous pourrez commencer à configurer votre Appliance virtuelle Kemp

clip_image018

 

Maintenant, quelques détails purement Kemp :

  • Ne cherchez pas à déployer une quelconque VM Extension dans la machine virtuelle, le Linux VMAgent ne s’installera pas
  • Ne cherchez pas à activer le mode Transparency dans la configuration vos virtual services.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)

Shared Access Signature with stored Access Policy

Pendant mes cours Azure, lorsqu’on en arrive au stockage on parle rapidement des Shared Access Signatures. C’est le seul mécanisme qui est visible depuis de portail Azure pour gérer plus finement l’accès au stockage.

clip_image001

Le problème, c’est que ce mécanisme présente un certain nombre de contraintes :

  • SAS est une URL publique. Toute personne qui détient cette URL peut l’utiliser tant que les conditions exprimées lors de sa création restent valides.
  • Tant que l’URL est valable, on peut l’utiliser. En fait le seul réel moyen de la révoquer une clé SAS consiste à renouveler la clé primaire / secondaire qui a été utilisée pour délivrer la clé SAS.

C’est là que le mécanisme SAS with Stored Access Policy prend tout son sens :

  • Ce n’est pas une URL mais uniquement une clé d’accès pour un conteneur donné. Il faut donc disposer des deux informations pour exercer le niveau de privilège accordé
  • C’est une politique référencée que l’on peut mettre à jour ou même révoquer

Bref, cela n’a que des avantages par rapport aux clé SAS classiques telles que présentées dans le portail. Le seul truc, c’est que c’est un peu plus compliqué à mettre en œuvre car même en PowerShell, ce n’est pas nativement implémenté.

Histoire d’illustrer un peu la chose, nous allons mettre à disposition un fichier nommé secret.txt dans un conteneur lui-même nommé « topsecret » pour lequel la politique d’accès a été maintenu à « Private ». Le tout est dans un storage Account dont l’existence est-elle publique : . Objectif, se faire délivrer une clé d’accès pour le conteneur.

Pas la peine de présenter la première partie, c’est de l’initialisation Azure tout ce qu’il y a de classique, oups ARM devrais-je dire.

$cred = Get-Credential

Login-AzureRmAccount -Credential $Cred -SubscriptionName ‘Services de la plateforme Windows Azure pour Visual Studio Profe’

$storageaccount = Get-AzureRmStorageAccount -StorageAccountName tpstockage01 -ResourceGroupName ‘tpstockage’

clip_image002

 

On a besoin des clés primaires / secondaires pour travailler.

$accountKeys = Get-AzureRmStorageAccountKey -ResourceGroupName ‘TPStockage’ -Name ‘tpstockage01’

$accountKeys

clip_image003

 

On va utiliser la clé primaire pour se créer un contexte qui va nous permettre de manipuler le Storage Account.

$StorageContext = New-AzureStorageContext -StorageAccountName ‘tpstockage01’ -StorageAccountKey $accountKeys[0].Value

$StorageContext

clip_image003[1]

 

Dans notre Storage Account, nous allons mettre en place un Container. C’est obligatoire car c’est le seul niveau de délégation possible.

$container = New-AzureStorageContainer -Context $storageContext -Name ‘topsecret’

$container

$cbc = $container.CloudBlobContainer

$cbc

clip_image004

 

On notera que l’attribut PublicAccess est bien à « Off » pour le conteneur nouvellement créé. Au passage, nous avons créé un objet CloudBlobContainer que nous allons utiliser ultérieurement. Au passage, on retiendra l’URL d’accès à ce conteneur car c’est à cet emplacement que nous allons venir déposer un fichier avec la commande PowerShell suivante :

Set-AzureStorageBlobContent -File ‘C:\Users\bsaut\Desktop\Secret.txt’ -Container ‘topsecret’ -Blob ‘tpstorage01’ -Context $StorageContext

clip_image005

 

C’est maintenant que cela devient intéressant. On va commencer par récupérer la liste des permissions applicables au conteneur et créer une nouvelle policy. Pas encore de Shared Access Policies et le niveau d’accès au conteneur est bien « Private ».

$permissions = $cbc.Getpermissions()

$permissions

$policy = new-object ‘Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy’

$policy

clip_image006

 

Nous venons de créer un nouvel objet pour décrire notre politique d’accès. Nous allons peupler cet objet Policy avec quelques restrictions :

  • Date de début de la permission
  • Date de fin de la permission
  • Le niveau de permission que l’on veut accorder
  • Le nom de notre permission

 

$policy.SharedAccessStartTime = $(Get-Date).ToUniversalTime().AddMinutes(-5)
$policy.SharedAccessExpiryTime = $(Get-Date).ToUniversalTime().AddMinutes(10)
$policy.Permissions = « Read »
$permissions.SharedAccessPolicies.Add(‘SASPolicy02’, $policy)

$cbc.SetPermissions($permissions)

$permissions

$cbc

clip_image007

 

La nouvelle politique d’accès est en place. Au passage, attention sur le nommage des policy, elles doivent être uniques, sinon on actualise une policy existante. La policy est maintenant en place, on peut communiquer la clé d’accès qui s’appliquera au conteneur.

$policy = new-object ‘Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy’
$policy

$sas = $cbc.GetSharedAccessSignature($policy, ‘SASPolicy02’)

$sas.Substring(1)

clip_image008

 

La clé d’accès au conteneur (limitée dans le temps) a été révélée, il ne reste plus qu’à la consommer en accolant l’URL d’accès de notre fichier secret.txt avec la clé d’accès. Il faut juste ne pas oublier le séparateur : « ? ». On obtient la clé suivante :

 

Et effectivement, lorsqu’on consomme cela avec un Invoke-WebRequest -Uri « https://tpstockage01.blob.core.windows.net/topsecret/Secret.txt?sv=2015-04-05&sr=c&si=SASPolicy02&sig=1bJvOnNeeLgm1zDGgA9v41KkdgW2K5%2FcSBsE3s8Ottg%3D », on arrive bien à accéder au fichier en question. Pourtant, le conteneur a bien « Private » comme niveau de permission.

clip_image009

 

Si on a pu positionner une stratégie d’accès, on peut aussi la révoquer. Pour cela, on a juste besoin de connaitre son nom :

$permissions = $cbc.GetPermissions()

$permissions

$permissions.SharedAccessPolicies.remove(‘SASPolicy02’)

$Permissions

$cbc.SetPermissions($permissions)

clip_image010

 

Maintenant, vous n’avez plus d’excuse pour ne plus utiliser les Shared Access Signatures with Stored Access Policy.

BenoîtS – Simple and secure by design but Business compliant (with disruptive flag enabled)