Azure Network Security Groups: Implementatie En Architectuur

💼 Management Samenvatting

Network Security Groups (NSG's) vormen de fundamentele beveiligingslaag voor netwerkverkeer in Azure Virtual Networks. Ze functioneren als een distribueerde stateful firewall die netwerkverkeer filtert op basis van bron- en doel-IP-adressen, poorten en protocollen. Het implementeren van NSG's is een eerste vereiste voor elke Azure-omgeving die voldoet aan security best practices en compliance-frameworks zoals de BIO, ISO 27001 en NIS2. Zonder NSG's hebben workloads in Azure Virtual Networks geen netwerkfiltering, wat betekent dat al het verkeer standaard wordt toegestaan, ongeacht de bron of bestemming. Dit creëert een enorm aanvalsoppervlak en maakt laterale beweging door aanvallers mogelijk. Voor Nederlandse overheidsorganisaties is het implementeren van NSG's niet alleen een security best practice, maar een verplichte maatregel volgens de Baseline Informatiebeveiliging Overheid norm 13.01 over netwerkbeveiliging.

Aanbeveling
IMPLEMENT
Risico zonder
Critical
Risk Score
10/10
Implementatie
24u (tech: 16u)
Van toepassing op:
Azure Virtual Networks
Azure Subnets
Network Interfaces
Network Security Groups
Netwerkbeveiliging

Het ontbreken van Network Security Groups in Azure-omgevingen creëert kritieke beveiligingsgaten die kunnen leiden tot ernstige gevolgen. Zonder NSG-filtering kunnen aanvallers die toegang krijgen tot een virtuele machine zich lateraal door het netwerk bewegen zonder beperkingen, kunnen ze ongeautoriseerde toegang krijgen tot gevoelige data, kunnen ze command-and-control verkeer opzetten zonder detectie, en kunnen ze andere workloads binnen hetzelfde Virtual Network compromitteren. In een hybride scenario waarbij Azure Virtual Networks zijn verbonden met on-premises netwerken via VPN of ExpressRoute, kan het ontbreken van NSG's ook leiden tot onbeperkte toegang van on-premises systemen naar cloudworkloads, wat de hele netwerkperimeter ondermijnt. Voor Nederlandse overheidsorganisaties is het ontbreken van NSG-filtering bovendien een directe schending van compliance-vereisten: BIO norm 13.01 vereist netwerksegmentatie en -filtering, ISO 27001:2022 controle A.8.20 vereist netwerkbeveiliging, en NIS2 artikel 21 vereist technische maatregelen voor risicobeheersing inclusief netwerkbeveiliging. Tijdens audits zal het ontbreken van NSG's worden gezien als een kritieke tekortkoming die kan leiden tot negatieve auditbevindingen, mogelijke boetes en reputatieschade.

PowerShell Modules Vereist
Primary API: Azure API
Connection: Connect-AzAccount
Required Modules: Az.Network, Az.Resources, Az.Accounts

Implementatie

Dit artikel beschrijft hoe organisaties binnen de Nederlandse Baseline voor Veilige Cloud Network Security Groups implementeren en architectonisch positioneren binnen Azure Virtual Networks. De focus ligt op vijf hoofdcomponenten. Ten eerste architecturale planning en ontwerp: het bepalen waar NSG's moeten worden geïmplementeerd (subnet-niveau, interface-niveau of beide), het ontwerpen van een gelaagde beveiligingsarchitectuur, het plannen van NSG-associaties met subnetten en netwerkinterfaces, en het definiëren van naming conventions en resource organisatie. Ten tweede implementatie en deployment: het aanmaken van NSG's via Azure Portal, PowerShell, Azure CLI of Infrastructure as Code, het koppelen van NSG's aan subnetten en netwerkinterfaces, het valideren van de implementatie, en het testen van netwerkconnectiviteit. Ten derde architecturale best practices: het gebruik van subnet-NSG's voor consistente beveiliging op subnetniveau, het gebruik van interface-NSG's voor workload-specifieke beveiliging, het implementeren van gelaagde beveiliging met beide typen, en het plannen van NSG-koppelingen voor verschillende scenario's. Ten vierde operationele overwegingen: het begrijpen van NSG-limieten en -quota, het plannen van NSG-capaciteit, het beheren van NSG-levenscyclus, en het implementeren van change management-processen. Ten vijfde integratie met andere Azure-services: het integreren van NSG's met Azure Firewall, Network Watcher, Azure Monitor en andere beveiligingsservices. Het bijbehorende PowerShell-script automatiseert de implementatie van NSG's, valideert of NSG's zijn gekoppeld aan alle relevante subnetten en netwerkinterfaces, en genereert implementatierapportages.

Architecturale planning en ontwerp

Een effectieve NSG-implementatie begint met zorgvuldige architecturale planning die bepaalt waar NSG's moeten worden geïmplementeerd en hoe ze worden georganiseerd binnen de Azure-omgeving. De eerste beslissing betreft de plaatsing van NSG's: op subnet-niveau, op interface-niveau, of een combinatie van beide. Subnet-NSG's worden gekoppeld aan subnetten binnen Virtual Networks en bieden consistente beveiliging voor alle resources binnen dat subnet. Deze aanpak is ideaal voor scenario's waarbij alle workloads binnen een subnet vergelijkbare beveiligingsvereisten hebben, zoals een subnet voor web servers, een subnet voor applicatieservers, of een subnet voor databases. Subnet-NSG's zijn eenvoudiger te beheren omdat ze centraal worden toegepast op alle resources binnen het subnet, maar bieden minder flexibiliteit voor individuele workloads met unieke beveiligingsvereisten. Interface-NSG's worden gekoppeld aan individuele netwerkinterfaces van virtuele machines en bieden workload-specifieke beveiliging. Deze aanpak is ideaal wanneer specifieke virtuele machines unieke beveiligingsvereisten hebben die niet kunnen worden geadresseerd op subnetniveau, of wanneer workloads worden verplaatst tussen subnetten en de beveiligingsregels moeten meeverhuizen. Interface-NSG's bieden meer flexibiliteit maar verhogen de operationele complexiteit omdat elke virtuele machine individueel moet worden beheerd.

Een gelaagde beveiligingsarchitectuur combineert subnet-NSG's met interface-NSG's voor maximale beveiliging en flexibiliteit. In een gelaagde aanpak worden subnet-NSG's gebruikt voor algemene beveiligingsregels die van toepassing zijn op alle workloads binnen een subnet, terwijl interface-NSG's worden gebruikt voor specifieke beveiligingsregels die alleen van toepassing zijn op individuele workloads. Wanneer zowel een subnet-NSG als een interface-NSG zijn geconfigureerd, worden beide sets regels geëvalueerd: verkeer moet door beide NSG's worden toegestaan om te worden doorgestuurd. Deze gelaagde aanpak verhoogt de beveiliging maar vereist zorgvuldige planning om te voorkomen dat regels conflicteren en legitiem verkeer per ongeluk wordt geblokkeerd. Organisaties moeten beginnen met subnet-NSG's voor basale beveiliging en vervolgens interface-NSG's toevoegen wanneer specifieke workloads extra beveiliging nodig hebben. De gelaagde aanpak is vooral waardevol in omgevingen met mixed workloads waar verschillende applicaties verschillende beveiligingsniveaus vereisen, of in omgevingen waar compliance-vereisten specifieke isolatie tussen workloads vereisen.

Naming conventions en resource organisatie zijn cruciaal voor beheerbaarheid en schaalbaarheid van NSG-implementaties. Organisaties moeten consistente naming conventions definiëren die duidelijk maken waar een NSG voor wordt gebruikt, bijvoorbeeld 'nsg-web-subnet-prod' voor een NSG voor het web-subnet in productie, of 'nsg-vm-database-db01' voor een interface-NSG voor een specifieke database virtuele machine. Deze naming conventions moeten consistent worden toegepast over alle NSG's en moeten worden gedocumenteerd zodat nieuwe teamleden snel kunnen begrijpen wat elke NSG doet. Daarnaast moeten NSG's worden georganiseerd met Azure resource tags die metadata bevatten zoals omgeving (productie, test, ontwikkel), kostenplaats, eigenaar, compliance-informatie, en bedrijfseenheid. Deze tags maken het mogelijk om NSG's te groeperen en te filteren voor reporting, kostenallocatie en governance. Organisaties moeten ook overwegen om NSG's te organiseren in logische resource groups die zijn afgestemd op de netwerkarchitectuur, bijvoorbeeld één resource group per Virtual Network of per toepassingslaag.

Het plannen van NSG-associaties met subnetten en netwerkinterfaces vereist een diepgaand begrip van de netwerkarchitectuur en de communicatiepatronen tussen workloads. Organisaties moeten beginnen met het inventariseren van alle subnetten binnen Virtual Networks, het identificeren van welke subnetten kritieke workloads bevatten, en het bepalen van welke beveiligingsniveaus vereist zijn voor elk subnet. Voor subnetten met kritieke workloads zoals databases of domeincontrollers moeten organisaties overwegen om zowel subnet-NSG's als interface-NSG's te implementeren voor extra beveiliging. Voor subnetten met minder kritieke workloads zoals test- of ontwikkelomgevingen kunnen alleen subnet-NSG's voldoende zijn. Organisaties moeten ook overwegen hoe NSG-associaties worden beheerd wanneer workloads worden verplaatst tussen subnetten, wanneer nieuwe subnetten worden toegevoegd, of wanneer Virtual Networks worden uitgebreid. Het gebruik van Infrastructure as Code (IaC) zoals Azure Resource Manager templates, Terraform of Bicep kan helpen om NSG-implementaties te standaardiseren en te automatiseren, waardoor consistentie wordt gewaarborgd en menselijke fouten worden verminderd.

Implementatie en deployment

De implementatie van Network Security Groups kan op verschillende manieren worden uitgevoerd, afhankelijk van de voorkeuren, vaardigheden en infrastructuur van de organisatie. De Azure Portal biedt een gebruiksvriendelijke grafische interface voor het aanmaken en configureren van NSG's, wat ideaal is voor ad-hoc implementaties, kleine omgevingen, of wanneer teams nieuw zijn met Azure-netwerken. De portal maakt het mogelijk om NSG's visueel aan te maken, regels te configureren via een wizard, en NSG's te koppelen aan subnetten en netwerkinterfaces met drag-and-drop functionaliteit. PowerShell biedt scripting-capabilities voor geautomatiseerde en herhaalbare implementaties, wat ideaal is voor grotere omgevingen, consistentie tussen omgevingen, of wanneer NSG's regelmatig moeten worden aangemaakt als onderdeel van workload-deployments. Azure CLI biedt cross-platform scripting-capabilities die werken op Windows, Linux en macOS, wat waardevol is voor organisaties met gemengde ontwikkelomgevingen. Infrastructure as Code tools zoals Azure Resource Manager templates, Terraform of Bicep bieden de hoogste mate van automatisering en consistentie, wat essentieel is voor enterprise-omgevingen waar NSG's deel uitmaken van een groter netwerkarchitectuur-proces.

Het koppelen van NSG's aan subnetten en netwerkinterfaces is een kritieke stap in de implementatie die bepaalt waar de netwerkfiltering wordt toegepast. Wanneer een NSG wordt gekoppeld aan een subnet, worden alle netwerkinterfaces binnen dat subnet automatisch beschermd door de NSG-regels. Deze koppeling wordt gemaakt op het subnet-object zelf en blijft actief zolang de koppeling bestaat, ongeacht of virtuele machines worden toegevoegd of verwijderd uit het subnet. Wanneer een NSG wordt gekoppeld aan een netwerkinterface, wordt alleen die specifieke interface beschermd door de NSG-regels. Deze koppeling wordt gemaakt op het netwerkinterface-object en blijft actief zolang de koppeling bestaat, zelfs wanneer de virtuele machine wordt verplaatst naar een ander subnet. Organisaties kunnen ook beide koppelingen combineren: een subnet-NSG voor algemene beveiliging en een interface-NSG voor workload-specifieke beveiliging. Wanneer beide zijn geconfigureerd, worden beide sets regels geëvalueerd en moet verkeer door beide NSG's worden toegestaan om te worden doorgestuurd.

Gebruik PowerShell-script network-security-groups.ps1 (functie Invoke-Remediation) – Automatiseert de implementatie van Network Security Groups, koppelt NSG's aan subnetten en netwerkinterfaces waar nodig, en valideert de implementatie..

Validatie en testing van NSG-implementaties zijn essentieel om te waarborgen dat NSG's correct zijn geïmplementeerd en dat netwerkconnectiviteit niet wordt verstoord. Na het aanmaken en koppelen van NSG's moeten organisaties verifiëren dat de NSG's daadwerkelijk zijn gekoppeld aan de bedoelde subnetten of netwerkinterfaces, dat de NSG-regels correct zijn geconfigureerd, en dat legitiem netwerkverkeer nog steeds werkt. Organisaties kunnen Azure Network Watcher gebruiken om de IP Flow Verify-functionaliteit te gebruiken die controleert of verkeer tussen specifieke bron- en doel-IP-adressen en poorten wordt toegestaan of geblokkeerd door NSG's. Deze validatie moet worden uitgevoerd voordat NSG's in productie worden gebruikt, en moet worden herhaald wanneer wijzigingen worden gemaakt aan NSG-regels of -koppelingen. Organisaties moeten ook testen of workloads nog steeds kunnen communiceren met benodigde services zoals Azure Storage, Azure SQL Database, of andere Azure-services, en of beheerconnectiviteit zoals RDP of SSH nog steeds werkt. Het testen moet worden uitgevoerd in een niet-productieomgeving wanneer mogelijk, en moet worden gedocumenteerd voor auditdoeleinden.

Architecturale best practices

Het gebruik van subnet-NSG's voor consistente beveiliging op subnetniveau is een best practice die zorgt voor uniforme beveiliging voor alle workloads binnen een subnet. Subnet-NSG's zijn ideaal wanneer alle workloads binnen een subnet vergelijkbare beveiligingsvereisten hebben, zoals een subnet voor web servers die allemaal toegankelijk moeten zijn vanaf internet op poort 80 en 443, of een subnet voor databases die alleen toegankelijk moeten zijn vanaf applicatieservers. Deze aanpak vereenvoudigt beheer omdat beveiligingsregels centraal worden gedefinieerd en toegepast, vermindert de kans op configuratiefouten door consistente configuraties, en maakt het gemakkelijker om wijzigingen door te voeren omdat regels op één plek worden beheerd. Subnet-NSG's zijn ook kosteneffectief omdat er minder NSG's nodig zijn: één NSG per subnet in plaats van één NSG per virtuele machine. Organisaties moeten subnet-NSG's gebruiken als de standaard benadering en alleen interface-NSG's toevoegen wanneer specifieke workloads unieke beveiligingsvereisten hebben die niet kunnen worden geadresseerd op subnetniveau.

Het implementeren van gelaagde beveiliging met zowel subnet- als interface-NSG's biedt extra beveiliging maar vereist zorgvuldige planning en coördinatie. In een gelaagde aanpak worden subnet-NSG's gebruikt voor algemene beveiligingsregels die van toepassing zijn op alle workloads, zoals het blokkeren van verkeer vanaf internet naar alle workloads, of het toestaan van verkeer tussen subnetten binnen hetzelfde Virtual Network. Interface-NSG's worden gebruikt voor specifieke beveiligingsregels die alleen van toepassing zijn op individuele workloads, zoals het toestaan van RDP-verkeer naar een specifieke virtuele machine vanaf een beheerders-IP-adres, of het blokkeren van uitgaand verkeer naar specifieke bestemmingen voor een specifieke workload. Wanneer beide NSG's zijn geconfigureerd, worden beide sets regels geëvalueerd: verkeer moet door beide NSG's worden toegestaan om te worden doorgestuurd. Dit betekent dat organisaties ervoor moeten zorgen dat regels in beide NSG's compatibel zijn en niet conflicteren, anders kan legitiem verkeer per ongeluk worden geblokkeerd. De gelaagde aanpak verhoogt de beveiliging maar verhoogt ook de complexiteit, en organisaties moeten ervoor zorgen dat ze de interactie tussen subnet- en interface-NSG's volledig begrijpen voordat ze deze implementeren.

Het plannen van NSG-koppelingen voor verschillende scenario's vereist een diepgaand begrip van de netwerkarchitectuur en de communicatiepatronen tussen workloads. Voor nieuwe workloads moeten organisaties NSG's plannen als onderdeel van de initiële architectuur, waarbij NSG's worden aangemaakt en gekoppeld tijdens het deployment-proces. Voor bestaande workloads zonder NSG's moeten organisaties een migratieplan ontwikkelen dat NSG's toevoegt zonder netwerkconnectiviteit te verstoren. Dit vereist vaak een gefaseerde aanpak waarbij eerst NSG's worden aangemaakt met permissieve regels die alle bestaande verkeer toestaan, vervolgens NSG Flow Logs worden ingeschakeld om het daadwerkelijke verkeer te analyseren, en vervolgens regels worden aangescherpt op basis van de analyse. Voor workloads die worden verplaatst tussen subnetten moeten organisaties overwegen om interface-NSG's te gebruiken die met de workload meeverhuizen, in plaats van subnet-NSG's die specifiek zijn voor een subnet. Voor hybride scenario's waarbij Azure Virtual Networks zijn verbonden met on-premises netwerken moeten organisaties NSG's plannen die rekening houden met verkeer van en naar on-premises systemen, en moeten ze overwegen om NSG's te combineren met Azure Firewall voor geavanceerde netwerkfiltering.

Operationele overwegingen

Het begrijpen van NSG-limieten en -quota is belangrijk voor het plannen van NSG-implementaties en het voorkomen van onverwachte beperkingen. Azure heeft verschillende limieten voor NSG's die organisaties moeten kennen: per abonnement kunnen maximaal 5.000 NSG's worden aangemaakt, per NSG kunnen maximaal 1.000 beveiligingsregels worden gedefinieerd, per netwerkinterface kunnen maximaal twee NSG's worden gekoppeld (één subnet-NSG en één interface-NSG), en per Virtual Network kunnen NSG's worden gekoppeld aan maximaal 1.000 subnetten. Deze limieten zijn meestal voldoende voor de meeste organisaties, maar grote enterprise-omgevingen met honderden subnetten en duizenden virtuele machines moeten rekening houden met deze limieten bij het plannen van NSG-implementaties. Organisaties die tegen limieten aanlopen kunnen overwegen om NSG's te consolideren door meerdere subnetten te beschermen met dezelfde NSG wanneer ze vergelijkbare beveiligingsvereisten hebben, of door interface-NSG's te gebruiken in plaats van subnet-NSG's wanneer individuele workloads verschillende beveiligingsvereisten hebben. Azure biedt ook de mogelijkheid om limieten te verhogen via support requests, maar dit proces kan tijd kosten en is niet gegarandeerd.

Change management voor NSG-implementaties is cruciaal voor het voorkomen van netwerkonderbrekingen en het waarborgen van compliance. Alle wijzigingen aan NSG's, inclusief het aanmaken van nieuwe NSG's, het koppelen of ontkoppelen van NSG's, en het toevoegen of wijzigen van NSG-regels, moeten worden gedocumenteerd met informatie over wie de wijziging heeft aangevraagd, waarom de wijziging nodig is, welke risico's zijn geëvalueerd, en wie de wijziging heeft goedgekeurd. Voor productieomgevingen moeten wijzigingen eerst worden getest in een niet-productieomgeving om te verifiëren dat de wijzigingen werken zoals bedoeld en geen onbedoelde gevolgen hebben. Wijzigingen moeten worden gepland tijdens onderhoudsvensters wanneer mogelijk, en er moeten rollback-plannen zijn voor het geval een wijziging problemen veroorzaakt. Organisaties moeten ook overwegen om NSG-configuraties te versiebeheren via Infrastructure as Code, wat helpt bij het bijhouden van wijzigingen en het terugdraaien van problematische configuraties. Een changelog moet worden bijgehouden waarin alle wijzigingen worden vastgelegd, inclusief datum, tijd, persoon, reden en impact, voor auditdoeleinden en troubleshooting.

Het beheren van de NSG-levenscyclus is belangrijk voor het waarborgen van consistente beveiliging en het voorkomen van configuratiedrift. Organisaties moeten processen definiëren voor het aanmaken van nieuwe NSG's wanneer nieuwe subnetten of workloads worden toegevoegd, voor het bijwerken van bestaande NSG's wanneer beveiligingsvereisten wijzigen, en voor het verwijderen van ongebruikte NSG's wanneer subnetten of workloads worden verwijderd. Het gebruik van Infrastructure as Code kan helpen om de NSG-levenscyclus te automatiseren en consistentie te waarborgen, vooral wanneer NSG's deel uitmaken van grotere workload-deployments. Organisaties moeten ook overwegen om automatische validaties te implementeren die controleren of NSG's correct zijn gekoppeld aan alle relevante subnetten en netwerkinterfaces, of er ongebruikte NSG's zijn die kunnen worden verwijderd, en of NSG-configuraties voldoen aan beveiligingsbest practices. Deze validaties kunnen worden geïntegreerd in CI/CD-pipelines of kunnen worden uitgevoerd als onderdeel van regelmatige compliance-checks. Het bijbehorende PowerShell-script kan worden gebruikt om deze validaties uit te voeren en rapportages te genereren die helpen bij het beheren van de NSG-levenscyclus.

Integratie met andere Azure-services

Network Security Groups werken samen met andere Azure-beveiligingsservices om een gelaagde beveiligingsarchitectuur te creëren. Azure Firewall is een managed firewall-service die geavanceerde netwerkfiltering biedt op Virtual Network-niveau, inclusief stateful packet inspection, threat intelligence filtering, en FQDN filtering. NSG's en Azure Firewall vullen elkaar aan: NSG's bieden basis netwerkfiltering op subnet- en interface-niveau, terwijl Azure Firewall geavanceerde filtering biedt op Virtual Network-niveau. Organisaties kunnen NSG's gebruiken voor basic filtering tussen subnetten en workloads, terwijl Azure Firewall wordt gebruikt voor geavanceerde filtering van verkeer van en naar internet, of voor centraal beheer van uitgaand verkeer. Azure Network Watcher biedt tools voor het monitoren en diagnosticeren van netwerkproblemen, inclusief NSG Flow Logs die gedetailleerde informatie verzamelen over verkeer dat door NSG's wordt gecontroleerd. Network Watcher IP Flow Verify kan worden gebruikt om te testen of verkeer tussen specifieke bron- en doel-IP-adressen en poorten wordt toegestaan of geblokkeerd door NSG's, wat waardevol is voor troubleshooting en validatie.

Azure Monitor en Log Analytics bieden krachtige mogelijkheden voor het monitoren en analyseren van NSG-activiteiten. NSG Flow Logs kunnen worden doorgestuurd naar een Log Analytics-workspace waar ze kunnen worden geanalyseerd met KQL-queries om patronen te identificeren, afwijkingen te detecteren, en compliance-rapportages te genereren. Azure Monitor kan alertregels configureren die waarschuwingen genereren bij ongebruikelijke NSG-activiteiten, zoals plotselinge toename van geblokkeerd verkeer, herhaalde pogingen tot toegang tot geblokkeerde poorten, of verkeer van bekende kwaadaardige IP-adressen. Deze alerts kunnen worden geïntegreerd met incident response-processen om snelle reactie op bedreigingen mogelijk te maken. Azure Security Center en Azure Defender voor Cloud bieden geavanceerde security analytics die NSG-configuraties analyseren en aanbevelingen doen voor het verbeteren van netwerkbeveiliging. Deze services kunnen ook automatische remediatie uitvoeren wanneer onveilige NSG-configuraties worden gedetecteerd, zoals het toevoegen van default deny-regels of het aanscherpen van overbrede regels.

Azure Policy kan worden gebruikt om NSG-implementaties te standaardiseren en te waarborgen dat alle NSG's voldoen aan beveiligingsbest practices. Organisaties kunnen policies definiëren die vereisen dat alle subnetten zijn gekoppeld aan een NSG, dat alle NSG's bepaalde regels bevatten (bijvoorbeeld default deny-regels), of dat NSG's worden aangemaakt met specifieke tags of metadata. Deze policies kunnen worden toegepast op abonnements- of management group-niveau om ervoor te zorgen dat alle resources binnen de scope voldoen aan de gestelde eisen. Azure Policy biedt ook de mogelijkheid om automatische remediatie uit te voeren wanneer niet-compliant configuraties worden gedetecteerd, bijvoorbeeld door automatisch NSG's aan te maken en te koppelen wanneer subnetten worden aangemaakt zonder NSG's. Deze geautomatiseerde aanpak vermindert de werklast voor IT-teams en zorgt voor consistente beveiliging, zelfs wanneer er frequente wijzigingen zijn aan de cloudomgeving. Organisaties kunnen ook custom policies ontwikkelen die specifiek zijn voor hun beveiligingsvereisten en compliance-frameworks, wat waardevol is voor het waarborgen van consistentie met interne standaarden en externe reguleringen.

Compliance & Frameworks

Automation

Gebruik het onderstaande PowerShell script om deze security control te monitoren en te implementeren. Het script bevat functies voor zowel monitoring (-Monitoring) als remediation (-Remediation).

PowerShell
<# .SYNOPSIS Azure Network Security Groups Implementatie en Validatie .DESCRIPTION Dit script ondersteunt Nederlandse overheidsorganisaties bij het implementeren en valideren van Network Security Groups (NSG's) in Azure-omgevingen. Het script controleert of NSG's zijn geïmplementeerd voor alle relevante subnetten en netwerkinterfaces, automatiseert de implementatie van ontbrekende NSG's, en genereert implementatie- en validatierapportages. Het script is ontworpen om veilig lokaal of vanuit een beheerde automation-runner te draaien met READ-ONLY rechten voor monitoring, en met beperkte schrijfrechten voor remediatie. Het voert implementatiewijzigingen alleen uit na expliciete bevestiging of in WhatIf-modus. .NOTES Filename: network-security-groups.ps1 Author: Nederlandse Baseline voor Veilige Cloud Created: 2025-01-28 Version: 1.0 Related JSON: content/azure/network/network-security-groups.json Category: network Workload: azure .LINK https://github.com/m365-tenant-best-practise .EXAMPLE .\network-security-groups.ps1 -Monitoring Voert een read-only validatie uit van alle NSG-implementaties en toont een samenvatting van de huidige status. .EXAMPLE .\network-security-groups.ps1 -Remediation -WhatIf Genereert een rapport met concrete aanbevelingen zonder wijzigingen aan te brengen. .EXAMPLE .\network-security-groups.ps1 -Remediation Implementeert ontbrekende NSG's en koppelt ze aan subnetten en netwerkinterfaces. #> #Requires -Version 5.1 #Requires -Modules Az.Accounts, Az.Network, Az.Resources [CmdletBinding()] param( [Parameter(HelpMessage = "Voer een read-only validatie uit van alle Network Security Group-implementaties")] [switch]$Monitoring, [Parameter(HelpMessage = "Implementeer ontbrekende NSG's en koppel ze aan subnetten en netwerkinterfaces")] [switch]$Remediation, [Parameter(HelpMessage = "Draai implementatiewijzigingen terug (indien mogelijk)")] [switch]$Revert, [Parameter(HelpMessage = "Toon welke acties zouden worden uitgevoerd zonder deze echt uit te voeren")] [switch]$WhatIf, [Parameter(HelpMessage = "Optioneel pad om resultaten als JSON te exporteren")] [string]$ExportPath ) $ErrorActionPreference = 'Stop' # ============================================================================ # HEADER # ============================================================================ Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "Azure NSG Implementatie – Validatie" -ForegroundColor Cyan Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan # ============================================================================ # HULPFUNCTIES # ============================================================================ function Connect-NbvvcAzContext { <# .SYNOPSIS Zorgt voor een geldige Az-context voor leesacties .DESCRIPTION Probeert eerst een bestaande context te gebruiken. Als er geen context is, wordt Connect-AzAccount aangeroepen. Dit is geschikt voor lokale debug- scenario's met een interactieve sessie of een managed identity. #> [CmdletBinding()] param() try { $context = Get-AzContext -ErrorAction SilentlyContinue if (-not $context) { Write-Host "Geen actieve Azure-context gevonden. Probeer te verbinden..." -ForegroundColor Yellow Connect-AzAccount -ErrorAction Stop | Out-Null $context = Get-AzContext -ErrorAction Stop } Write-Host "Actieve Azure-context: $($context.Subscription.Name) [$($context.Subscription.Id)]" -ForegroundColor Gray return $context } catch { Write-Host "[FAIL] Kon geen geldige Azure-context verkrijgen: $_" -ForegroundColor Red throw } } function Get-NbvvcNSGImplementationStatus { <# .SYNOPSIS Verzamelt de implementatiestatus van Network Security Groups .DESCRIPTION Haalt de implementatiestatus op van NSG's, controleert welke subnetten en netwerkinterfaces zijn gekoppeld aan NSG's, identificeert ontbrekende NSG's, en genereert een overzicht van de huidige implementatie. .OUTPUTS Hashtable met NSG-implementatiestatus per component #> [CmdletBinding()] param() $status = @{ timestamp = Get-Date subscriptionId = (Get-AzContext).Subscription.Id networkSecurityGroups = @{ totalCount = 0 nsgDetails = @() } subnets = @{ totalCount = 0 withNSGCount = 0 withoutNSGCount = 0 subnetDetails = @() } networkInterfaces = @{ totalCount = 0 withNSGCount = 0 withoutNSGCount = 0 interfaceDetails = @() } findings = @() } Write-Host "`nValidatie van Network Security Group-implementaties (read-only)..." -ForegroundColor Yellow # NSG's - Inventariseer alle Network Security Groups try { $nsgs = Get-AzNetworkSecurityGroup -ErrorAction SilentlyContinue $status.networkSecurityGroups.totalCount = $nsgs.Count Write-Host " Network Security Groups: $($nsgs.Count) gevonden" -ForegroundColor Gray foreach ($nsg in $nsgs) { $nsgDetail = @{ name = $nsg.Name resourceGroup = $nsg.ResourceGroupName location = $nsg.Location id = $nsg.Id ruleCount = ($nsg.SecurityRules | Measure-Object).Count associatedSubnets = @() associatedInterfaces = @() } $status.networkSecurityGroups.nsgDetails += $nsgDetail } if ($nsgs.Count -eq 0) { $status.findings += "Geen Network Security Groups gevonden; overweeg implementatie voor netwerkbeveiliging." } } catch { Write-Host " [WARN] Kon NSG's niet volledig inventariseren: $_" -ForegroundColor Yellow $status.findings += "Kon NSG's niet volledig inventariseren; controleer rechten en Az.Network-module." } # Subnetten - Controleer welke subnetten NSG's hebben try { $vnets = Get-AzVirtualNetwork -ErrorAction SilentlyContinue $allSubnets = @() foreach ($vnet in $vnets) { foreach ($subnet in $vnet.Subnets) { $subnetDetail = @{ name = $subnet.Name virtualNetwork = $vnet.Name resourceGroup = $vnet.ResourceGroupName id = $subnet.Id hasNSG = $false nsgId = $null nsgName = $null } if ($subnet.NetworkSecurityGroup) { $subnetDetail.hasNSG = $true $subnetDetail.nsgId = $subnet.NetworkSecurityGroup.Id $subnetDetail.nsgName = ($subnet.NetworkSecurityGroup.Id -split '/')[-1] $status.subnets.withNSGCount++ } else { $status.subnets.withoutNSGCount++ } $allSubnets += $subnetDetail } } $status.subnets.totalCount = $allSubnets.Count $status.subnets.subnetDetails = $allSubnets Write-Host " Subnetten: $($status.subnets.totalCount) gevonden" -ForegroundColor Gray Write-Host " Met NSG: $($status.subnets.withNSGCount)" -ForegroundColor $(if ($status.subnets.withNSGCount -eq $status.subnets.totalCount) { "Green" } else { "Yellow" }) Write-Host " Zonder NSG: $($status.subnets.withoutNSGCount)" -ForegroundColor $(if ($status.subnets.withoutNSGCount -eq 0) { "Green" } else { "Red" }) if ($status.subnets.withoutNSGCount -gt 0) { $status.findings += "$($status.subnets.withoutNSGCount) subnet(ten) zonder NSG gevonden; overweeg implementatie voor netwerkbeveiliging." } } catch { Write-Host " [WARN] Kon subnetten niet volledig inventariseren: $_" -ForegroundColor Yellow $status.findings += "Kon subnetten niet volledig inventariseren; controleer rechten en Az.Network-module." } # Netwerkinterfaces - Controleer welke interfaces NSG's hebben try { $nics = Get-AzNetworkInterface -ErrorAction SilentlyContinue $status.networkInterfaces.totalCount = $nics.Count Write-Host " Netwerkinterfaces: $($nics.Count) gevonden" -ForegroundColor Gray foreach ($nic in $nics) { $nicDetail = @{ name = $nic.Name resourceGroup = $nic.ResourceGroupName id = $nic.Id hasNSG = $false nsgId = $null nsgName = $null vmName = $null } if ($nic.VirtualMachine) { $nicDetail.vmName = ($nic.VirtualMachine.Id -split '/')[-1] } if ($nic.NetworkSecurityGroup) { $nicDetail.hasNSG = $true $nicDetail.nsgId = $nic.NetworkSecurityGroup.Id $nicDetail.nsgName = ($nic.NetworkSecurityGroup.Id -split '/')[-1] $status.networkInterfaces.withNSGCount++ } else { $status.networkInterfaces.withoutNSGCount++ } $status.networkInterfaces.interfaceDetails += $nicDetail } Write-Host " Met NSG: $($status.networkInterfaces.withNSGCount)" -ForegroundColor $(if ($status.networkInterfaces.withNSGCount -eq $status.networkInterfaces.totalCount) { "Green" } else { "Yellow" }) Write-Host " Zonder NSG: $($status.networkInterfaces.withoutNSGCount)" -ForegroundColor $(if ($status.networkInterfaces.withoutNSGCount -eq 0) { "Green" } else { "Yellow" }) if ($status.networkInterfaces.withoutNSGCount -gt 0) { Write-Host " [INFO] Interface-NSG's zijn optioneel; subnet-NSG's hebben prioriteit." -ForegroundColor Gray } } catch { Write-Host " [WARN] Kon netwerkinterfaces niet volledig inventariseren: $_" -ForegroundColor Yellow $status.findings += "Kon netwerkinterfaces niet volledig inventariseren; controleer rechten en Az.Network-module." } return $status } function Invoke-Monitoring { <# .SYNOPSIS Voert een read-only NSG-implementatievalidatie uit .DESCRIPTION Gebruikt implementatiecontroles om inzicht te geven in de huidige NSG-implementaties per component. Dit helpt bij het prioriteren van implementatietrajecten en het identificeren van ontbrekende NSG's. .OUTPUTS Hashtable met samenvattende metrics en status per component #> [CmdletBinding()] param() $null = Connect-NbvvcAzContext $status = Get-NbvvcNSGImplementationStatus Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "SAMENVATTING NSG IMPLEMENTATIE STATUS" -ForegroundColor Cyan Write-Host "`n Network Security Groups:" -ForegroundColor Yellow Write-Host " Totaal aantal NSG's : $($status.networkSecurityGroups.totalCount)" -ForegroundColor Gray Write-Host "`n Subnetten:" -ForegroundColor Yellow Write-Host " Totaal aantal : $($status.subnets.totalCount)" -ForegroundColor Gray Write-Host " Met NSG : $($status.subnets.withNSGCount)" -ForegroundColor $(if ($status.subnets.withNSGCount -eq $status.subnets.totalCount -and $status.subnets.totalCount -gt 0) { "Green" } else { "Yellow" }) Write-Host " Zonder NSG : $($status.subnets.withoutNSGCount)" -ForegroundColor $(if ($status.subnets.withoutNSGCount -eq 0) { "Green" } else { "Red" }) Write-Host "`n Netwerkinterfaces:" -ForegroundColor Yellow Write-Host " Totaal aantal : $($status.networkInterfaces.totalCount)" -ForegroundColor Gray Write-Host " Met NSG : $($status.networkInterfaces.withNSGCount)" -ForegroundColor Gray Write-Host " Zonder NSG : $($status.networkInterfaces.withoutNSGCount)" -ForegroundColor Gray if ($status.subnets.subnetDetails.Count -gt 0 -and $status.subnets.withoutNSGCount -gt 0) { Write-Host "`n Subnetten zonder NSG:" -ForegroundColor Yellow foreach ($subnet in ($status.subnets.subnetDetails | Where-Object { -not $_.hasNSG })) { Write-Host " - $($subnet.name) in $($subnet.virtualNetwork) ($($subnet.resourceGroup))" -ForegroundColor Red } } $allFindings = @() $allFindings += $status.findings if ($allFindings.Count -gt 0) { Write-Host "`nAandachtspunten:" -ForegroundColor Yellow foreach ($f in $allFindings) { Write-Host " - $f" -ForegroundColor Yellow } } else { Write-Host "`nGeen specifieke aandachtspunten gedetecteerd op basis van deze scan." -ForegroundColor Green } return @{ status = $status } } function Invoke-Remediation { <# .SYNOPSIS Implementeert ontbrekende NSG's en koppelt ze aan subnetten .DESCRIPTION Op basis van de implementatievalidatie worden ontbrekende NSG's geïdentificeerd en geïmplementeerd. Het script voert implementatiewijzigingen alleen uit na expliciete bevestiging of in WhatIf-modus. #> [CmdletBinding(SupportsShouldProcess)] param() if ($WhatIf) { Write-Host "`nWhatIf: er wordt een implementatieplan gegenereerd op basis van validatie, maar er vinden geen wijzigingen plaats." -ForegroundColor Yellow } $result = Invoke-Monitoring $status = $result.status $recommendations = @() $actions = @() # Identificeer subnetten zonder NSG $subnetsWithoutNSG = $status.subnets.subnetDetails | Where-Object { -not $_.hasNSG } if ($subnetsWithoutNSG.Count -gt 0) { $recommendations += "Implementeer NSG's voor $($subnetsWithoutNSG.Count) subnet(ten) zonder NSG-beveiliging." foreach ($subnet in $subnetsWithoutNSG) { $nsgName = "nsg-$($subnet.virtualNetwork)-$($subnet.name)" $action = @{ Type = "CreateNSG" NSGName = $nsgName SubnetName = $subnet.name VirtualNetwork = $subnet.virtualNetwork ResourceGroup = $subnet.resourceGroup } $actions += $action if ($WhatIf) { Write-Host "`n WHAT IF: Zou NSG '$nsgName' aanmaken en koppelen aan subnet '$($subnet.name)' in VNet '$($subnet.virtualNetwork)'" -ForegroundColor Cyan } else { Write-Host "`n Implementeer NSG voor subnet: $($subnet.name) in $($subnet.virtualNetwork)" -ForegroundColor Gray try { # Controleer of NSG al bestaat $existingNSG = Get-AzNetworkSecurityGroup -ResourceGroupName $subnet.resourceGroup -Name $nsgName -ErrorAction SilentlyContinue if (-not $existingNSG) { if ($PSCmdlet.ShouldProcess($nsgName, "Maak Network Security Group aan")) { $nsg = New-AzNetworkSecurityGroup ` -ResourceGroupName $subnet.resourceGroup ` -Location (Get-AzResourceGroup -ResourceGroupName $subnet.resourceGroup).Location ` -Name $nsgName ` -ErrorAction Stop Write-Host " NSG aangemaakt: $($nsg.Name)" -ForegroundColor Green } } else { Write-Host " NSG bestaat al: $nsgName" -ForegroundColor Gray $nsg = $existingNSG } # Koppel NSG aan subnet if ($PSCmdlet.ShouldProcess($subnet.name, "Koppel NSG aan subnet")) { $vnet = Get-AzVirtualNetwork -ResourceGroupName $subnet.resourceGroup -Name $subnet.virtualNetwork -ErrorAction Stop $subnetObj = $vnet.Subnets | Where-Object { $_.Name -eq $subnet.name } $subnetObj.NetworkSecurityGroup = $nsg $vnet | Set-AzVirtualNetwork -ErrorAction Stop | Out-Null Write-Host " NSG gekoppeld aan subnet: $($subnet.name)" -ForegroundColor Green } } catch { Write-Host " [ERROR] Kon NSG niet implementeren voor subnet $($subnet.name): $_" -ForegroundColor Red } } } } else { $recommendations += "Alle subnetten hebben NSG's gekoppeld; geen implementatie-acties vereist." } Write-Host "`nAanbevolen vervolgstappen:" -ForegroundColor Cyan foreach ($rec in $recommendations) { Write-Host " - $rec" -ForegroundColor White } $report = @{ generatedAt = Get-Date subscriptionId = $status.subscriptionId recommendations = $recommendations plannedActions = $actions status = $status } if ($ExportPath) { if ($PSCmdlet.ShouldProcess($ExportPath, "Schrijf NSG-implementatie rapport naar JSON-bestand")) { $report | ConvertTo-Json -Depth 6 | Out-File -FilePath $ExportPath -Encoding UTF8 Write-Host "`n[OK] Rapport geschreven naar: $ExportPath" -ForegroundColor Green } } } function Invoke-Revert { <# .SYNOPSIS Draai implementatiewijzigingen terug .DESCRIPTION Dit script voert implementatiewijzigingen alleen uit na expliciete bevestiging. Revert-functionaliteit is beperkt omdat NSG-koppelingen complex zijn en handmatige interventie vereisen. De functie is aanwezig voor consistentie met andere scripts binnen de Nederlandse Baseline voor Veilige Cloud. #> [CmdletBinding(SupportsShouldProcess)] param() Write-Host "`nNSG-implementaties vereisen handmatige interventie voor revert-operaties." -ForegroundColor Yellow Write-Host "Raadpleeg de documentatie en Azure-portal voor specifieke revert-stappen per component." -ForegroundColor Gray } # ============================================================================ # MAIN EXECUTION # ============================================================================ try { if ($Revert) { Invoke-Revert } elseif ($Remediation) { Invoke-Remediation } elseif ($Monitoring) { $null = Invoke-Monitoring } else { Write-Host "Beschikbare parameters:" -ForegroundColor Yellow Write-Host " -Monitoring : Voer een read-only NSG-implementatievalidatie uit" -ForegroundColor Gray Write-Host " -Remediation : Implementeer ontbrekende NSG's en koppel ze aan subnetten" -ForegroundColor Gray Write-Host " -Revert : Beperkte revert-functionaliteit (handmatige interventie vereist)" -ForegroundColor Gray Write-Host " -WhatIf : Toon welke acties logisch zouden zijn zonder uitvoer" -ForegroundColor Gray Write-Host " -ExportPath : Optioneel pad voor JSON-rapport" -ForegroundColor Gray Write-Host "`nVoorbeeld: .\network-security-groups.ps1 -Monitoring" -ForegroundColor Cyan } } catch { Write-Error "Scriptuitvoering mislukt: $_" exit 2 } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan } # Exitcodes: # 0 = Succesvolle uitvoering # 2 = Fout tijdens uitvoering

Risico zonder implementatie

Risico zonder implementatie
Critical: Het ontbreken van Network Security Groups in Azure-omgevingen creëert kritieke beveiligingsgaten die kunnen leiden tot ernstige gevolgen. Zonder NSG-filtering kunnen aanvallers die toegang krijgen tot een virtuele machine zich lateraal door het netwerk bewegen zonder beperkingen, kunnen ze ongeautoriseerde toegang krijgen tot gevoelige data, kunnen ze command-and-control verkeer opzetten zonder detectie, en kunnen ze andere workloads binnen hetzelfde Virtual Network compromitteren. In een hybride scenario waarbij Azure Virtual Networks zijn verbonden met on-premises netwerken kan het ontbreken van NSG's ook leiden tot onbeperkte toegang van on-premises systemen naar cloudworkloads. Voor Nederlandse overheidsorganisaties is het ontbreken van NSG-filtering bovendien een directe schending van compliance-vereisten: BIO norm 13.01, ISO 27001:2022 controle A.8.20 en NIS2 artikel 21 vereisen allemaal netwerkbeveiliging. Tijdens audits zal het ontbreken van NSG's worden gezien als een kritieke tekortkoming die kan leiden tot negatieve auditbevindingen, mogelijke boetes en reputatieschade.

Management Samenvatting

Network Security Groups vormen de fundamentele beveiligingslaag voor netwerkverkeer in Azure Virtual Networks en zijn een verplichte maatregel voor elke Azure-omgeving die voldoet aan security best practices en compliance-frameworks. Door NSG's te implementeren op subnet- en interface-niveau, een gelaagde beveiligingsarchitectuur te creëren, en NSG's te integreren met Azure Firewall, Network Watcher en Azure Monitor, worden netwerkaanvallen vroegtijdig geblokkeerd en wordt een solide basis gelegd voor netwerkbeveiliging. Het bijbehorende PowerShell-script automatiseert de implementatie van NSG's, valideert of NSG's zijn gekoppeld aan alle relevante subnetten en netwerkinterfaces, en genereert implementatierapportages. De benodigde inspanning is beperkt (circa 24 uur initiële implementatie), terwijl de risicoreductie en compliance-waarde aanzienlijk zijn voor alle netwerkgebaseerde diensten in Azure.