Skip to content

Commit ed48aae

Browse files
Merge pull request #98893 from sivagudivadaz/update-kerberos-docs-with-sample-deployment
Update kerberos docs with sample deployment
2 parents c10f118 + 03f1374 commit ed48aae

File tree

1 file changed

+365
-0
lines changed

1 file changed

+365
-0
lines changed

articles/bastion/kerberos-authentication-portal.md

Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,371 @@ Once you have enabled Kerberos on your Bastion resource, you can verify that it'
6565
1. End the VM session.
6666
1. Connect to the target VM again using Bastion. Sign-in should succeed, indicating that Bastion used Kerberos (and not NTLM) for authentication.
6767

68+
## Quickstart: Setup Bastion with Kerberos - Resource Manager template
69+
70+
### Review the template
71+
72+
```
73+
{
74+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
75+
"contentVersion": "1.0.0.0",
76+
"parameters": {
77+
"location": {
78+
"defaultValue": "[resourceGroup().location]",
79+
"type": "string"
80+
},
81+
"defaultNsgName": {
82+
"type": "string",
83+
"defaultValue": "Default-nsg"
84+
},
85+
"VnetName": {
86+
"type": "string",
87+
"defaultValue": "myVnet"
88+
},
89+
"ClientVMName": {
90+
"defaultValue": "Client-vm",
91+
"type": "string"
92+
},
93+
"ServerVMName": {
94+
"defaultValue": "Server-vm",
95+
"type": "string"
96+
},
97+
"vmsize": {
98+
"defaultValue": "Standard_DS1_v2",
99+
"type": "string",
100+
"metadata": {
101+
"description": "VM SKU to deploy"
102+
}
103+
},
104+
"ServerVMUsername": {
105+
"type": "string",
106+
"defaultValue": "serveruser",
107+
"metadata": {
108+
"description": "Admin username on all VMs."
109+
}
110+
},
111+
"ServerVMPassword": {
112+
"type": "securestring",
113+
"metadata": {
114+
"description": "Admin password on all VMs."
115+
}
116+
},
117+
"SafeModeAdministratorPassword": {
118+
"type": "securestring",
119+
"metadata": {
120+
"description": "See https://learn.microsoft.com/en-us/powershell/module/addsdeployment/install-addsdomaincontroller?view=windowsserver2022-ps#-safemodeadministratorpassword"
121+
}
122+
},
123+
"ClientVMUsername": {
124+
"type": "string",
125+
"defaultValue": "clientuser",
126+
"metadata": {
127+
"description": "username on ClientVM."
128+
}
129+
},
130+
"ClientVMPassword": {
131+
"type": "securestring",
132+
"metadata": {
133+
"description": "password on ClientVM."
134+
}
135+
},
136+
"ServerVmImage": {
137+
"type": "object",
138+
"defaultValue": {
139+
"offer": "WindowsServer",
140+
"publisher": "MicrosoftWindowsServer",
141+
"sku": "2019-Datacenter",
142+
"version": "latest"
143+
}
144+
},
145+
"ClientVmImage": {
146+
"type": "object",
147+
"defaultValue": {
148+
"offer": "Windows",
149+
"publisher": "microsoftvisualstudio",
150+
"sku": "Windows-10-N-x64",
151+
"version": "latest"
152+
}
153+
},
154+
"publicIPAllocationMethod": {
155+
"type": "string",
156+
"defaultValue": "Static"
157+
},
158+
"BastionName": {
159+
"defaultValue": "Bastion",
160+
"type": "string"
161+
},
162+
"BastionPublicIPName": {
163+
"defaultValue": "Bastion-ip",
164+
"type": "string"
165+
}
166+
},
167+
"variables": {
168+
"DefaultSubnetId": "[concat(resourceId('Microsoft.Network/virtualNetworks', parameters('VnetName')), '/subnets/default')]",
169+
"ClientVMSubnetId": "[concat(resourceId('Microsoft.Network/virtualNetworks', parameters('VnetName')), '/subnets/clientvm-subnet')]",
170+
"DNSServerIpAddress": "10.16.0.4",
171+
"ClientVMPrivateIpAddress": "10.16.1.4"
172+
},
173+
"resources": [
174+
{
175+
"apiVersion": "2020-03-01",
176+
"name": "[parameters('VnetName')]",
177+
"type": "Microsoft.Network/virtualNetworks",
178+
"location": "[parameters('location')]",
179+
"properties": {
180+
"dhcpOptions": {
181+
"dnsServers": [ "[variables('DNSServerIpAddress')]" ]
182+
},
183+
"subnets": [
184+
{
185+
"name": "default",
186+
"properties": {
187+
"addressPrefix": "10.16.0.0/24"
188+
}
189+
},
190+
{
191+
"name": "clientvm-subnet",
192+
"properties": {
193+
"addressPrefix": "10.16.1.0/24"
194+
}
195+
},
196+
{
197+
"name": "AzureBastionSubnet",
198+
"properties": {
199+
"addressPrefix": "10.16.2.0/24"
200+
}
201+
}
202+
],
203+
"addressSpace": {
204+
"addressPrefixes": [
205+
"10.16.0.0/16"
206+
]
207+
}
208+
}
209+
},
210+
{
211+
"type": "Microsoft.Network/networkInterfaces",
212+
"apiVersion": "2018-10-01",
213+
"name": "[concat(parameters('ServerVMName'), 'Nic')]",
214+
"location": "[parameters('location')]",
215+
"dependsOn": [
216+
"[concat('Microsoft.Network/virtualNetworks/', parameters('VnetName'))]"
217+
],
218+
"properties": {
219+
"ipConfigurations": [
220+
{
221+
"name": "[concat(parameters('ServerVMName'), 'NicIpConfig')]",
222+
"properties": {
223+
"privateIPAllocationMethod": "Static",
224+
"privateIPAddress": "[variables('DNSServerIpAddress')]",
225+
"subnet": {
226+
"id": "[variables('DefaultSubnetId')]"
227+
}
228+
}
229+
}
230+
]
231+
}
232+
},
233+
{
234+
"type": "Microsoft.Compute/virtualMachines",
235+
"apiVersion": "2020-06-01",
236+
"name": "[parameters('ServerVMName')]",
237+
"location": "[parameters('location')]",
238+
"dependsOn": [
239+
"[concat('Microsoft.Network/networkInterfaces/', parameters('ServerVMName'), 'Nic')]"
240+
],
241+
"properties": {
242+
"hardwareProfile": {
243+
"vmSize": "[parameters('vmSize')]"
244+
},
245+
"osProfile": {
246+
"AdminUsername": "[parameters('ServerVMUsername')]",
247+
"AdminPassword": "[parameters('ServerVMPassword')]",
248+
"computerName": "[parameters('ServerVMName')]"
249+
},
250+
"storageProfile": {
251+
"imageReference": "[parameters('ServerVmImage')]",
252+
"osDisk": {
253+
"createOption": "FromImage",
254+
"managedDisk": {
255+
"storageAccountType": "Standard_LRS"
256+
}
257+
}
258+
},
259+
"networkProfile": {
260+
"networkInterfaces": [
261+
{
262+
"id": "[ResourceId('Microsoft.Network/networkInterfaces/', concat(parameters('ServerVMName'), 'Nic'))]"
263+
}
264+
]
265+
}
266+
}
267+
},
268+
{
269+
"type": "Microsoft.Compute/virtualMachines/extensions",
270+
"apiVersion": "2021-04-01",
271+
"name": "[concat(parameters('ServerVMName'),'/', 'PromoteToDomainController')]",
272+
"location": "[parameters('location')]",
273+
"dependsOn": [
274+
"[concat('Microsoft.Compute/virtualMachines/',parameters('ServerVMName'))]"
275+
],
276+
"properties": {
277+
"publisher": "Microsoft.Compute",
278+
"type": "CustomScriptExtension",
279+
"typeHandlerVersion": "1.7",
280+
"autoUpgradeMinorVersion": true,
281+
"settings": {
282+
"commandToExecute": "[concat('powershell.exe -Command \"Install-windowsfeature AD-domain-services; Import-Module ADDSDeployment;$Secure_String_Pwd = ConvertTo-SecureString ',parameters('SafeModeAdministratorPassword'),' -AsPlainText -Force; Install-ADDSForest -DomainName \"bastionkrb.test\" -SafeModeAdministratorPassword $Secure_String_Pwd -Force:$true')]"
283+
}
284+
}
285+
},
286+
{
287+
"type": "Microsoft.Network/networkInterfaces",
288+
"apiVersion": "2018-10-01",
289+
"name": "[concat(parameters('ClientVMName'), 'Nic')]",
290+
"location": "[parameters('location')]",
291+
"dependsOn": [
292+
"[concat('Microsoft.Network/virtualNetworks/', parameters('VnetName'))]",
293+
"[concat('Microsoft.Compute/virtualMachines/', parameters('ServerVMName'))]"
294+
],
295+
"properties": {
296+
"ipConfigurations": [
297+
{
298+
"name": "[concat(parameters('ClientVMName'), 'NicIpConfig')]",
299+
"properties": {
300+
"privateIPAllocationMethod": "Static",
301+
"privateIPAddress": "[variables('ClientVMPrivateIpAddress')]",
302+
"subnet": {
303+
"id": "[variables('ClientVMSubnetId')]"
304+
}
305+
}
306+
}
307+
]
308+
}
309+
},
310+
{
311+
"type": "Microsoft.Compute/virtualMachines",
312+
"apiVersion": "2020-06-01",
313+
"name": "[parameters('ClientVMName')]",
314+
"location": "[parameters('location')]",
315+
"dependsOn": [
316+
"[concat('Microsoft.Network/networkInterfaces/', parameters('ClientVMName'), 'Nic')]"
317+
],
318+
"properties": {
319+
"hardwareProfile": {
320+
"vmSize": "[parameters('vmSize')]"
321+
},
322+
"osProfile": {
323+
"AdminUsername": "[parameters('ClientVMUsername')]",
324+
"AdminPassword": "[parameters('ClientVMPassword')]",
325+
"computerName": "[parameters('ClientVMName')]"
326+
},
327+
"storageProfile": {
328+
"imageReference": "[parameters('ClientVmImage')]",
329+
"osDisk": {
330+
"createOption": "FromImage",
331+
"managedDisk": {
332+
"storageAccountType": "Standard_LRS"
333+
}
334+
}
335+
},
336+
"networkProfile": {
337+
"networkInterfaces": [
338+
{
339+
"id": "[ResourceId('Microsoft.Network/networkInterfaces/', concat(parameters('ClientVMName'), 'Nic'))]"
340+
}
341+
]
342+
}
343+
}
344+
},
345+
{
346+
"type": "Microsoft.Compute/virtualMachines/extensions",
347+
"apiVersion": "2021-04-01",
348+
"name": "[concat(parameters('ClientVMName'),'/', 'DomainJoin')]",
349+
"location": "[parameters('location')]",
350+
"dependsOn": [
351+
"[concat('Microsoft.Compute/virtualMachines/',parameters('ClientVMName'))]",
352+
"[concat('Microsoft.Compute/virtualMachines/', parameters('ServerVMName'),'/extensions/', 'PromoteToDomainController')]",
353+
"[concat('Microsoft.Network/bastionHosts/', parameters('BastionName'))]"
354+
],
355+
"properties": {
356+
"publisher": "Microsoft.Compute",
357+
"type": "CustomScriptExtension",
358+
"typeHandlerVersion": "1.7",
359+
"autoUpgradeMinorVersion": true,
360+
"settings": {
361+
"commandToExecute": "[concat('powershell.exe -Command Set-ItemProperty -Path HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0\\ -Name RestrictReceivingNTLMTraffic -Value 1; $Pass= ConvertTo-SecureString -String ',parameters('ServerVMPassword'),' -AsPlainText -Force; $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList \"AD\\serveruser\", $Pass; do { try { $joined = add-computer -computername Client-vm -domainname bastionkrb.test –credential $Credential -passthru -restart –force; } catch {}} while ($joined.HasSucceeded -ne $true)')]"
362+
}
363+
}
364+
},
365+
{
366+
"apiVersion": "2020-11-01",
367+
"type": "Microsoft.Network/publicIPAddresses",
368+
"name": "[parameters('BastionPublicIPName')]",
369+
"location": "[resourceGroup().location]",
370+
"sku": {
371+
"name": "Standard"
372+
},
373+
"properties": {
374+
"publicIPAllocationMethod": "Static"
375+
},
376+
"tags": {}
377+
},
378+
{
379+
"type": "Microsoft.Network/bastionHosts",
380+
"apiVersion": "2020-11-01",
381+
"name": "[parameters('BastionName')]",
382+
"location": "[resourceGroup().location]",
383+
"dependsOn": [
384+
"[concat('Microsoft.Network/virtualNetworks/', parameters('VnetName'))]",
385+
"[concat('Microsoft.Network/publicIpAddresses/', parameters('BastionPublicIPName'))]"
386+
],
387+
"sku": {
388+
"name": "Standard"
389+
},
390+
"properties": {
391+
"enableKerberos": "true",
392+
"ipConfigurations": [
393+
{
394+
"name": "IpConf",
395+
"properties": {
396+
"privateIPAllocationMethod": "Dynamic",
397+
"publicIPAddress": {
398+
"id": "[resourceId('Microsoft.Network/publicIpAddresses', parameters('BastionPublicIPName'))]"
399+
},
400+
"subnet": {
401+
"id": "[concat(resourceId('Microsoft.Network/virtualNetworks', parameters('VnetName')), '/subnets/AzureBastionSubnet')]"
402+
}
403+
}
404+
}
405+
]
406+
}
407+
}
408+
]
409+
}
410+
```
411+
412+
The following resources have been defined in the template:
413+
- Deploys the following Azure resources:
414+
- [**Microsoft.Network/virtualNetworks**](/azure/templates/microsoft.network/virtualnetworks): create an Azure virtual network.
415+
- [**Microsoft.Network/bastionHosts**](/azure/templates/microsoft.network/bastionHosts): create a Standard SKU Bastion with a public IP and Kerberos feature enabled
416+
- Create a Windows 10 ClientVM and a Windows Server 2019 ServerVM
417+
- Have the DNS Server of the VNET point to the private IP address of the ServerVM (domain controller).
418+
- Runs a Custom Script Extension on the ServerVM to promote it to a domain controller with domain name: `bastionkrb.test`.
419+
- Runs a Custom Script Extension on the ClientVM to have it:
420+
- **Restrict NTLM: Incoming NTLM traffic** = Deny all domain accounts (this is to ensure Kerberos is used for authentication).
421+
- Domain-join the `bastionkrb.test` domain.
422+
423+
## Deploy the template
424+
To setup Kerberos, deploy the ARM template above by running the following PS cmd:
425+
```
426+
New-AzResourceGroupDeployment -ResourceGroupName <your-rg-name> -TemplateFile "<path-to-template>\KerberosDeployment.json"`
427+
```
428+
## Review deployed resources
429+
Now, login to ClientVM using Bastion with Kerberos authentication:
430+
- credentials: username = `[email protected]` and password = `<password-entered-during-deployment>`.
431+
432+
68433
## Next steps
69434

70435
For more information about Azure Bastion, see [What is Azure Bastion?](bastion-overview.md)

0 commit comments

Comments
 (0)