VMware Data Services Manager Kubernetes API
Integrate DSM SQL Server cluster with Active Directory using Windows tooling
Overview
The following document describes how to integrate a DSM SQL Server cluster with an Active Directory (AD) domain. This enables domain users to connect to this DSM SQL Server instance using Windows Authentication, i.e. without providing a password in the connection parameters.
In order to integrate a given DSM SQL Server instance with Active Directory, the server needs:
A dedicated AD domain user account with one or more registered Service Principal Names which the SQL Server will use as its Kerberos identity.
A dedicated AD domain user account with one or more registered Service Principal Names which the SQL Server will use as its Kerberos identity and to perform group refresh. This account is commonly referred to as privileged Active Directory account for SQL Server in Microsoft’s documentation.
For more information see: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-ad-auth-understanding?view=sql-server-ver16#sql-server-group-refresh
Note that while the SQL Server documentation does not explicitly state that the Kerberos identity and the group refresh account must be the same, in practice we’ve run into multiple problems when trying to use different accounts. For this reason, when running SQL Server on DSM this guide recommends to use the same account for both purposes.
A keytab file with the credentials of both accounts.
A resolvable and reverse-resolvable DNS name. While not strictly required, it is needed for compatibility with most client tools. For example, the Windows authentication with Microsoft SQL Server Management Studio will not work without DNS name.
The steps outlined in this document must be executed on a domain-joined Windows machine with a domain account that has sufficient privileges to create other domain accounts and register/configure SPNs in AD to generate a .keytab file. Alternatively, these steps can be performed using adutil tool on a domain-joined Ubuntu machine.
Modes of operation
An identity account, a keytab, and DNS records are necessary for each AD-integrated SQL Server cluster running on DSM. You can create all the required records and perform all configuration manually. However, DSM also support automating some of the steps:
Automated creation of Service Principal Names : you still need to create the SQL Server’s identity account in Active Directory, but instead of creating SPNs and a keytab, you need to provide to DSM the credentials of user who can write to the
servicePrincipalName
property; then, DSM itself will register the required SPNs and generate a keytab file.Automated creation of DNS records: if you are using the Active Directory built-in DNS implementation, you can provide DSM with the credentials of a user which can create records in one or more DNS zones; then, DSM itself will create A and PTR records for the DNS names and the IP address of the cluster respectively.
Note that the automation support is not all-or-nothing: you can let DSM only create SPNs, or only write DNS records for you, and perform the remainder manually.
Prerequisites
- A Windows Domain Controller running Active Directory Domain Services must be available and discoverable through DNS in the network used by DSM. Тhe DNS must be able to resolve all names in the Active Directory domain required for SQL Server Windows Authentication, e.g. domain controller, KDC, SQL Server hostname etc., including reverse lookup zones and PTR records as per Microsoft’s official documentation.
- A privileged domain account that can create other domain accounts and register/configure SPNs in AD to generate a .keytab file.
Fully manual mode
This section describes how to create all Active Directory configuration manually and provide it to DSM. You don’t need to provide any plaintext password to DSM, only the Kerberos service keytab.
Create AD user and Service Principal Names (SPN) for a given DSM SQL Server instance
Create SQLServerCluster instance through DSM and obtain the static IP address allocated by DSM from the cluster’s status, i.e.
status.connection.host
Choose an FQDN (e.g.
sql01.dsmsqlserver.com
) for the cluster and create a forwarding host (A) entry mapping it to the above IP address. The same name must be used in the following SPN records for that cluster. Additionally, create associated PTR record in a reverse lookup zone.On your domain controller, use PowerShell’s New-ADUser command and setspn.exe tool to create a new AD user and set SPNs for the target DSM SQL Server instance as described here: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-active-directory-authentication?view=sql-server-ver16#create-active-directory-user-for-sql-server-and-set-spn
For example:
Create new Active Directory user:
Import-Module ActiveDirectory New-ADUser sql01user -AccountPassword (Read-Host -AsSecureString "<password>") -PasswordNeverExpires $true -Enabled $true
Create Service Principal Names:
-A MSSQLSvc/sql01.dsmsqlserver.com:1433 sql01user setspn -A MSSQLSvc/sql01:1433 sql01user setspn
Additionally, create the keytab file for the target DSM SQL Server instance as described here: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-active-directory-authentication?view=sql-server-ver16#spn-keytab-entries
For example:
/princ MSSQLSvc/sql01.dsmsqlserver.com:[email protected] /ptype KRB5_NT_PRINCIPAL /crypto aes256-sha1 /mapuser DSMSQLSERVER\sql01user /out mssql.keytab -setpass -setupn /kvno 2 /pass <password> ktpass /princ MSSQLSvc/sql01.dsmsqlserver.com:[email protected] /ptype KRB5_NT_PRINCIPAL /crypto rc4-hmac-nt /mapuser DSMSQLSERVER\sql01user /in mssql.keytab /out mssql.keytab -setpass -setupn /kvno 2 /pass <password> ktpass /princ MSSQLSvc/sql01:[email protected] /ptype KRB5_NT_PRINCIPAL /crypto aes256-sha1 /mapuser DSMSQLSERVER\sql01user /in mssql.keytab /out mssql.keytab -setpass -setupn /kvno 2 /pass <password> ktpass /princ MSSQLSvc/sql01:[email protected] /ptype KRB5_NT_PRINCIPAL /crypto rc4-hmac-nt /mapuser DSMSQLSERVER\sql01user /in mssql.keytab /out mssql.keytab -setpass -setupn /kvno 2 /pass <password> ktpass /princ [email protected] /ptype KRB5_NT_PRINCIPAL /crypto aes256-sha1 /mapuser DSMSQLSERVER\sql01user /in mssql.keytab /out mssql.keytab -setpass -setupn /kvno 2 /pass <password> ktpass /princ [email protected] /ptype KRB5_NT_PRINCIPAL /crypto rc4-hmac-nt /mapuser DSMSQLSERVER\sql01user /in mssql.keytab /out mssql.keytab -setpass -setupn /kvno 2 /pass <password> ktpass
Configure the DSM SQL Server instance to integrate with Active Directory
In DSM API create a Secret from the keytab file created in the previous section
KUBECONFIG=dsm-api-kubeconfig.yaml kubectl create secret generic sql01-keytab-secret --from-file=keytab=/path/to/mssql.keytab
Create an ActiveDirectoryDomain object for your Active Directory domain. If the DNS server responsible for the AD domain is different from the system-wide DNS configured for DSM globally, you need to specify the domain’s DNS explicitly in the ActiveDirectoryDomain’s spec. You don’t need to specify trustBundle and privilegedAccountCredentials in manual mode. Multiple SQLServerClusters can share the same ActiveDirectoryDomain.
Example:
apiVersion: infrastructure.dataservices.vmware.com/v1alpha1 kind: ActiveDirectoryDomain metadata: name: my-test-domain spec: name: dsmsqlserver.com nameservers: # Only needed if the globally configured DNS nameserver for DSM cannot # resolve dsmsqlserver.com - 10.20.30.40
Update the SQLServerCluster spec with the Active Directory configuration.
Example:
apiVersion: v1 kind: Secret metadata: name: sql01user stringData: # You don't need to provide a password when a keytab is provided username: "sql01user" --- apiVersion: databases.dataservices.vmware.com/v1alpha1 kind: SQLServerCluster metadata: name: sqlserver-01 namespace: default spec: dnsNames: - sql01.dsmsqlserver.com activeDirectory: domain: # References the name of the ActiveDirectoryDomain object name: my-test-domain sqlServerAccount: # References the name of the Secret name: sql01user keytab: name: sql01-keytab-secret
Automated creation of Service Principal Names
You need to manually create the server identity account for SQL Server. DSM will register Service Principal Names and will create a keytab from the credentials you provided.
Multiple SQL Server clusters can share the same identity account for testing purposes, but this is not a secure practice and is strongly discouraged for production deployments.
Create AD user for a given DSM SQL Server instance
On your domain controller, use PowerShell’s New-ADUser command to create an AD user for the target DSM SQL Server instance as described here: https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-active-directory-authentication?view=sql-server-ver16#create-active-directory-user-for-sql-server-and-set-spn
For example:
Create new Active Directory user: ```powershell Import-Module ActiveDirectory
New-ADUser sql01user -AccountPassword (Read-Host -AsSecureString
“
Configure the DSM SQL Server instance to integrate with Active Directory
You’ll provide DSM with two sets of credentials:
- The credentials of the SQL Server identity user created in the previous section:
KUBECONFIG=dsm-api-kubeconfig.yaml kubectl create secret generic sql01-credentials --from-literal=username=sql01user --from-literal=password='<password>'
- The credentials of a user who can write to the servicePrincipalName property of the server identity user:
KUBECONFIG=dsm-api-kubeconfig.yaml kubectl create secret generic config-credentials --from-literal=username=my-admin --from-literal=password='<password>'
You may optionally use the same user for both purposes; in this case, the user needs to be able to write servicePrincipalName to SELF. See the final paragraph in this section on how to configure a user with the minimal required privileges.
Create an ActiveDirectoryDomain object for your Active Directory domain using the “config-credentials” Secret created in the previous step as privilegedAccountCredentials.
If the DNS server responsible for the AD domain is different from the system-wide DNS configured for DSM globally, you need to specify domain’s DNS explicitly in the ActiveDirectoryDomain’s spec.
If the domain’s LDAP servers’ TLS certificates are not issued by a well-known authority, you also need to create a ConfigMap with a single key – tls.crt – which contains the PEM encoded certificate of the LDAP servers’ signing CA.
Example:
kind: ConfigMap apiVersion: v1 metadata: name: test-domain-trust-bundle data: tls.crt: | -----BEGIN CERTIFICATE----- ... The PEM-encoded CA certificate of the domain's LDAP services. -----END CERTIFICATE-------- apiVersion: infrastructure.dataservices.vmware.com/v1alpha1 kind: ActiveDirectoryDomain metadata: name: dsmsqlserver.com spec: name: dsmsqlserver.com nameservers: # Only needed if the globally configured DNS nameserver for DSM cannot # resolve dsmsqlserver.com - 10.20.30.40 trustBundle: # If the domain's LDAP servers TLS certificates are issued by a well-known # authority like DigiCert or GlobalSign, you may skip this section. name: test-domain-trust-bundle privilegedAccountCredentials: # These credentials are required and will be used to create SPNs under # the SQL Server's identity account. name: config-credentials
Update the SQLServerCluster spec with the Active Directory configuration.
Example:
apiVersion: v1 kind: Secret metadata: name: sql01user stringData: # We must provide a password in semi-automatic mode so DSM can create a keytab file username: "sql01user" password: "<sql01user's-password>" --- apiVersion: databases.dataservices.vmware.com/v1alpha1 kind: SQLServerCluster metadata: name: sqlserver-01 namespace: default spec: dnsNames: - sql01.dsmsqlserver.com activeDirectory: domain: name: dsmsqlserver.com # If no keytab is provided, DSM will create Service Principal Names in # Active Directory under the sql01user, and create a keytab for the same. # The referenced secret must have both "username" and "password" fields. sqlServerAccount: name: sql01user
Create DNS records, or configure the cluster with “writeDNSNames” (see bellow.)
Automated creation of DNS records
If you are using the Active Directory’s integrated DNS server, you can configure DSM to create the necessary DNS records for you. This can be set for each SQL Server cluster individually and regardless whether you configure the cluster with manually-provided keytab.
Instead of Active Directory, you may use any DNS implementation which supports RFC 2136 dynamic DNS updates with Kerberos authentication (RFC 3645), but please note that this hasn’t been extensively tested.
Provide the credentials of a user which can create and update DNS records to DSM
KUBECONFIG=dsm-api-kubeconfig.yaml kubectl create secret generic config-credentials --from-literal=username=my-admin --from-literal=password='<password>'
Create an ActiveDirectoryDomain object for your Active Directory domain using the “config-credentials” Secret created in the previous step as privilegedAccountCredentials. Follow the guidelines from the “Automated creation of Service Principal Names” section to configure the nameserver and trust bundle.
apiVersion: infrastructure.dataservices.vmware.com/v1alpha1 kind: ActiveDirectoryDomain metadata: name: dsmsqlserver.com spec: name: dsmsqlserver.com nameservers: # Only needed if the globally configured DNS nameserver for DSM cannot # resolve dsmsqlserver.com - 10.20.30.40 - 10.20.30.50 trustBundle: # If the domain's LDAP servers TLS certificates are issued by a well-known # authority like DigiCert or GlobalSign, you may skip this section. name: test-domain-trust-bundle privilegedAccountCredentials: # These credentials are required and will be used to create DNS records. # Note that it's the same credentials used to write SPNs as well; if # both modes of automation are enabled on a cluster, the respective user # simply needs to have both sets of privileges. name: config-credentials # If writeDNSNames is specified for the cluster (see bellow), DSM will # execute the updates against this server. If the property is not specified, # DSM will execute the updates against the first nameserver i.e. 10.20.30.40 # in this example. primaryNameserver: 10.20.30.50
Update the SQLServerCluster spec with the Active Directory configuration.
Example:
apiVersion: databases.dataservices.vmware.com/v1alpha1 kind: SQLServerCluster metadata: name: sqlserver-01 namespace: default spec: dnsNames: - sql01.dsmsqlserver.com activeDirectory: domain: name: dsmsqlserver.com sqlServerAccount: name: sql01user # You MAY provide keytab, or let DSM create the SPNs and the keytab in # addition to the DNS records. keytab: name: sql01user-keytab # This instructs DSM to create A record for "sql01.dsmsqlserver.com" # pointing to the cluster's IP address, and a PTR record for the # cluster's IP address pointing back to "sql01.dsmsqlserver.com". # The update is run against the domain's primaryNameserver (see above.) writeDNSNames: ForwardAndReverse
How is the target DNS zone chosen?
For each DNS name that it needs to write, DSM will choose the “narrowest” parent zone of the name for which the domain’s primary nameserver is authoritative.
For example, consider a cluster with dnsNames
sql01.mydbs.myorg.dsmsqlserver.com
.
- First, DSM will ask the primary nameserver whether it has authority
(SOA) over
mydbs.myorg.dsmsqlserver.com
- If the primary nameserver response with authoritative SOA answer for that zone, DSM will create A record there. End.
- Otherwise, DSM will “strip” one more component from the name and repeat the process.
When writing PTR records, DSM follows the same procedure with the PTR
name. For example, a PTR record for IP address 10.20.30.40
has name 40.30.20.10.in-addr.arpa.
. DSM will ask, in
order, about 30.20.10.in-addr.arpa
,
20.10.in-addr.arpa
, and 10.in-addr.arpa
.
Assigning the correct privileges to the ActiveDirectoryDomain’s privileged account
Required privileges for automatic creation of SPNs
DSM uses the privilegedAccountCredentials from the
ActiveDirectoryDomain object to write the Service Principal Names under
the SQL Server’s identity account. This — being able to write to the
servicePrincipalName
property — is the only write privilege
that DSM actually requires. DSM will not attempt write to other
properties, and will not attempt to create users.
The required privilege can be configured using the Microsoft’s
dsacls
utility.
Example 1: configure the privileged account to be able to write the
servicePrincipalName
of all users, assuming that
“CN=Users,DC=dsmsqlserver,DC=com” is the root of the LDAP subtree where
all Active Directory users are located. Change accordingly if your
domain uses different structure, or if you want to limit the privileges
to a subset of users.
/I:S /G "my-admin:RPWP;servicePrincipalName;user" dsacls CN=Users,DC=dsmsqlserver,DC=com
Example 2: configure the privileged account to be able to write the
servicePrincipalName
of a single user (syntax assumes
PowerShell):
-samid sqlserver-user) /G "my-admin:RPWP;servicePrincipalName" dsacls $(dsquery user
Example 3: configure the privileged account to be able to write its
own servicePrincipalName
; this is useful if you prefer to
use the same account as a privileged account and as a SQL Server
identity account.
-samid sqlserver-user) /G "SELF:RPWP;servicePrincipalName" dsacls $(dsquery user
Required privileges for automatic creation of DNS records
Note: the information in this section is specific to the Active Directory DNS server implementation.
Like with SPNs, DSM uses the privilegedAccountCredentials from the ActiveDirectoryDomain object to write DNS records for the SQL Server’s DNS names and IP address. DSM requires the following privileges:
- Create child objects privilege of type “dnsNode” on the zone(s) where the A and PTR records for SQL Server clusters will be created.
- Optional but recommended: Change owner privilege for all child objects of the zone(s) where A and PTR records will be created. This will allow DSM to overwrite existing DNS records, including if you switch from one privileged account to another.
The required privileges can be assigned by:
- Using Active Directory’s DNS server management UI.
- Using the
dsacls
command line utility to modify the permissions on the LDAP subtree which the Active Directory’s DNS implementation uses for storage.
In the examples bellow, replace name of the zone and the default naming context with the names from your own domain.
Example 1: grant privileges to my-admin over the Forward Zone “mydnszone.com”
/G "my-admin:CC;dnsNode"
dsacls DC=mydnszone.com,CN=MicrosoftDNS,DC=DomainDNSZones,DC=dsmsqlserver,DC=com
/G "my-admin:WO" dsacls DC=mydnszone.com,CN=MicrosoftDNS,DC=DomainDNSZones,DC=dsmsqlserver,DC=com
Example 2: grant privileges to my-admin over the Reverse Zone for the 10.20.0.0/16 network.
-addr.arpa,CN=MicrosoftDNS,DC=DomainDNSZones,DC=dsmsqlserver,DC=com /G "my-admin:CC;dnsNode"
dsacls DC=20.10.in
-addr.arpa,CN=MicrosoftDNS,DC=DomainDNSZones,DC=dsmsqlserver,DC=com /G "my-admin:WO" dsacls DC=20.10.in
Create SQL Server logins to enable AD users to login using Windows Authentication
DSM SQL Server automatically restarts and is now ready for you to create Windows logins and enable Active Directory users to login using Windows Authentication.
For example, connect to the SQL Server using the initial local
account provisioned by DSM (referenced in
status.connection
) and run the following commands to create
the login, and confirm that it exists:
CREATE LOGIN [DSMSQLSERVER\aduser]
FROM WINDOWS;
SELECT name
FROM sys.server_principals;
Finally, sign in to a domain-joined Windows machine using
aduser’s domain credentials. Open SQL Server Management
Studio and connect to your DSM SQL Server instance
(e.g. sql01.dsmsqlserver.com
) by specifying Windows
Authentication in the Connect to Server dialog.
Implementation limitations
The current Technical Preview implementation has some limitations w.r.t. the cleanup of the created Active Directory objects.
If you change the cluster’s spec.dnsNames
, the objects
created for the removed entries will be cleaned from Active Directory as
long as they’ve been created by DSM to begin with.
However, in the following scenarios the objects will NOT be deleted and will have to cleaned up manually:
- If you delete the SQLServerCluster
- If you remove the SQLServerCluster’s Active Directory integration
configuration i.e. remove the
spec.activeDirectory
property. - The Service Principal Names will not be removed from the old account
if you change the cluster’s server identity account i.e. if you change
spec.activeDirectory.sqlServerAccount
to identify another user.