avatarBill WANG

Summary

The website content details a method for configuring Local Group Policy to disable Network Level Authentication (NLA) for AzureAD-Ready logins on Windows Servers in Azure Virtual Machines, ensuring seamless AzureAD login without manual intervention.

Abstract

The article outlines a solution to a long-standing challenge of disabling Network Level Authentication (NLA) in Windows Server for AzureAD logins, which is essential for AzureAD-Ready environments. The author provides a background on the necessity of automating this process, particularly when setting up a Windows Golden image or deploying new Azure VMs. Despite facing several challenges, including ineffective Azure Run Commands and limitations in managing group policies without domain services, the author successfully developed a PowerShell script using the third-party PolicyFileEditor module to modify the local group policy settings. This script ensures that the NLA settings persist after system reboots, facilitating direct AzureAD logins without manual configuration.

Opinions

  • The author emphasizes the importance of automating the NLA disabling process to streamline AzureAD logins for Azure VMs.
  • There is a clear distinction made between the ineffectiveness of built-in Azure Run Commands and the need for a more robust solution.
  • The author acknowledges the complexity of managing group policies without domain services, which is a common scenario for application teams with local administrator permissions.
  • The use of a third-party tool, PolicyFileEditor, is presented as a key component in achieving the desired configuration.
  • The author shares a personal triumph after a two-year struggle to find a solution, highlighting the non-trivial nature of the task.
  • The article concludes with a recommendation for an AI service, ZAI.chat, as a cost-effective alternative to ChatGPT Plus (GPT-4), suggesting the author's endorsement of the service based on its performance and affordability.

Configure Local Group Policy to Disable NLA in Windows Server for AzureAD-Ready Logins.

Follow up on my blogs regarding Azure AD (Microsoft Entra ID) login to Azure Virtual Machines

Prerequesites

Several configurations for a successful AzureAD login to a Azure Windows Virtual machine

  • Azure Bastion with Standard Tier (highest and most expensive tier)
  • Enable System-assigned managed identity
  • Assign users or groups in Access control (IAM) with build-in role of “Virtual Machine Administrator Login
  • Install the AADLoginForWindows extension on the VM
  • Disable NLA (for Windows system only)

Background

I can work out the setting with Terraform automation code for the other four (for detail , take reference in Login to a Virtual Machine using Azure AD Account on Linux), but I’m facing challenges in implementing the last one “Disable NLA ( Network Level Authentication)” through scripts

I managed it by manually changing two registry keys in the Local Group Policy.

  • Open gpedit.msc applet.
  • Navigate to Computer Configuration -> Administrative Templates -> Windows Components -> Remote Desktop Services -> Remote Desktop Session Host -> Security.
  • Enable Require use of specific security layer for remote (RDP) connections and select RDP as Security Layer.
  • Disable Require user authentication for remote connections by using Network Level Authentication policy.
  • run command gpupdate /force to update your Group Policies

However, this is done manually. I’m aiming to take it a step further by creating a Windows Golden image with “Disable NLA” ready or start up Windows Virtual Machine with custom-data or user-data script to “Disable NLA”

It took me two years to figure this out.

Challenges

  • Challenge #1: In each Azure Windows VM, there is a Azure Run Command, called “Disable NLA”. But it doesn’t work. I still can’t login via AzureAD after run that command with reboot.
  • Challenge #2: Research on Manage group policy with Domain services. This is beyond my permission. As member of an application team, we have only local administrator permission on the VM, and our VMs aren’t Corporate Domain-Joined. Main reason is, we don’t have AD server in Azure Platform yet.
  • Challenge #3: Difference between Registry and local group policy
Get-Item -LiteralPath $registryPath

    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT


Name                           Property                                                                                                                          
----                           --------                                                                                                                          
Terminal Services              KeepAliveEnable       : 1                                                                                                         
                               KeepAliveInterval     : 1                                                                                                         
                               DeleteTempDirsOnExit  : 1                                                                                                         
                               DisablePasswordSaving : 1                                                                                                         
                               fAllowToGetHelp       : 0                                                                                                         
                               fAllowUnsolicited     : 0                                                                                                         
                               fDisableCdm           : 1                                                                                                         
                               fEncryptRPCTraffic    : 1                                                                                                         
                               MinEncryptionLevel    : 3                                                                                                         
                               PerSessionTempDir     : 1                                                                                                         
                               UserAuthentication    : 0

With help of this official document [Download Group Policy Settings Reference for Windows and Windows Server] I know two registry keys I need target:

  • HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\SecurityLayer
  • HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services\UserAuthentication

Got help from another document [Require use of specific security layer for remote (RDP) connections]

I understood, the value of SecurityLayer need be set to 0 (it is RDP)

With this document Why gpedit and the corresponding registry entries are not synchronized?, I realized, Registry keys and Local Grou policy are different layers to manage the registry keys.

https://excalidraw.com/#json=sOTI-twNAw20K1oLl0JhX,jLmnF2UNxzIKWMVVZnl9zw

Our VMs are not Domain-Joined, so the Domain-Layer Group policy would not be able to override the setting in registry keys.

But the changes I did on local Registry, after gpupdate /force or VM reboot, these settings are always rolled back.

So we have to do the settting on Local Group Policy via PowerShell Script.

Local group policy settings are stored in registry.pol files located in ”$env:windir\system32\GroupPolicy\Machine\registry.pol”. These files overwrite the corresponding keys in the registry every time the system performs a group policy refresh. The local group policy never actually reads the registry to see what settings it contains.

Let’s focus on Local Group Policy Editor

Group Policy Editor

Unlocky, Microsoft doens’t have the module in PowerShell to manage local group policy. Finally I worked it out with a third-party tool, called PolicyFileEditor

PolicyFileEditor is a PowerShell module to manage local GPO registry.pol files.

Then I wrote the script and successfully run it to disable NLA, and keep the setting after VM rebooted as well.

Write-Host "### Disable Network Level Authentication (NLA)  ### "

# Group Policy Settings Reference for Windows and Windows Server
# https://www.microsoft.com/en-us/download/confirmation.aspx?id=25250
# https://download.microsoft.com/download/8/F/B/8FBD2E85-8852-45EC-8465-92756EBD9365/Windows10andWindowsServer2016PolicySettings.xlsx
#
# HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services!SecurityLayer
# HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services!UserAuthentication

# Group Policy File Editor
# https://github.com/dlwyatt/PolicyFileEditor

# Function to configure policies on Terminal Server
function Configure-TerminalServerPolicies {

    $UserDir = "$env:windir\system32\GroupPolicy\Machine\registry.pol"
    # Navigate to the specified path in the registry

    # Enable specific security layer for RDP connections
    $RegPath = 'Software\Policies\Microsoft\Windows NT\Terminal Services'
    $RegName = 'SecurityLayer'
    $RegData = '0'
    $RegType = 'DWORD'
    Set-PolicyFileEntry -Path $UserDir -Key $RegPath -ValueName $RegName -Data $RegData -Type $RegType

    # Disable Network Level Authentication (NLA)
    $RegPath = 'Software\Policies\Microsoft\Windows NT\Terminal Services'
    $RegName = 'UserAuthentication'
    $RegData = '0'
    $RegType = 'DWORD'
    Set-PolicyFileEntry -Path $UserDir -Key $RegPath -ValueName $RegName -Data $RegData -Type $RegType
}

# Force install the third-party module PolicyFileEditor
Install-Module -Name PolicyFileEditor -Force

# Configure policies on Terminal Server
Configure-TerminalServerPolicies

# Force update Group Policies
gpupdate /force

Write-Host "Check the values, both should be 0"
$registryPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"
Get-ItemProperty -Path $registryPath  -Name "securitylayer"
Get-ItemProperty -Path $registryPath  -Name "UserAuthentication"

Write-Host "### Disable Network Level Authentication (NLA)  - Done ### "

With this script, I can put it in when bake the Windows Golden Image or create a new VM with User data script. Finally I can create a new Azure Windows VM and login with AzureAD ( AzureAD\<your_mail_box> )directly without any manual tasks.

Reference

github repo for PolicyFileEditor

Useful usage about PolicyFileEditor

RDP to a Windows Azure VM using Microsoft Entra ID (Azure AD)

Why gpedit and the corresponding registry entries are not synchronized?

Learning is fun

# Azure # AzureAD # Microsoft Entra ID # DevOps # Group Policy # Azure VM # Best Practices

Azure
Azure Ad
DevOps
Best Practices
Cloud
Recommended from ReadMedium