With Server 2025, how do you avoid NTLM authentication for a RDP session originating from a non domain workstation ?

Serge Caron 0 Reputation points
2025-12-06T19:48:13.38+00:00

In order to reduce complexity, I am using a test domain consisting of a single domain controller ON PREMISES and a single user, the domain administrator.

There is a single role installed: Remote Desktop Gateway. None of the other 5 RDS roles are installed. Direct Access and/or VPNs are not allowed in this test.

The AD domain is MyDomain.local and the internal FQDN is MyServer.MyDomain.local

There is a Let's Encrypt certificate installed on this server for MyServer.MyDomain.TLD.

Finally, there is a single port 443 forwarded to the server from the firewall.

I can RDP into this server from the Internet to MyServer.MyDomain.local via RDG MyServer.MyDomain.TLD.

However, all logons are downgraded to NTLMv2 even if I set

rdgiskdcproxy:i:1

kdcproxyname:s:MyServer.Mydomain.TLD

In this test case, I am using a non domain joined Windows 10 Pro client (even if I know it is deprecated): we need to demonstrate RDG working with BYOD, including non Windows devices.

Is there a way to do this in Windows Server 2025 ?

Windows for business | Windows Server | Directory services | User logon and profiles
0 comments No comments
{count} votes

11 answers

Sort by: Most helpful
  1. Serge Caron 0 Reputation points
    2025-12-09T15:58:38.54+00:00

    Hello VPHAN,

    Thank you for explaining that it is the client that is downgrading the authentification protocol.

    Most of what follows is translated from French and may not be the exact wording you are used to.

    The client Security-Kerberos is recording event ID 100:

    The service principal name (SPN) HTTP/MyServer.MyDomain.TLD@MYDOMAIN.LOCAL is not registered, which caused the Kerberos authentication to fail: 0x7. Use the setspn command-line tool to register the service principal name.

    ksetup shows the current configuration and notes that the client is not domain registered. However it fails to record the encoding types:

    C:\WINDOWS\system32>ksetup /DumpState

    The computer is not configured to log on to an external KDC. Probably a member of a workgroup.

    MYDOMAIN.LOCAL:

    kdc = MyServer.MyDomain.TLD

    Domain indicators = 0x0No domain indicators

    No user mapping defined.

    C:\WINDOWS\system32>ksetup /SetEncTypeAttr MYDOMAIN.LOCAL AES256-CTS-HMAC-SHA1-96

    Definition of the encoding types for the domain MYDOMAIN.LOCAL on: AES256-CTS-HMAC-SHA1-96

    The definition of the coding types on MYDOMAIN.LOCAL failed with 0xc0000034

    /SetEncTypeAttr failed: 0xc0000034

    0xc0000034 is NTSTATUS "STATUS_OBJECT_NAME_NOT_FOUND" and documented as "The object name is not found.".

    Please note that the command "ksetup /addhosttorealmmap .MyDomain.local MYDOMAIN.LOCAL" does not generate any output and can be repeated without any error message to the effect that this mapping is already recorded.

    All attempts to use setspn on the client have failed with error LDAP 0x51.

    Clearly I am still missing a piece of that puzzle.

    Regards,

    0 comments No comments

  2. VPHAN 10,565 Reputation points Independent Advisor
    2025-12-09T21:46:03.13+00:00

    Hi,

    You have successfully identified the root cause with that Event ID 100 on the client. The error code 0x7 (KDC_ERR_S_PRINCIPAL_UNKNOWN) is the definitive blocker here.

    Your Windows 10 client connects to https://MyServer.MyDomain.TLD (The Gateway/Proxy). Because you are enforcing Kerberos, the client must obtain a Service Ticket for that specific endpoint to prove its identity before the Proxy will talk to it. The client asks the KDC (your server) for a ticket for the Service Principal Name (SPN) HTTP/MyServer.MyDomain.TLD. The Active Directory responds: "I have no record of any computer with that name." Authentication stops immediately. The encryption types (AES vs RC4) don't even matter yet because the account lookup failed first.

    To fix the SPN and the ksetup error.

    Step 1: Register the SPN (Must be done on the SERVER)

    You can't run setspn on the non-domain joined client because it lacks write permissions to your Active Directory. You must run this command on the Windows Server 2025 domain controller.

    Open an Administrator Command Prompt on the Server and run: setspn -S HTTP/MyServer.MyDomain.TLD MyServer

    Replace MyServer at the end with the actual SAMAccountName of your server computer object if it differs. This tells Active Directory: "When a client asks for HTTP/MyServer.MyDomain.TLD, that traffic belongs to the computer account MyServer."

    Step 2: Fix the ksetup 0xc0000034 Error (Client Side)

    The error 0xc0000034 (STATUS_OBJECT_NAME_NOT_FOUND) on the client indicates that the registry key for the Realm MYDOMAIN.LOCAL was not fully or correctly initialized during the ksetup /addkdc step, or there is a casing mismatch (ksetup is case-sensitive).

    To fix this, we will perform a clean reset of the KDC configuration on the client.

    On the Client (Administrator Command Prompt):

    Remove the existing configuration (Clean Slate): ksetup /delrealm MYDOMAIN.LOCAL

    Re-add the Realm (Ensure UPPERCASE for the Realm): ksetup /addkdc MYDOMAIN.LOCAL MyServer.MyDomain.TLD

    Re-apply the Encryption Type (Now the object should exist): ksetup /SetEncTypeAttr MYDOMAIN.LOCAL AES256-CTS-HMAC-SHA1-96

    Re-apply the Host Mapping: ksetup /addhosttorealmmap .MyDomain.local MYDOMAIN.LOCAL

    Step 3: Verify and Connect

    Once the SPN is registered on the server and the client configuration is refreshed:

    Run klist purge on the client.

    Attempt the RDP connection again.

    Run klist on the client. You should now see a ticket for HTTP/MyServer.MyDomain.TLD.

    I hope you've found something useful here. If it helps you get more insight into the issue, it's appreciated to accept the answer. Should you have more questions, feel free to leave a message. Have a nice day!

    VPHAN

    0 comments No comments

  3. Serge Caron 0 Reputation points
    2025-12-10T14:54:05.3566667+00:00

    Hello VPHAN,

    On this client, there is no "delrealm" option in ksetup. There is a "RemoveRealm" which I used to remove the MYDOMAIN.LOCAL realm followed by a "DumpState" to verify that no mapping is defined.

    The command "ksetup /addkdc MYDOMAIN.LOCAL MyServer.MyDomain.TLD" completes successfully and I can verify the result with "DumpState".

    I can also verify with regedit that the key HKLM\SYSTEM\CurrentControlSet\Control\LSA\Kerberos\Domains\MYDOMAIN.LOCAL has an item "KdcNames" of type MultiString with value "MyServer.MyDomain.TLD".

    At this point, the other subkeys of the "Kerberos" key ("HostToRealm" and "Parameters") are empty.

    Any attempt to manipulate the encryption attributes, whether "ksetup /SetEncTypeAttr MYDOMAIN.LOCAL AES256-CTS-HMAC-SHA1-96" or a simple "ksetup /GetEncTypeAttr MYDOMAIN.LOCAL" results in error 0xc0000034.

    I also repeated these tests after using "ksetup /SetRealm MYDOMAIN.LOCAL" and rebooting: this basically substitute the workgroup for a default domain. Again, any attempt to manipulate the encryption attributes fail with the same error code.

    I have no clue of what the missing object may be ;-)

    Regards,

    0 comments No comments

  4. VPHAN 10,565 Reputation points Independent Advisor
    2025-12-11T04:53:44.2+00:00

    Hi,

    I think we are dealing with two distinct issues here, so it is crucial to separate them to avoid chasing ghosts.

    Error 0x7 (Server Side): The client cannot find the Service Principal Name (SPN). This is a hard blocker in Active Directory.

    Error 0xc0000034 (Client Side): The ksetup tool is buggy when running on non-domain joined machines (Workgroup) because it fails to properly handle handles for LSA objects that don't fully exist in a local SAM context.

    We will bypass the buggy ksetup tool by manipulating the registry directly, and we will fix the SPN.

    Phase 1: Bypass the ksetup 0xc0000034 Error

    Since ksetup is failing to write the encryption attributes because of an "Object Name Not Found" error (likely looking for a domain policy object that doesn't exist in a workgroup), we will inject the configuration directly into the registry where ksetup is supposed to put it.

    Open PowerShell as Administrator on your Windows 10 Client and run this.

    $RealmPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Domains\MYDOMAIN.LOCAL"

    New-ItemProperty -Path $RealmPath -Name "SupportedEncryptionTypes" -PropertyType DWORD -Value 24 -Force

    After running this, run ksetup /DumpState. You should now see the encryption types listed, proving the configuration has been accepted by the LSA.

    Phase 2: The Critical SPN Fix (Error 0x7)

    You mentioned the client log showed KDC_ERR_S_PRINCIPAL_UNKNOWN (0x7) regarding HTTP/MyServer.MyDomain.TLD.

    You can't skip this step. Even if the client is perfectly configured, if Active Directory does not know that the URL MyServer.MyDomain.TLD belongs to your Domain Controller, it will reject the ticket request immediately. This is why you see the 0x7 error.

    On your Server 2025 Domain Controller (Admin Cmd), run:

    setspn -S HTTP/MyServer.MyDomain.TLD MyServer

    (Replace MyServer at the very end with the actual NetBIOS name of the server object in AD if it is different).

    Phase 3: Final Verification Steps

    Once the Registry key is injected on the client and the SPN is registered on the server:

    Flush Client Cache:

    klist purge

    Verify Host Mapping: Ensure the registry has the host mapping. Check HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\HostToRealm. You should see a value named .MyDomain.local containing MYDOMAIN.LOCAL. If not, create it manually via regedit to bypass any ksetup silence.

    Connect: Launch your RDP file.

    Windows 10 Workgroup clients rely on the KDC Proxy to "tunnel" the Kerberos request. The Client asks: "I need a ticket for HTTP/MyServer.MyDomain.TLD".

    The KDC (Server) looks up that name. Without setspn, it returns "Unknown Principal" (0x7).

    If setspn is present, the KDC replies with a Ticket.

    The Client then uses that ticket to establish the HTTP tunnel.

    Inside the tunnel, the Client requests a ticket for TERMSRV/MyServer.MyDomain.local (the internal name).

    By manually setting the Registry key on the client, you force the client to propose AES encryption during that first handshake, preventing the downgrade to NTLM caused by protocol mismatch.

    VP

    0 comments No comments

  5. Serge Caron 0 Reputation points
    2025-12-11T22:06:35.4966667+00:00

    Hello VPHAN,

    Rather than rely on expected behavior from ksetup and/or direct RegEdit modifications, I decided to go for a "belt and suspenders" script.

    Here is the script (you need to edit the first two lines to define the Realm and the FQDN of the KDC): see other comments below.

    $Realm = "MYDOMAIN.LOCAL"
    $KdcFQDN = "MyServer.MyDomain.TLD"
    ### Make sure proper case is used in these namespaces
    $KdcFQDN = $KdcFQDN.ToLOWER()
    $Realm = $Realm.ToUPPER()
    ### Location of Kerberos keys
    $KerberosLSA = "HKLM:\SYSTEM\CurrentControlSet\Control\LSA\Kerberos"
    $KerberosPolicies = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters"
    ### Delete this realm and dump actual configuration
    ksetup /DelHostToRealmMap ".$Realm" "$Realm"	# /RemoveRealm will not remove duplicate mappings
    ksetup /RemoveRealm $Realm
    ksetup /DumpState
    ## Host to Realm
    	ksetup /AddHostToRealmMap ".$Realm" "$Realm"
    	(Get-ItemProperty -Path "$KerberosLSA\HostToRealm\$Realm").SpnMappings.Count
    	(Get-ItemProperty -Path "$KerberosLSA\HostToRealm\$Realm").SpnMappings[0] -eq ".$Realm"
    	"" -eq (Get-ItemProperty -Path "$KerberosLSA\HostToRealm\$Realm").SpnMappings[1]
    ### KDC
    	ksetup /addkdc "$Realm" $KdcFQDN
    	(Get-ItemProperty -Path "$KerberosLSA\Domains\$Realm").KdcNames.Count
    	(Get-ItemProperty -Path "$KerberosLSA\Domains\$Realm").KdcNames[0] -eq $KdcFQDN
    	"" -eq (Get-ItemProperty -Path "$KerberosLSA\Domains\$Realm").KdcNames[1]
    ### Encryption Types
    	New-ItemProperty -Path "$KerberosLSA\Domains\$Realm" -Name "SupportedEncryptionTypes" -PropertyType DWORD -Value 24 -Force | `
    		Select-Object SupportedEncryptionTypes
    	(Get-ItemProperty -Path "$KerberosLSA\Domains\$Realm").SupportedEncryptionTypes -eq (Get-ItemProperty -Path "$KerberosPolicies").SupportedEncryptionTypes
    ### LogLevel
    	(Get-ItemProperty -Path "$KerberosLSA\Parameters").LogLevel
    ### Final configuration
    ksetup /DumpState
    

    Comments:

    • ksetup adds an empty line in the multistring entries for realms and host to realms mappings. Regedit does not allow such empty strings.
    • I have added the Kerberos Policies to this configuration
    • on my client, the final /DumpState does not show the encryption type.

    With this configuration in place, the client still reports Event ID 100, error code 0x07, missing spn HTTP/MyServer.MyDomain.TLD@MYDOMAIN.LOCAL.

    On the server, I have the following SPNs in place: I did the duplicate HTTP entry out of desperation ;-)

    PS C:\Users\Administrateur> setspn -S HTTP/MyServer.MyDomain.local MYSERVER
    Vérification du domaine DC=MyServer,DC=local
    CN=MYSERVER,OU=Domain Controllers,DC=MyServer,DC=local
            HTTP/MyServer.MyDomain.local
            HTTP/MyServer.MyDomain.local@MYDOMAIN.LOCAL
            TERMSRV/MYSERVER
            TERMSRV/MyServer.MyDomain.local
            Dfsr-12F9A27C-BF97-4787-9364-D31B6C55EB04/MyServer.MyDomain.local
            ldap/MyServer.MyDomain.local/ForestDnsZones.MYDOMAIN.LOCAL
            ldap/MyServer.MyDomain.local/DomainDnsZones.MYDOMAIN.LOCAL
            DNS/MyServer.MyDomain.local
            GC/MyServer.MyDomain.local/MYDOMAIN.LOCAL
            RestrictedKrbHost/MyServer.MyDomain.local
            RestrictedKrbHost/MYSERVER
            RPC/068ad705-a4dd-4de4-9ca2-84103dc61040._msdcs.MYDOMAIN.LOCAL
            HOST/MYSERVER/MYDOMAIN
            HOST/MyServer.MyDomain.local/MYDOMAIN
            HOST/MYSERVER
            HOST/MyServer.MyDomain.local
            HOST/MyServer.MyDomain.local/MYDOMAIN.LOCAL
            E3514235-4B06-11D1-AB04-00C04FC2DCD2/068ad705-a4dd-4de4-9ca2-84103dc61040/MYDOMAIN.LOCAL
            ldap/MYSERVER/MYDOMAIN
            ldap/068ad705-a4dd-4de4-9ca2-84103dc61040._msdcs.MYDOMAIN.LOCAL
            ldap/MyServer.MyDomain.local/MYDOMAIN
            ldap/MYSERVER
            ldap/MyServer.MyDomain.local
            ldap/MyServer.MyDomain.local/MYDOMAIN.LOCAL
    Détection d'un SPN en double, opération abandonnée.
    PS C:\Users\Administrateur>
    

    And I still did not see a kerberos ticket on the client.

    Regards,

    PS: I updated the server with the december 20205 patch tuesday updates.

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.