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