AWS Systems Manager Fleet Manager — Connect to Windows EC2 Instance Privately without Opening RDP ports
One of the most important and priority task for any Security, IT Administrators is how effectively they can control the access to Linux and Windows servers by limiting SSH and RDP(Remote Desktop Protocol) access. It’s not advisable to expose the administration ports of your instances (RDP 3389 and SSH 22) to internet because adversaries could try to leverage a vulnerability to access and take control or they could achieve access through brute force attacks.
Previously we used to use bastion hosts, which were hardened instances with security features to mitigate the risk of having that instance exposed. The use of bastion hosts is better than granting direct access to the instances opening their RDP/SSH ports. However, currently there is a better way using AWS Systems Manager.
In this blog, I will walk you through the steps of using AWS Systems Manager Fleet Manager and access Windows Instance in the private subnet from the browser without the need to open port 3389 as the connection is initiated from the agent.
Pre Requisites:
- VPC with Subnets and Route tables
- Access to Create IAM roles and policies
Step 1: Create 3 interface endpoints (ssm, ssmmessages and ec2messages)
Endpoints help us to connect privately without internet access. In one of my blogs I have walked to you through the step by step process to create Interface endpoints.
Step 2: Create KMS Key
Go to KMS in AWS Console and create a KMS key.
Step 3: Create an IAM Policy
Create an IAM policy named EC2-Fleet-Test-policy with below permissions. From the previous step fetch the ARN of the KMS key and add it to the policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2",
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:DescribeInstances",
"ec2:DescribeTags"
],
"Resource": "*"
},
{
"Sid": "General",
"Effect": "Allow",
"Action": [
"ssm:AddTagsToResource",
"ssm:DescribeInstanceAssociationsStatus",
"ssm:DescribeInstancePatches",
"ssm:DescribeInstancePatchStates",
"ssm:DescribeInstanceProperties",
"ssm:GetCommandInvocation",
"ssm:GetServiceSetting",
"ssm:GetInventorySchema",
"ssm:ListComplianceItems",
"ssm:ListInventoryEntries",
"ssm:ListTagsForResource",
"ssm:ListCommandInvocations",
"ssm:ListAssociations",
"ssm:RemoveTagsFromResource"
],
"Resource": "*"
},
{
"Sid": "SendCommand",
"Effect": "Allow",
"Action": [
"ssm:GetDocument",
"ssm:SendCommand",
"ssm:StartSession"
],
"Resource": [
"arn:aws:ec2:*:088585194665:instance/*",
"arn:aws:ssm:*:088585194665:managed-instance/*",
"arn:aws:ssm:*:088585194665:document/SSM-SessionManagerRunShell",
"arn:aws:ssm:*:*:document/AWS-PasswordReset",
"arn:aws:ssm:*:*:document/AWSFleetManager-AddUsersToGroups",
"arn:aws:ssm:*:*:document/AWSFleetManager-AWSFleetManager-CopyFileSystemItem",
"arn:aws:ssm:*:*:document/AWSFleetManager-CreateDirectory",
"arn:aws:ssm:*:*:document/AWSFleetManager-CreateGroup",
"arn:aws:ssm:*:*:document/AWSFleetManager-CreateUser",
"arn:aws:ssm:*:*:document/AWSFleetManager-CreateUserInteractive",
"arn:aws:ssm:*:*:document/AWSFleetManager-CreateWindowsRegistryKey",
"arn:aws:ssm:*:*:document/AWSFleetManager-DeleteGroup",
"arn:aws:ssm:*:*:document/AWSFleetManager-DeleteUser",
"arn:aws:ssm:*:*:document/AWSFleetManager-DeleteWindowsRegistryKey",
"arn:aws:ssm:*:*:document/AWSFleetManager-DeleteWindowsRegistryValue",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetFileContent",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetFileSystemContent",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetGroups",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetPerformanceCounters",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetProcessDetails",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetUsers",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetWindowsEvents",
"arn:aws:ssm:*:*:document/AWSFleetManager-GetWindowsRegistryContent",
"arn:aws:ssm:*:*:document/AWSFleetManager-MoveFileSystemItem",
"arn:aws:ssm:*:*:document/AWSFleetManager-RemoveUsersFromGroups",
"arn:aws:ssm:*:*:document/AWSFleetManager-RenameFileSystemItem",
"arn:aws:ssm:*:*:document/AWSFleetManager-SetWindowsRegistryValue",
"arn:aws:ssm:*:*:document/AWSFleetManager-StartProcess",
"arn:aws:ssm:*:*:document/AWSFleetManager-TerminateProcess"
],
"Condition": {
"BoolIfExists": {
"ssm:SessionDocumentAccessCheck": "true"
}
}
},
{
"Sid": "TerminateSession",
"Effect": "Allow",
"Action": [
"ssm:TerminateSession"
],
"Resource": "*",
"Condition": {
"StringLike": {
"ssm:resourceTag/aws:ssmmessages:session-id": [
"${aws:userid}"
]
}
}
},
{
"Sid": "KMS",
"Effect": "Allow",
"Action": [
"kms:GenerateDataKey"
],
"Resource": [
"arn:aws:kms:us-east-1:111111111111:key/knvjdndfvnhjnjh"
]
}
]
}
Step 4: Create One IAM role “EC2-Fleet-Test-Role”
Create an IAM role and attach the below policies.
Step 4: Attach the IAM role as Instance Profile to the EC2 Instance
Step 5: Login to the EC2 instance from the bastion host for the first time and install SSM Agent.
The SSM agent can be downloaded from below location.
https://amazon-ssm-us-east-2.s3.us-east-2.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe
- Once you Download that SSM agent, install the agent.
- Go to the search bar and you will able to see the SSM agent running.
Once you install the SSM Agent take an AMI of the Instance and use it for launching future instances so that you can avoid this step.
Step 6: Go to Session Manager and Open Fleet Manager
As we attched the Instance profile and have installed SSM agent we can now access the EC2 instance in Fleet Manager. In order to view, go to System manager and in the left pane click on Fleet Manager.
Select the EC2 instance and under the Node Actions click on ‘Connect with Remote Desktop.
Step 7: Provide Credentials to RDP into the Instance
Bingo !!!!
We are able to successfully RDP into the Windows instance without opening 3389 port in the security group.