Azure VNET

Intro
Netværk. Kedeligt tænker mange: det skal jo bare køre, og da det er i skyen, jamen så er der en anden der går med bipperen. Vi skal jo blot deploye noget kode. Realiteterne er dog en anden, og det opdager man typisk alt for sent. Selvom man er kommet i skyen, skal man stadig tage stilling til:
- Netværkssikkerhed
- Routing og styring af trafik
- Inddæmning af interne API'er, og
- Korrekt exposure af public API'er
Hvordan gør man det i Azure? Det har jeg kigget lidt nærmere på. Det her er ikke ment som en serie af blog indlæg, som kommer som pølser på en snor, men det er noget jeg vil blogge om fra tid til anden, og derfor starter jeg også med et intro
forløb, hvor terminologien bliver slået fast, og grundstenene lagt. Jeg vil i dette indlæg zoome ind på VNET, og hvordan man bruger det, og derefter snakke lidt om det store billede.
Lets get started.
VNET vs VNET integration
Det første vi skal have aflaret er at der eksisterer to dele:
- VNET
- VNET integration
Et VNET er et virtuelt netværk, med subnets, hvor resourcerne man propper i dem får tildelt en IP
fra en range af IP'ere. Alt der er i VNET'et kan snakke sammen. Har man fx en VPN gateway i sit VNET, kan de andre resourcer i samme VNET altså gøre brug af VPN forbindelsen, og derved nå onprem resourcer, eller resourcer i et andet VNET som er lokaliseret i en anden del af verden. En resource kunne fx være en VM
eller en database. De workloads der kører på disse resourcer vil altså kunne snakke sammen og finde hinanden. Meget smart. Hvad med webapps
, kan jeg HØRE dig tænke. Ja: hvad med dem. Kan man smide dem i et VNET
? Det korte, og næsten sande svar er: nej. Det lidt længere og diffuse svar er: tjaaaooo måske, men det kommer man på. Det tekniske svar er:
- for almindelige
webapps
kan man ikke - for
webapps
i en ASE, kan man godt
Men betydet det så at man slet ikke kan gøre brug af et VNET
når man har almindelige webapps? Det kan man godt: man kan integrerer en webapp med et VNET. Det er dog ikke det samme som at smide ens webapp
i et VNET
. Lad mig (låne nogen tegninger) tegne det.
VNET
Et VNET
består af:
- en eller flere subnet, som
- hver har nul eller flere
NSG'ere
De resourcer som befinder sig i VNET'et
får tildelt en IP
hver af den IP pulje
som er tildelt subnettet
ved oprettelse.
ARM
For at oprette et VNET
via en ARM
template skal man skrive følgende
{
"apiVersion": "2020-05-01",
"type": "Microsoft.Network/virtualNetworks",
"name": "vnet-test",
"location": "west europe",
"properties": {
"addressSpace": {
"addressPrefixes": [
"10.1.0.0/16"
]
},
"subnets": [
{
"name": "WebappSubnet",
"properties": {
"addressPrefix": "10.1.2.0/24",
"serviceEndpoints": [
{
"service": "Microsoft.Web"
}
],
"delegations": [
{
"name": "delegation",
"properties": {
"serviceName": "Microsoft.Web/serverFarms"
}
}
]
}
}
]
}
}
Mere skal der egentligt ikke til. Læg mærke til at jeg i det subnet jeg har oprettet, har delegeret subnettet til serverfarms. På den måde fortæller jeg subnettet at den skal kunne håndtere trafik fra webapps
. Bag om ryggen på os installeres der således en NSG
som sørger for at styre HTTP
trafik korrekt. Meget smart. Vi skal bruge den lige om lidt når vi skal integrere en webapp
ind i vores VNET
: der blev sagt INTEGRERES!! Djævlen er i detaljen.
bonus info: det er faktisk delegationen der teknisk set er integrationsdelen i VNET /integration/
, da det er den som sørger for at bestemte typer af trafik kan integrerer ind i VNET'et
. SPÆNDENDE!!
VNET integration
Her skal man bide mærke i:
- Ens
webapps
ligger udenfor det defineredeVNET
. De webapps man har integrerer sig ind iVNET'et
via et dedikeret subnet (som er provisioneret med henblik på at styre trafik frawebapps
hvilket betyder at der er opsat nogleNSG'ere
som hjælper med at styre trafikken) - Bemærk at trafikken fra
internettet
rammer de integreredewebapps
før de rammer voresVNET
hvilket betyder at man ikke kan styre indadgående trafik medNSG'ere
, men kun trafik som forlader voresVNET
. Det er en meget vigtig pointe: man kan IKKE lukke af for indadgående trafik. Vil man lukke for indadgående trafik kan man heldigvis brugeaccess restrictions
på dewebapps
man gerne vil skærme af. Husk dog: webapp'en har stadig en offentlig IP, men man har blot fortalt den LB'er der ligger foranwebapp'en
at den kun må modtage trafik som er hevet gennemVNET'et
- Er ens
webapp
først integreret kan man tilgå alle resourcer på tværs af subnets: det betyder at man kan gøre brug af deVPN'ere
der er sat op, eller de databaser som kun er tilgængelig i det pågældendeVNET
ARM
For at få en webapp
til at integrere op mod et VNET
skal man fortælle webapp'en
hvad for VNET
resource id den skal tilknyttes
{
"apiVersion": "2020-06-01",
"name": "webappname",
"type": "Microsoft.Web/sites",
"location": "west europe",
"properties": {
"name": "webappname",
"siteConfig": {
"appSettings": [
],
"ipSecurityRestrictions": [
{
"name": "webappSubnetAllowRule",
"priority": "1",
"action": "Allow",
"vnetSubnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'virtual network name', 'WebappSubnet')]"
}
],
},
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', 'hosting plan name']"
},
"resources": [
{
"name": "virtualNetwork",
"type": "networkConfig",
"apiVersion": "2019-08-01",
"dependsOn": [
"[parameters('webappName')]"
],
"properties": {
"subnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'virtual network name', 'WebappSubnet')]",
"swiftSupported": true
}
}
]
}
Jeg har tilladt mig at lade en ipSecurityRestrictions
blive, så I også kan se hvordan sådan en ser ud. Der er nogle vigtige deltajer her:
- HUSK
swiftSupported: true
ellers vil integrationen ikke virke. Jeg har endnu ikke fundet ud af hvorfor - HUSK for guds skyld at smide security restrictions på SCM sitet, hvis det i sandheden skal være sikkert (dog skal man også huske på at det giver uforudsete problemer med deploys). Mange tror at hele sitet er lukket af bare man smider det på produktions slottet, men det er det ikke, da SCM sitet stadig kan tilgåes
- HUSK: har man flere slots tilknytttet, så skal man også integrere disse
Man har nu fået:
- et
VNET
, og - en
webapp
som integrerer med den
Man kan nu begynde at bruge fx ip restrictions
og afskærme ens indkommende trafik til webapp'en, og skærme den af for omverdenen, eller tilgå VPN
forbindelsen, som måske ligger i VNET'et
. Wild world indeed!!
De sidste bemærkninger
Det er svært at ramme rigtigt, og det kræver meget planlægning, specielt hvis man gerne vil gøre det ordentligt, og jeg vil sige at hvis man gerne vil lave det helt rigtigt, så kræver det:
- et
ASE
miljø - en dedikeret VM med en DevOps agent, som man kan deploye til
Det overstående giver to udfordringer:
- Man har en VM, som skal holdes ved lige, og det kræver meget konfiguration. Azure har utrolig mange lag beskyttelse for
VMs
, dog er det alle nogen man selv skal aktivere. Jeg vil tro jeg kunne skrive en hel serie bare omkring sikkerhed omVMs
, men det må blive en anden gang - Pris: Når man hiver
ASE
ind i stakken, så stiger prisen også, man får dig et dedikeretVNET
, som man kan bruge som ens webapp ligger i, og man er derfor foruden at skulle laveipRestrictions
påSCM
sites,slots
osv
At lave ordentlig sikkerhed i Azure er altså i bund og grund ikke mere anderledes end sikkerhed onprem: det er dyrt at gøre ordentligt. Man har dog flere stykker værktøj til rådighed i Azure (og for den sags skyld i de andre cloud tjenester).
Jeg har nu dækket to dele af netværket i Azure (faktisk kun en, VNET
), men der er mange flere knapper og dimser man kan hive for at
- få mere fart på (vil du ikke gerne have at alt dit trafik smutter på Azure backbone fx?)
- mere sikkerhed (vil du ikke gerne have at alt dit trafik ikke bliver routed ud på det store
Internet
?)
Enhver med respekt for sig selv vil svare jo til overstående, men igen: det kommer med en pris: 1) penge 2) der er sindssygt meget man skal have styr på. Disse dimser og knapper ligner derfor også meget onprem
verdenen. Azure giver dig kassen, og et færdigbygget skelet, som nemt kan servere data på Internettet
(de får noget egress og ingress, og tjener penge, og du får kassen som du kan vælge fra), og det er nu din opgave at gøre det sikkert, og stabilt. Du skal læse lige så meget op på lektien som man skulle i vores gode, gamle, kære onprem
verden.
Jeg vil i de efterfølgende afsnit opridse nogle af de andre dimser, som man kan hive ind. Disse dimer og dingenoter er nogen jeg vil blogge om senere: for nu, vil jeg blot nævne dem (så kan du jo selv gå igang). Meget af koden (undtagen ASE
og VM
) er at finde i linket til sidst i artiklen, så kan du jo selv tage et kig. Husk: KeyVault
er noget jeg selv personlig spinner op med nogle scripts, indtil access permissions bliver behandlet ordentligt når man opretter en KeyVault
via en ARM
template. Mere om det i et andet indlæg.
Ready? Detroit, New York, du er (Mandril joke - se det).
Private link
Et private link
er et sæt af resourcer som man kan bruge til at binde en Azure resource, fx en Azure SQL
database, eller en storage account, og et VNET
sammen med. Man opnår derved at at databasen eller det storage man har, får en privat IP fra VNET
puljen, i stedet for at den URI
en database eller en storage account har, bliver resolved til en offentlig IP.
Teknisk set sker der det at:
- der oprettes en
NIC
som placeres iVNET'et
og binder sig til fx databasen eller storage account'en i den anden ende - Der oprettes en private
DNS zone
som sørger for at resolve den interneIP
når den givneURI
skal slåes op, i stedet for den offentligeIP
.
Man opnår derved at alt trafikken travasere over Azures backbone, og aldrig kommer ud på Internettet
. En bonus her er at man også undgår SNAT exhaustion (https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-outbound-connections#exhausting-ports), noget du sikkert har oplevet uden du ved det, da man undgår at gå gennem "den store LB'er
", som fronter hele Azure (der jo kun en, og du ved det jo godt - computeren ovre i hjørnet som har påklistret production :)).
Service endpoint
Det er nu det bliver lidt krads, fordi en Service Endpoint er næsten det samme som et private link
, næsten. Når man opretter en service endpoint i et VNET, sørger man for at resourcerne som kører ind i dette subnet:
- får en privat IP tildelt, og
- trafikken bliver tagget, og derved identificerbar, hvilket gør at man kan bygge firewall regler op på baggrund af denne information (bla med de føromtalte
ip restrictions
på enwebapp
)
Man bruger derfor service endpoints til at sørge for at trafikken ikke går ud på Internettet
, og at man kan identificere trafikken efterfølgende. Det er blandt andet sådan man laver ip restrictions: man fortæller at man kun tillader trafik fra specifikke subnets. Disse subnets skal have en service endpoint enabled. Som man kan se på tegningen betyder det at man, på de resourcer som har en firewall til rådighed (fx en webapp, en storage account eller en SQL server), kan sige: denne og denne trafik må gerne gå igennem til mig, mens alt andet trafik ikke må.
Det lyder unægtelig meget som private links
, dog er der den forskel at man
- skal have et subnet til hver gruppe af resourcer
- man kan ikke bruge private peering fra onprem og op på den private ip som bliver tildelt
der er nok andre forskellige også, men disse to er de væsentlige. Med private links
kan man forbinde onprem med skyen, og man sørger faktisk for at man med private links
giver den givne resource en ny privat ip fra ens VNET pulje: med service endpoints er det lidt mere skjult, og resourcen har stadig en public ip.
Rent sikkerhedsmæssig bør man vælge private links hvor end man kan, dog er service endpoints
gode til at skærme trafik. private links
er stadig så ny en fætter i Azure, at man nogen gange bliver nød både at have service endpoints, og private links, for at få det hele til at spille (bla hvis man skal lukke en storage account ordentligt af).
Rent faktisk har jeg et helt indlæg omkring service endpoint vs private links, som kan læses her: https://bl0g.dev/post/arm/service-endpoints-vs-private-links/.
ASE (og alt det andet: VM, DevOps og KeyVault)
Den dyre elefant, som giver hele paletten. Her bevæger vi os væk fra delegation og VNET integration
og får fuld power på. Der er to typer:
- en intern og
- en ekstern
Detaljerne vil jeg gemme til en anden dag, men i bund og grund handler det om, om man vil have en offentlig IP eller ej. Med en ASE
får man flere ting:
- dedikeret jern
- mere af alt
- og et RIGTIGT VNET til ens resourcer (det vil sige: de webapps man har ligger rent faktisk indeni
VNET
)
da resourcerne nu ligger inde i selve VNET'et
kan man nu bruge NSG'ere
til at styre både indgående og udgående trafik. Ens webapps har også fået en intern IP. Skal man lave det helt rigtige setup, med en KeyVault
og DevOps
er min klare anbefaling at man køre med en ASE
som har deployet en VM
med en DevOps
byggeagent i sig, så man kan skærme sine webapps helt af (OGSÅ SCM
sitet). Når man har en dedikeret byggeagent, får den en IP og med denne IP kan man nu bruge KeyVault
fuldt ud, og lukke den helt ned.
Teknisk set har man mulighed for at lukke godt af for KeyVault'en
, og kun tillade trusted services
adgang til valuten. Vil man linke Azure DevOps og KeyVault
sammen er det mildest talt umuligt, hvis man kun kører med hosted byggeagenter, da Azure DevOps ikke er en trusted service set med KeyVaults
øjne, og det er den ikke af den simple grund, at Microsoft ikke kan styre alt koden som er hosted i en DevOps
subscription (du kan jo selv smide scripts osv ind i dine pipelines). Derfor: få en dedikeret byggeagent og drag fuld udnytte af det ekstra sikkerhed det giver dig.
Nogen andet smart er også: har man en dedikeret byggeagent på en VM
, kan man smide VM'en
ind i et scaleset, og skalere ud når man laver mange deploys. Det er smart, i stedet for at betale for 10 byggeagtenter 24/7, så er det mere on demand. Det betyder dog også at man bliver nød til at vedligeholde byggeagtenten manuelt, og vedligeholde VM'en
, men det er nu en gang prisen man må betale, for at få mere sikkerhed (har du 10 byggeagtenter bør du dog kigge ind i VM og scaleset, da det faktisk godt kan gå hen og være billigere i længden).
Closing up
Alt koden, som jeg blogger om i dette indlæg og i de fremtidige kan findes her: https://gitlab.com/mslot/cloud.network.security.
Det er vigtigt at man tager stilling til alle disse ting. Tager man hele paletten får man
- styring af trafik internt i Azure
- adgangsgivning baseret på trafik tagging
- afskærming af kritisk infrastruktur
- horisontal netværkssegmentering
- vertikal netværkssegmentering
Hvem vil ikke gerne have det?