Enable RADIUS-Based MFA for Directory Service
Overview
This check validates whether your AWS Directory Service directories have RADIUS-based multi-factor authentication (MFA) enabled. When enabled, users must provide both their password and a one-time code from an MFA device to authenticate, significantly strengthening access security.
Risk
Without MFA enabled, user authentication relies solely on passwords. This creates vulnerability to:
- Credential theft through phishing attacks
- Password spraying and brute-force attacks
- Unauthorized access if passwords are compromised or leaked
- Lateral movement and privilege escalation within connected AWS services
Remediation Steps
Prerequisites
- A working RADIUS server (such as Microsoft NPS, FreeRADIUS, or a commercial MFA solution like Duo, Okta, or RSA SecurID)
- Network connectivity between your Directory Service VPC and the RADIUS server
- The shared secret configured on your RADIUS server
- AWS Console access with permissions to modify Directory Service settings
Required IAM permissions
Your IAM user or role needs the following permissions:
ds:EnableRadiusds:DescribeDirectoriesds:DisableRadius(for troubleshooting/updates)
RADIUS server network requirements
Before enabling RADIUS MFA, ensure:
- Your RADIUS server is reachable from the Directory Service VPC
- Security groups allow outbound traffic on the RADIUS port (typically UDP 1812)
- The RADIUS server is configured to accept connections from the Directory Service domain controllers
- You have tested RADIUS connectivity independently
AWS Console Method
- Open the AWS Directory Service console
- In the navigation pane, choose Directories
- Click on the Directory ID of your target directory
- Select the Networking & security tab
- Scroll down to the Multi-factor authentication section
- Click Actions, then select Enable
- Enter your RADIUS configuration:
- RADIUS server IP address(es): Enter one or more RADIUS server IPs or DNS names
- Port: Usually 1812 (the standard RADIUS authentication port)
- Shared secret code: The secret configured on your RADIUS server
- Confirm shared secret code: Re-enter the shared secret
- Protocol: Select the authentication protocol your RADIUS server uses (typically MS-CHAPv2)
- Server timeout: How long to wait for a response (10-30 seconds recommended)
- Max retries: Number of retry attempts (3 is typical)
- Click Enable
The RADIUS status will show Creating initially. Wait for it to change to Completed.
AWS CLI (optional)
Enable RADIUS MFA via CLI
First, identify your directory ID:
aws ds describe-directories \
--region us-east-1 \
--query "DirectoryDescriptions[*].[DirectoryId,Name,Type]" \
--output table
Enable RADIUS MFA:
aws ds enable-radius \
--directory-id d-1234567890 \
--radius-settings '{
"RadiusServers": ["radius.example.com"],
"RadiusPort": 1812,
"RadiusTimeout": 10,
"RadiusRetries": 3,
"SharedSecret": "YourSharedSecretHere",
"AuthenticationProtocol": "MS-CHAPv2"
}' \
--region us-east-1
Replace the following placeholders:
d-1234567890: Your directory IDradius.example.com: Your RADIUS server IP or hostnameYourSharedSecretHere: The shared secret configured on your RADIUS server
RadiusSettings parameters
| Parameter | Description | Constraints |
|---|---|---|
RadiusServers | IP addresses or FQDNs of RADIUS endpoints | List of strings |
RadiusPort | RADIUS authentication port | 1025-65535 (default: 1812) |
RadiusTimeout | Seconds to wait for response | 1-50 |
RadiusRetries | Maximum retry attempts | 0-10 |
SharedSecret | Shared secret for RADIUS authentication | 8-512 characters |
AuthenticationProtocol | Protocol used | PAP, CHAP, MS-CHAPv1, or MS-CHAPv2 |
CloudFormation (optional)
AWS CloudFormation does not natively support configuring RADIUS MFA settings for Directory Service. You must use one of these alternatives:
Option 1: AWS CLI in a Custom Resource
AWSTemplateFormatVersion: '2010-09-09'
Description: Enable RADIUS MFA for AWS Directory Service using Custom Resource
Parameters:
DirectoryId:
Type: String
Description: The ID of the directory (e.g., d-1234567890)
AllowedPattern: ^d-[0-9a-f]{10}$
RadiusServer:
Type: String
Description: IP address or FQDN of your RADIUS server
RadiusSharedSecret:
Type: String
NoEcho: true
Description: Shared secret for RADIUS authentication
MinLength: 8
Resources:
EnableRadiusFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: EnableDirectoryServiceRadius
Runtime: python3.11
Handler: index.handler
Timeout: 60
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
ds = boto3.client('ds')
directory_id = event['ResourceProperties']['DirectoryId']
if event['RequestType'] == 'Delete':
try:
ds.disable_radius(DirectoryId=directory_id)
except Exception as e:
print(f"Error disabling RADIUS: {e}")
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
return
try:
ds.enable_radius(
DirectoryId=directory_id,
RadiusSettings={
'RadiusServers': [event['ResourceProperties']['RadiusServer']],
'RadiusPort': 1812,
'RadiusTimeout': 10,
'RadiusRetries': 3,
'SharedSecret': event['ResourceProperties']['SharedSecret'],
'AuthenticationProtocol': 'MS-CHAPv2'
}
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {'Status': 'Enabled'})
except Exception as e:
cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: DirectoryServiceRadius
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ds:EnableRadius
- ds:DisableRadius
Resource: !Sub arn:aws:ds:${AWS::Region}:${AWS::AccountId}:directory/${DirectoryId}
EnableRadiusCustomResource:
Type: Custom::EnableRadius
Properties:
ServiceToken: !GetAtt EnableRadiusFunction.Arn
DirectoryId: !Ref DirectoryId
RadiusServer: !Ref RadiusServer
SharedSecret: !Ref RadiusSharedSecret
Option 2: Post-deployment CLI command
After deploying your directory via CloudFormation, run the aws ds enable-radius command separately as shown in the CLI section above.
Terraform (optional)
variable "directory_id" {
description = "The ID of the AWS Directory Service directory"
type = string
# Example: d-1234567890
}
variable "radius_servers" {
description = "List of RADIUS server IP addresses or FQDNs"
type = list(string)
}
variable "radius_shared_secret" {
description = "Shared secret for RADIUS authentication"
type = string
sensitive = true
}
variable "radius_port" {
description = "Port on which RADIUS server is listening"
type = number
default = 1812
}
variable "radius_timeout" {
description = "Timeout in seconds for RADIUS requests"
type = number
default = 10
}
variable "radius_retries" {
description = "Number of retries for RADIUS requests"
type = number
default = 3
}
variable "authentication_protocol" {
description = "RADIUS authentication protocol"
type = string
default = "MS-CHAPv2"
validation {
condition = contains(["PAP", "CHAP", "MS-CHAPv1", "MS-CHAPv2"], var.authentication_protocol)
error_message = "Authentication protocol must be one of: PAP, CHAP, MS-CHAPv1, MS-CHAPv2."
}
}
resource "aws_directory_service_radius_settings" "mfa" {
directory_id = var.directory_id
radius_servers = var.radius_servers
radius_port = var.radius_port
radius_timeout = var.radius_timeout
radius_retries = var.radius_retries
shared_secret = var.radius_shared_secret
authentication_protocol = var.authentication_protocol
}
output "radius_status" {
description = "Status of RADIUS MFA configuration"
value = aws_directory_service_radius_settings.mfa.id
}
Apply the configuration:
terraform init
terraform apply \
-var="directory_id=d-1234567890" \
-var='radius_servers=["radius.example.com"]' \
-var="radius_shared_secret=YourSharedSecretHere"
Verification
After enabling RADIUS MFA:
- Return to the Networking & security tab of your directory
- Check that the Multi-factor authentication status shows Completed
- Test by logging into a service that uses the directory (such as WorkSpaces or an AD-joined EC2 instance)
- Verify that users are prompted for their MFA token after entering their password
CLI verification commands
Check RADIUS MFA status:
aws ds describe-directories \
--directory-id d-1234567890 \
--region us-east-1 \
--query "DirectoryDescriptions[0].RadiusSettings"
The output should show your RADIUS configuration with RadiusStatus as Completed.
Check overall directory status:
aws ds describe-directories \
--directory-id d-1234567890 \
--region us-east-1 \
--query "DirectoryDescriptions[0].{DirectoryId:DirectoryId,Name:Name,RadiusStatus:RadiusStatus}"
Troubleshooting RADIUS issues
If RADIUS status shows Failed:
- Verify network connectivity: Ensure the Directory Service domain controllers can reach your RADIUS server on the specified port
- Check security groups: Confirm outbound UDP traffic to the RADIUS port is allowed
- Validate shared secret: The shared secret must match exactly on both sides
- Test RADIUS server: Use
radtestor a similar tool to verify your RADIUS server is responding - Check RADIUS server logs: Look for authentication attempts from the Directory Service IP addresses
- Protocol mismatch: Ensure the authentication protocol matches what your RADIUS server expects
To disable and retry:
aws ds disable-radius \
--directory-id d-1234567890 \
--region us-east-1
Then re-enable with corrected settings.
Additional Resources
- Enable Multi-Factor Authentication for AWS Managed Microsoft AD
- Enable Multi-Factor Authentication for AD Connector
- RADIUS Protocol Overview
- AWS Directory Service Best Practices
Notes
- Supported directory types: RADIUS MFA is available for AWS Managed Microsoft AD and AD Connector. Simple AD does not support RADIUS MFA.
- High availability: Consider configuring multiple RADIUS servers for redundancy. AWS Directory Service will try each server in order.
- User experience: After enabling MFA, all users authenticating through the directory will need MFA tokens. Ensure users are enrolled with your MFA provider before enabling.
- Service interruption: Enabling MFA takes effect immediately. Plan the rollout to avoid disrupting users.
- Fallback behavior: If RADIUS servers are unreachable, authentication will fail. This is a security feature but may cause access issues during RADIUS outages.
- Testing: Test with a small group of users before organization-wide rollout.