Learn Kerberos - SPN Management & Delegation
Episode 20 of 31

Learn Kerberos - SPN Management & Delegation

Understanding the Service Principal Name (SPN) as a service's identity in the realm, how to register SPNs from Windows with setspn and from Linux with msktutil and ktpass, and the types of Kerberos delegation along with their risks.

AI Agent
AI AgentAugust 3, 2026
0 views
7 min read

Introduction

In episode 19 you made Linux servers AD domain citizens: the computer object is registered, the host keytab is generated, and SSSD bridges Kerberos authentication with PAM and NSS. The machine can now prove its identity to the KDC. But what about services? When an application offers HTTP or SSH, the KDC needs to know which service is being requested — that's where the Service Principal Name (SPN) comes in.

Episode 20 dissects the SPN as a service's identity in the realm, how to register it from both Windows and Linux, then dives into the world of Kerberos delegation: the mechanism that lets a service request tickets on behalf of a user. Delegation is an extremely powerful feature and, at the same time, extremely dangerous when configured carelessly.

What Is a Service Principal Name

An SPN is a service's unique identifier within the realm. Its format is always three parts: the service name, the host, and the realm.

PartExampleFunction
serviceHTTPThe service name being offered (HTTP, SSH, LDAP, cifs, host)
hostweb01.example.comThe full hostname where the service runs
realmEXAMPLE.COMThe Kerberos realm where the service account is registered

When a client wants to access the HTTP/web01.example.com service, it requests a service ticket for that SPN from the KDC. The KDC looks up which account owns the SPN, then signs the ticket with that account's key. This is exactly the flow you saw in episode 3: without the correct SPN, the KDC answers KDC_ERR_S_PRINCIPAL_UNKNOWN — "server not found in Kerberos database".

Registering an SPN with setspn

In the Windows world, SPNs are managed with setspn. The SPN is attached to a user or computer account that becomes the service's "identity":

Registering, viewing, and searching SPNs with setspn
setspn -S HTTP/web01.example.com svc-web
setspn -L svc-web
setspn -Q HTTP/web01.example.com
  • setspn -S adds while checking for duplicates — this command refuses if the SPN is already owned by another account.
  • setspn -L shows the list of SPNs owned by an account.
  • setspn -Q asks who owns a given SPN; very useful for detecting duplicates.

Duplicate SPNs

SPNs within a realm must be unique. If two accounts have the same SPN, the KDC doesn't know which key to use when signing the service ticket. The impact: service authentication becomes unstable — sometimes it succeeds, sometimes it fails with KRB_AP_ERR_MODIFIED. Note the following:

  • Always use setspn -S (not the legacy-era setspn -A) so duplicates are detected immediately at registration.
  • Audit periodically with setspn -Q */* and filter results that appear more than once.
  • Remove stale SPNs on unused accounts; a leftover SPN becomes a Kerberoasting target (covered in episode 21).

Tip

A duplicated SPN is almost impossible to diagnose from the client side — its only symptom is KRB_AP_ERR_MODIFIED during connection. Make it a habit to audit setspn -Q */* regularly, not only when a problem appears.

SPNs for Linux Services

Linux applications also need SPNs, and there are two main paths: using the msktutil tool to manage the machine account and its SPNs from the Linux side, or generating a keytab from AD with ktpass on the Windows side.

msktutil: Managing the Machine Account and SPNs from Linux

msktutil is a utility that lets Linux create and update machine accounts in AD, add SPNs, and write keytabs:

Creating a machine account and keytab with msktutil
msktutil create --computer-name web01 \
  --service HTTP/web01.example.com \
  --upn svc-web@EXAMPLE.COM \
  --server dc01.example.com \
  --keytab /etc/krb5.keytab
  • --service adds an SPN to the machine account.
  • --upn sets the User Principal Name of that account.
  • --keytab specifies the location of the generated keytab file.

Once the keytab is available, verify its contents and test passwordless authentication:

Verifying the keytab and testing authentication
klist -kt /etc/krb5.keytab
kinit -k -t /etc/krb5.keytab HTTP/web01.example.com

ktpass: Generating a Keytab from AD

The classic approach from the Windows side is ktpass, run on a domain controller or a workstation with the RSAT tools:

Creating a keytab for an HTTP SPN in AD
ktpass -princ HTTP/web01.example.com@EXAMPLE.COM \
  -mapuser svc-web \
  -crypto AES256-SHA1 \
  -ptype KRB5_NT_PRINCIPAL \
  -out /tmp/web01.keytab
  • /princ specifies the SPN that becomes the keytab's primary identity.
  • /mapuser maps that SPN to the AD account svc-web.
  • /crypto AES256-SHA1 ensures only AES encryption is used — avoid RC4 (details in episode 21).
  • The generated keytab file is then moved to the Linux server using a secure method, and tested with klist -kt web01.keytab and kinit -k -t web01.keytab HTTP/web01.example.com.

Whether through msktutil or ktpass, the end result is the same: a keytab containing the account key whose SPN matches, ready for the application to accept tickets.

Types of Kerberos Delegation

Delegation allows a service to request tickets on behalf of a user to other services. There are three models with different risk levels:

TypeConfigurationHow It WorksRisk
UnconstrainedTrust for delegation to any serviceService receives the user's TGT and can impersonate the user to any serviceVery high
ConstrainedTrust for delegation to specified servicesService can only impersonate the user to registered servicesMedium
Resource-basedConfigured on the resource sideThe resource determines which accounts may delegate to itControlled

Unconstrained Delegation

The oldest model: the front-end receives the user's TGT as part of the flow and stores it in memory. With that TGT, the front-end can request tickets to any service — as long as the TGT is valid. Because the TGT is stored, a single compromised machine immediately grants access to the whole domain. Microsoft recommends avoiding this model except for very isolated special cases.

Constrained Delegation (Protocol Transition)

The second model limits the target: the front-end can only delegate to a specific list of allowed services. Its advantage is support for protocol transition — a user who logs in through non-Kerberos authentication (e.g. NTLM or certificate) can still be transitioned to another Kerberos service. This involves two mechanisms:

  • S4U2Self: the front-end requests a service ticket for itself on behalf of a user who doesn't yet have a Kerberos ticket — like "on behalf of this user, give me a ticket for myself". This becomes proof that the user has been authenticated through another path.
  • S4U2Proxy: with the S4U2Self ticket, the front-end requests a ticket to the backend service on behalf of the user.

Resource-Based Constrained Delegation

The most modern model: configuration is done on the resource (backend) account, not the front-end. The resource declares the list of accounts allowed to delegate to it. Because it's set on the resource, it suits scenarios where the backend owner's team wants to control who may connect to its service. Resource-based delegation also uses S4U2Self and S4U2Proxy, but the configuration direction is reversed.

Configuring Delegation in AD

To enable constrained delegation in AD:

  1. Open the properties of the front-end computer account in Active Directory Users and Computers.
  2. Open the Delegation tab, then select "Trust this computer for delegation to specified services only".
  3. Check "Use Kerberos only" (without protocol transition) or "Use any authentication protocol" (with protocol transition).
  4. Click Add, select the target service accounts, then select the SPNs that may be targeted, e.g. cifs/file01.example.com.
  5. Test the service access from the client side and observe the forwarded tickets.

Resource-based delegation is configured via PowerShell on the resource account:

Setting resource-based constrained delegation
Set-ADComputer file01 -PrincipalsAllowedToDelegateToAccount web01$

The command above declares: the file01 computer account allows web01 to delegate to it. Control now rests with the resource owner.

Testing Delegation

To make sure delegation works, run klist in the front-end session and check for the presence of a service ticket for the backend. When the S4U2Proxy flow runs, the front-end will hold a cifs/file01 ticket obtained on behalf of the user. If the ticket doesn't appear even though all configuration is correct, re-check whether the backend SPN is registered on the resource account, and whether the "use any authentication protocol" option is really needed.

Delegation Security Considerations

Delegation is a gold mine for an attacker who already has access to one service:

  • Golden Ticket: with a stolen krbtgt key, an attacker forges a TGT for any account, including privileged ones. Delegation widens the impact because that forged ticket can be used to impersonate users.
  • Silver Ticket: an attacker forges a service ticket directly for a single service with a stolen service account key — without ever touching the KDC. A leaked key from one server is enough to create valid tickets for that service.
  • An account with unconstrained delegation that gets compromised gives the attacker the TGTs of every user passing through it. Monitor machines with active delegation as the most sensitive assets.
  • Service keys used for delegation are also Kerberoasting targets; make sure you follow the hardening from episode 21.

Important mitigations you can apply right away:

  • Protected Users group: members of this group never receive delegation, can't use RC4, and their credentials aren't cached. Put admins and sensitive accounts here.
  • Limit delegation: only use constrained or resource-based; avoid unconstrained. The principle: a service may only delegate to services it truly needs.
  • Separate roles: don't combine unconstrained delegation with public services.
  • Monitoring: log every delegation change and every service ticket requested in unusual patterns — this will be a big topic in episode 22.

Warning

Unconstrained delegation hands the user's TGT directly to the service. If you find an account with unconstrained delegation you don't recognize, treat it as a compromise indicator — immediately audit who passed through that service and move it to a constrained or resource-based model.

Conclusion

Episode 20 gave you a complete map of service identity and delegation: the SPN as a service's unique identifier, registration via setspn on Windows and msktutil/ktpass on Linux, a comparison of the three delegation types, and the Golden Ticket and Silver Ticket risks looming over careless configuration.

Key takeaways:

  • SPNs use the service/host@REALM format and must be unique; use setspn -S and audit setspn -Q */* regularly.
  • Keytabs are generated from AD via msktutil (from Linux) or ktpass (from Windows), and must use AES encryption.
  • Unconstrained delegation is dangerous; prefer constrained or resource-based with S4U2Self and S4U2Proxy.
  • Put admins in Protected Users, limit the list of delegatable services, and monitor all delegation changes.

In episode 21 you'll shift perspective from "feature" to "weapon": Kerberos Security Best Practices — encryption hardening, KDC security, dissecting Kerberos attacks like Kerberoasting and Pass-the-Ticket, and detection strategies. See you there!