[Update] Kerberos authentication is now supported when joining RDS for SQL Server to a self-managed Active Directory domain
Shibata here.
As the title suggests, recently AWS announced support for Kerberos authentication when connecting to RDS for SQL Server joined to a self-managed Active Directory domain.
Here is the announcement from AWS:
The capability to join RDS for SQL Server to a self-managed Active Directory domain was supported two years ago, but at that time Kerberos authentication was not supported, and only NTLM authentication was possible.
With this update, Kerberos authentication is now possible even when joining to a self-managed Active Directory domain.
Details of the Update
To newly support Kerberos authentication, the following configuration changes were made:
- Some changes to the self-managed Active Directory side configuration
- Additional permission settings related to Kerberos authentication are now required
- A dedicated hostname (CNAME) for Kerberos authentication is automatically registered
The dedicated hostname follows this format:
<RDS instance name>
.<hash value>
.region name
.awsrds.<AD domain FQDN>
A CNAME record is registered in DNS with this hostname, and Kerberos authentication is used when connecting to this hostname.
Other Limitations
The descriptions of limitations other than the authentication method have slightly changed, but they appear to be the same as before.
- Your DB instances sync with AWS's NTP service and not the AD domain's time server. For database connections between linked SQL Server instances within your AD domain, you can only SQL authentication and not Windows authentication.
- Group Policy Object settings from your self-managed AD domain are not be propagated to your RDS for SQL Server instances.
Testing It Out
From here, I'll actually test this functionality.
I'll create an environment similar to the previous article, but since the environment setup procedure is slightly different this time, I'll introduce it again.
0. Architecture Diagram
The configuration is almost the same as before.
I'll prepare a Windows Server 2022 EC2 instance to serve as a domain controller in a pre-configured VPC, and set up an RDS for SQL Server 2022 Standard Edition environment in the same subnet for testing.
This time, I've updated the SQL Server version from 2019 to 2022.### 1. Preparing the Domain Controller
The EC2 that will become the domain controller is created from the latest Japanese version of Windows Server 2022 AMI as of today.
ami-0dd93ac55dfdc376a
: Windows_Server-2022-Japanese-Full-Base-2025.08.13
The EC2 instance creation procedure is omitted.
Also, the security group has been configured to open the ports specified in the prerequisites.
Building the Active Directory domain
The self-managed Active Directory domain corp.contoso.com
was built using the following PowerShell commands.
# Adding Windows features
Add-WindowsFeature AD-Domain-Services, GPMC, RSAT-ADDS, RSAT-AD-PowerShell, RSAT-DNS-Server | Format-List
# Creating domain + restart
Import-Module ADDSDeployment
$params = @{
DomainName = 'corp.contoso.com';
DomainNetbiosName = 'CORP';
ForestMode = 'WinThreshold';
DomainMode = 'WinThreshold';
DatabasePath = 'C:\Windows\NTDS';
LogPath = 'C:\Windows\NTDS';
SysvolPath = 'C:\Windows\SYSVOL';
SafeModeAdministratorPassword = (ConvertTo-SecureString 'P@ssword' -AsPlainText -Force);
InstallDns = $true;
CreateDnsDelegation = $false;
NoRebootOnCompletion = $false;
Confirm = $false;
}
Install-ADDSForest @params
```#### Creating dedicated OU and dedicated user
After the domain is set up, we need to prepare:
* A dedicated OU for RDS instances
* A dedicated user for joining RDS instances to the domain
It remains recommended by AWS to create a dedicated OU and management user.
> We recommend creating a dedicated OU and service credential scoped to that OU for any AWS account that owns an RDS for SQL Server DB instance joined your self-managed AD domain. By dedicating an OU and service credential, you can avoid conflicting permissions and follow the principal of least privilege.
* [Step 1: Create an Organizational Unit in your AD](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_SQLServer_SelfManagedActiveDirectory.SettingUp.html)
In this case, we'll create:
* `RDSInstances` OU
* `rdssql@corp.contoso.com` management user
using the following PowerShell commands.
```powershell:PowerShell
# Prepare a dedicated OU called RDSInstances
New-ADOrganizationalUnit -Name 'RDSInstances' -Path 'DC=corp,DC=contoso,DC=com'
# Create rdssql user
$params = @{
Name = 'rdssql';
UserPrincipalName = 'rdssql@corp.contoso.com';
Description = 'RDS for SQL Server service user';
AccountPassword = ConvertTo-SecureString -AsPlainText 'P@ssword' -Force;
Enabled = $true;
PasswordNeverExpires = $true;
}
New-ADUser @params
Dedicated OU
Dedicated user#### Setting permissions for dedicated user (delegating control)
Next, we'll grant necessary permissions to the rdssql@corp.contoso.com
user.
This part differs slightly from conventional methods.
First, start "Active Directory Users and Computers," right-click on RDSInstancesOU, and click "Delegate Control."
When the wizard starts, click "Next."
Add the rdssql@corp.contoso.com
user to the selected users and groups, then click "Next."
For tasks to delegate, select "Create a custom task to delegate" and click "Next."
Select target objects as shown below and click "Next."
- Select "Only the following objects in the folder"
- Check "Computer objects"
- Check "Create selected objects in this folder"
- Check "Delete selected objects in this folder"
Select permissions as shown below and click "Next."
- Check "General"
- Check the following permissions in the permissions section:
- "Validated write to DNS host name"
- "Validated write to service principal name"
- Check the following permissions in the permissions section:
- NEW! : Additionally check "Property-specific"
- Check the following permission in the permissions section:
- "Write servicePrincipalName"
- Check the following permission in the permissions section:
Finally, verify that the specified settings are correct and click "Finish."
You have chosen to delegate control of the following
Active Directory folder objects:
corp.contoso.com/RDSInstances
The group, user, or computer
given control:
rdssql (rdssql@corp.contoso.com)
The following permissions are granted:
Validated write to DNS host name
Validated write to service principal name
Write servicePrincipalName
For the following object types:
Computer
Now the rdssql@corp.contoso.com
user has the specified permissions for the RDSInstancesOU
.
Next, open "DNS Manager (dnsmgmt.msc
)", right-click on the server column and select "Properties".
In the Properties panel, select the "Security" tab and add read permissions for the rdssql@corp.contoso.com
user.
This completes the preparation of the domain controller.### 2. KMS Preparation
Next, we will prepare KMS.
Due to the need for RDS service to decrypt the KMS key, we need to create a new customer-managed key with a custom key policy.
This part remains unchanged from before; this time we'll create a key named rds-for-sql-server-self-managed-ad-2
from CloudShell.
# KMS key creation : rds-for-sql-server-self-managed-ad-2
# * Symmetric key
# * Usage is "Encrypt and decrypt"
# * KMS origin
# * Single-region key
kms_key_id=$(aws kms create-key --description 'Key for RDS for SQL Server with self managed AD' \
--key-usage 'ENCRYPT_DECRYPT' \
--origin 'AWS_KMS' \
--no-multi-region \
--query 'KeyMetadata.KeyId' \
--output text)
echo $kms_key_id
# Assign alias
aws kms create-alias --alias-name 'alias/rds-for-sql-server-self-managed-ad-2' \
--target-key-id $kms_key_id
# Add permissions : customize as needed for your environment
key_policy=$(cat << EOF
{
"Version": "2012-10-17",
"Id": "key-default-1",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::$(aws sts get-caller-identity --query 'Account' --output text):root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the KMS key on behalf of RDS",
"Effect": "Allow",
"Principal": {
"Service": [
"rds.amazonaws.com"
]
},
"Action": "kms:Decrypt",
"Resource": "*"
}
]
}
EOF
)
aws kms put-key-policy --key-id $kms_key_id --policy "$key_policy"
Customize the key policy according to your environment### 3. Preparing Secrets Manager
Next, we'll create a new secret in Secrets Manager.
This follows the same procedure as before
CUSTOMER_MANAGED_ACTIVE_DIRECTORY_USERNAME
: Dedicated user name (in this caserdssql@corp.contoso.com
)CUSTOMER_MANAGED_ACTIVE_DIRECTORY_PASSWORD
: Plain text password for the dedicated user
It's sufficient to create a secret with these two keys that can be decrypted by RDS.
This time we'll create a secret named rds-for-sql-server-self-managed-ad-2
using CloudShell.
# Create a secret for RDS for SQL Server
# * Specify the key created in the previous section as the KMS key
aws secretsmanager create-secret \
--name "rds-for-sql-server-self-managed-ad-2" \
--description "Secrets for RDS for SQL Server with self managed AD" \
--secret-string "{\"CUSTOMER_MANAGED_ACTIVE_DIRECTORY_USERNAME\":\"rdssql@corp.contoso.com\",\"CUSTOMER_MANAGED_ACTIVE_DIRECTORY_PASSWORD\":\"P@ssword\"}" \
--kms-key-id $kms_key_id
# Customize the resource policy according to your environment
account_id=$(aws sts get-caller-identity --query 'Account' --output text)
resource_policy=$(cat << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "rds.amazonaws.com"
},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:sourceAccount": "$account_id"
},
"ArnLike": {
"aws:sourceArn": "arn:aws:rds:ap-northeast-1:$account_id:db:*"
}
}
}
]
}
EOF
)
aws secretsmanager put-resource-policy \
--secret-id "rds-for-sql-server-self-managed-ad-2" \
--resource-policy "$resource_policy" \
--block-public-policy
If it looks like the following figures, you're good to go.
### 4. Creating an RDS Instance
Now we will create an RDS instance.
This article only covers the parts necessary for domain joining.
For sections not mentioned, please configure them according to your environment as appropriate.
In this case, we're using RDS for SQL Server 2022 Standard Edition with the latest engine version SQL Server 2022 16.00.4205.1.v1
.
In the Microsoft SQL Server Windows Authentication section, check "Enable Microsoft SQL Server Windows Authentication" and select the "Self-managed Microsoft Active Directory" option.
Other than the interface being in Japanese, the settings remain unchanged, and you should enter as follows:
Name | Purpose | Setting Value |
---|---|---|
Fully Qualified Domain Name | Join Domain | Specify FQDN (corp.contoso.com ) |
Domain Organizational Unit | OU name for RDS Instance | Specify Distinguished Name (OU=RDSInstances,DC=corp,DC=contoso,DC=com ) |
Authentication Credentials Secret ARN | Authentication Credentials | Specify ARN (ARN of rds-for-sql-server-self-managed-ad-2 ) |
Primary DNS | DNS Server | Specify IP Address |
Secondary DNS | DNS Server | Specify IP Address (required) |
If you can create the RDS instance without errors, then you're good to go.
Verify that the directory status shows "Joined".
### 5. Checking DNS Configuration
If there are no problems with the configuration, a CNAME record specifically for Kerberos authentication will be set up along with the creation of the RDS instance.
In this case, the alias became testdb.xxxxxxxxxxxx.ap-northeast-1.awsrds.corp.contoso.com
.
# Check records with nslookup command
PS C:\> nslookup testdb.xxxxxxxxxxxx.ap-northeast-1.awsrds.corp.contoso.com
Server: localhost
Address: ::1
Name: EC2AMAZ-UD2HTRU.corp.contoso.com
Address: 10.0.21.20
Aliases: testdb.xxxxxxxxxxxx.ap-northeast-1.awsrds.corp.contoso.com
When I checked the status of SPN registration, it was as follows:
# Search for SQL Server (MSSQLSvc) SPNs
PS C:\> setspn -T * -F -Q MSSQLSvc/*
Checking forest DC=corp,DC=contoso,DC=com
CN=EC2AMAZ-UD2HTRU,OU=RDSInstances,DC=corp,DC=contoso,DC=com
MSSQLSvc/EC2AMAZ-UD2HTRU.corp.contoso.com:1433
MSSQLSvc/EC2AMAZ-UD2HTRU.corp.contoso.com
MSServerClusterMgmtAPI/EC2AMAZ-UD2HTRU
MSServerClusterMgmtAPI/EC2AMAZ-UD2HTRU.corp.contoso.com
TERMSRV/EC2AMAZ-UD2HTRU
TERMSRV/EC2AMAZ-UD2HTRU.corp.contoso.com
WSMAN/EC2AMAZ-UD2HTRU
WSMAN/EC2AMAZ-UD2HTRU.corp.contoso.com
RestrictedKrbHost/EC2AMAZ-UD2HTRU
HOST/EC2AMAZ-UD2HTRU
RestrictedKrbHost/EC2AMAZ-UD2HTRU.corp.contoso.com
HOST/EC2AMAZ-UD2HTRU.corp.contoso.com
The fact that SPNs are registered to the actual RDS for SQL Server instance (EC2AMAZ-UD2HTRU
) remains unchanged.
I thought SPNs would also be registered for the alias (the awsrds.corp.contoso.com
part), but it seems that in the case of CNAMEs, having SPNs only for the actual hostname is sufficient.### 6. Connection Verification
After properly configuring the "Login" settings, let's connect from SQLCMD to both the default endpoint and the newly provided alias to confirm the authentication methods used for each.
# Connection to the default endpoint: NTLM authentication
sqlcmd -S testdb.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -H "from ADDS (default endpoint)"
# Connection to the new alias: Kerberos authentication
sqlcmd -S testdb.xxxxxxxxxxxx.ap-northeast-1.awsrds.corp.contoso.com -H "from ADDS (new CNAME)"
As expected, the connection to the default endpoint uses NTLM authentication, while the connection to the alias uses Kerberos authentication.
That looks good.
Side Note: About Errors
When I first performed this verification, I forgot to set up the permissions for the DNS server, which resulted in errors after the setup.
In such cases, while the RDS instance creation completes, an error is recorded in the RDS events.
RDS was unable to configure the Kerberos endpoint in your domain. This might prevent Kerberos authentication for your DB instance. Verify the network configuration between your DB instance and domain controllers.
Make sure to check the event logs after building your RDS instance.
Incidentally, once I set the permissions for the DNS server, the CNAME record was created fairly quickly.
Based on this behavior, I suspect that RDS instances that were previously joined to self-managed Active Directory domains might also have permission-related errors. While AWS documentation doesn't mention remediation for existing environments, it's likely that just updating the permissions for the management user (in this case, rdssql@corp.contoso.com
) should be sufficient.
In Conclusion
That's all for this walkthrough.
This may seem like a minor update, but I believe it's a useful one, so give it a try if you have the opportunity.