How to Create SPNs for Windows Services from a Linux Build Server


9 views

When automating service deployments, especially in hybrid environments, you might need to create Service Principal Names (SPNs) for Windows services from a Linux-based build server. SPNs are crucial for Kerberos authentication in Active Directory environments. While setspn.exe is the standard tool on Windows, Linux requires alternative approaches.

If you have access to a Windows server with PowerShell Remoting enabled, you can execute SPN creation remotely:

# Install PowerShell Core on Linux
sudo apt-get install -y powershell

# Execute remotely via PowerShell
pwsh -Command {
    $cred = New-Object System.Management.Automation.PSCredential (
        "DOMAIN\\admin", 
        (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force)
    )
    Invoke-Command -ComputerName windows-server -Credential $cred -ScriptBlock {
        setspn -A HTTP/newservice.domain.com domain\serviceaccount
    }
}

For more control, modify AD directly via LDAP from Linux:

import ldap3

server = ldap3.Server('ldap://domain-controller.domain.com')
conn = ldap3.Connection(
    server,
    user='DOMAIN\\admin',
    password='P@ssw0rd',
    authentication=ldap3.NTLM
)
conn.bind()

# DN of the service account
user_dn = "CN=ServiceAccount,OU=ServiceAccounts,DC=domain,DC=com"

# Add SPN attribute
conn.modify(
    user_dn,
    {
        'servicePrincipalName': [
            (ldap3.MODIFY_ADD, ['HTTP/newservice.domain.com'])
        ]
    }
)

If your environment exposes AD Web Services, you can use SOAP:



  
    
      CN=ServiceAccount,OU=ServiceAccounts,DC=domain,DC=com
      HTTP/newservice.domain.com
    
  

Always store credentials securely:

  • Use SSH certificates for remote PowerShell
  • Implement LDAPS instead of LDAP
  • Consider using managed service accounts
  • Rotate credentials regularly

After creation, verify the SPN exists:

# Using ldapsearch
ldapsearch -H ldap://domain-controller -x -D "DOMAIN\\admin" -w "P@ssw0rd" \
-b "CN=ServiceAccount,OU=ServiceAccounts,DC=domain,DC=com" servicePrincipalName

In modern infrastructure setups where Linux build servers need to integrate with Windows Active Directory services, managing Service Principal Names (SPNs) becomes particularly challenging. The traditional setspn.exe tool is Windows-native, forcing administrators to either:

  • Manually log into Windows servers
  • Maintain complex hybrid workflows
  • Create custom automation bridges

Here are three practical approaches to create SPNs from Linux systems:

1. Using Kerberos Utilities via kadmin


# Requires configured Kerberos admin credentials
kadmin -p adminuser@REALM -q "addprinc -randkey HTTP/webservice.domain.com"
kadmin -p adminuser@REALM -q "ktadd -k /etc/krb5.keytab HTTP/webservice.domain.com"

2. PowerShell Core Remoting


# Install PowerShell Core on Linux
curl -L https://aka.ms/install-powershell.sh | sudo bash

# Create SPN remotely
pwsh -Command {
    $cred = Get-Credential
    Invoke-Command -ComputerName dc01 -Credential $cred -ScriptBlock {
        setspn -A HTTP/newservice.domain.com domain\serviceaccount
    }
}

3. LDAP Direct Modification


# Using ldapmodify with service account privileges
dn: CN=ServiceAccount,OU=ServiceAccounts,DC=domain,DC=com
changetype: modify
add: servicePrincipalName
servicePrincipalName: HTTP/newservice.domain.com

For continuous integration scenarios, consider this Python example using python-ldap:


import ldap

def create_spn(service_name, hostname, service_account_dn):
    l = ldap.initialize('ldap://domain-controller')
    l.simple_bind_s('admin@DOMAIN', 'password')
    
    mod_attrs = [(ldap.MOD_ADD, 'servicePrincipalName', 
                 f'{service_name}/{hostname}'.encode('utf-8'))]
    
    l.modify_s(service_account_dn, mod_attrs)

# Example usage
create_spn('HTTP', 'api.prod.domain.com', 
          'CN=CI-Service,OU=ServiceAccounts,DC=domain,DC=com')
  • Always use encrypted connections (LDAPS or Kerberos)
  • Implement proper credential rotation for automation accounts
  • Apply principle of least privilege to service accounts
  • Audit SPN changes through AD monitoring

To confirm SPN creation from Linux:


ldapsearch -x -H ldaps://dc.domain.com -b "DC=domain,DC=com" \
-D "serviceaccount@domain.com" -W \
"(servicePrincipalName=HTTP/*)" servicePrincipalName