AWS Systems Manager (AWS SSM) Hybrid Activation - Windows.

Dilaawez KhanDilaawez Khan
8 min read

AWS Systems Manager as the name suggests is a infrastructure wide configuration mangement toll. It can manage both AWS hosted instances and on-Prem instance. Let's do on-Prem server activation in AWS Systems Manager in order to manager it.

Connectivity

Generally in organizations DEV servers have internet access however PROD servers have network access restricted. If our on-Prem windows server has limited network access then the on-Prem server should have outbound connectivity with following AWS Systems Manager endpoints at port 443.

ssm.region.amazonaws.com

ssm.messages.region.amazonaws.com

ec2messages.region.amazonaws.com

NOTE: SSM agent initiates all connections to AWS Systems Manager hence inbound access to server on firewall is not required.

If the server is behind a proxy the environment variable for the proxy must be set in the current shell based on whether its HTTP or HTTPS.

HTTP

http_proxy=http://hostname:port
https_proxy=http://hostname:port

HTTPS

http_proxy=http://hostname:port
https_proxy=https://hostname:port

Service Role

This IAM service role is required by ssm agent installed on on-Prem servers to make connection with AWS Systems Manager and vice-versa. It grants AWS STS AssumeRole trust to the systems manager service.

Login to AWS console-->Go to IAM-->Roles-->Create role-->AWS Service-->Under 'use case for other AWS services' search for 'systems manager'--> select Systems Manager radio button-->Next

SSM_Role.PNG

We have selected the trusted entity here which is Systems Manager now on current page we have to select a policy that has the access (permission) defined, we'll use an AWS managed policy AmazonSSMManagedInstanceCore to provide permissions to Systems Manager.

NOTE: Here you can add more managed policies based on what you want AWS Systems Manager role to do.

SSM_Role-1.PNG

Select the policy and click next--> Give it a name AWS-Systems-Manager-Role-->Create Role.

Role is created!

Here we can create more policies (permissions) for Systems Manager apart from SSM services. Let's give Systems Manager access to s3. But before that create a bucket in s3 to do a demo with objects.

C:\>aws s3api create-bucket --bucket ssm-demo-bucket-01 --profile Administrator
{
    "Location": "/ssm-demo-bucket-01"
}

copy/type the arn arn:aws:s3:::ssm-demo-bucket-01

Now move on to creating policy

Go to Roles-->Select AWS-Systems-Manager-Role-->on Permissions tab-->Click Add Permissions-->Create inline policy.

Role-1.PNG

It takes you to this screen. Select s3 in Service then in Actions under Access Level-->List select just ListAllMyBuckets.

It does not require any Resource selection since it applies to all.

List_bucket.JPG

If you want to work with the bucket ssm-demo-bucket-01 we have created before, click on Add additional permissions

Additional_permissions.JPG

Again do, select s3 in Service then in Actions under Access Level-->Under...

Read select GetObject (to list the objects within bucket.)

Write select PutObject (To upload the objects.)

Then under Resources keep Specific radio button selected and click on Add ARN

Add s3 bucket ARN like this arn:aws:s3:::ssm-demo-bucket-01/* here. By adding /* it denotes everything under the bucket.

Add_ARN-1.JPG

And click on Add.-->Review Policy-->Give it a Name s3-list-bucket-->Create policy.

We have provided the Systems Manager role access to list all buckets and work on one s3 bucket- ssm-demo-bucket-01.

on-Prem Server Activation

Now we will create an activation which is a process by which AWS Systems Manager on boards an on-Prem server to be managed from it.

Go to AWS console and search for Systems Manager. Select and open it then on the left hand side under Node Management --> select Hybrid Activations --> click button Create an Activation.

ssm-2.PNG

Activation description- Optional - SSM-test-activation

Instance limit - 1

IAM role - Select AWS-Systems-Manager-Role

Activation expiry date - I gave it 2022-07-30 10:10+5:30

Default instance name- Optional - Windows-2019-SSM

Click Create activation

SSM-3.JPG

SSM-4.JPG

Be careful here since both Activation Code and Activation ID will not be available once you move away from this page. Ensure both the codes are copied completely and verify.

ssm-3.png

Now since we are armed with the codes lets move to a different territory, our on-Prem server.

Login to on-Prem server with Administrator level access.

This is the script which is required to be run on on-Prem server. Analyse each line for its function.

$code = "PASTE-ACTIVATION-CODE"
$id = "PASTE-ACTIVATION-CODE"
$region = "REGION"
$dir = $env:TEMP + "\ssm"
New-Item -ItemType directory -Path $dir -Force
cd $dir
(New-Object System.Net.WebClient).DownloadFile("https://amazon-ssm-$region.s3.$region.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe", $dir + "\AmazonSSMAgentSetup.exe")
Start-Process .\AmazonSSMAgentSetup.exe -ArgumentList @("/q", "/log", "install.log", "CODE=$code", "ID=$id", "REGION=$region") -Wait
Get-Content ($env:ProgramData + "\Amazon\SSM\InstanceData\registration")
Get-Service -Name "AmazonSSMAgent"

Open PowerShell_ise on on-Prem server, paste the script with all required values replaced and run it. It should show output as following.

PS C:\> $code = "ACTIVATION-CODE"
$id = "ACTIVATION-ID"
$region = "us-east-1"
$dir = $env:TEMP + "\ssm"
New-Item -ItemType directory -Path $dir -Force
cd $dir
(New-Object System.Net.WebClient).DownloadFile("https://amazon-ssm-$region.s3.$region.amazonaws.com/latest/windows_amd64/AmazonSSMAgentSetup.exe", $dir + "\AmazonSSMAgentSetup.exe")
Start-Process .\AmazonSSMAgentSetup.exe -ArgumentList @("/q", "/log", "install.log", "CODE=$code", "ID=$id", "REGION=$region") -Wait
Get-Content ($env:ProgramData + "\Amazon\SSM\InstanceData\registration")
Get-Service -Name "AmazonSSMAgent"


    Directory: C:\Users\<username>\AppData\Local\Temp


Mode                LastWriteTime         Length Name                                                                                         
----                -------------         ------ ----                                                                                         
d-----        /15/2022  10:07 AM                ssm                                                                                          
{"ManagedInstanceID":"mi-0a677d17a2e595e06","Region":"us-east-1"}

Status      : Running
Name        : AmazonSSMAgent
DisplayName : Amazon SSM Agent

Once Amazon SSM Agent is installed on local server it makes a contact to AWS Systems Manager endpoint on port 443 which then identifies the request based on the Activation ID and Activation code and activates the connection with a ManagedInstanceID. For AWS Systems Manager this ID is the server identifier.

It has created following folders. You might not have access to first one. But with Admin account access can be obtained.

C:\Program Files\Amazon\SSM
C:\ProgramData\Amazon\SSM

SSM_Prog_File.JPG

SSM_Pro.JPG

If there is an error check the log file from here.

C:\ProgramData\Amazon\SSM\Logs

Go to services and check that following service is created and must be running.

Display Name : Amazon SSM Agent

Service Name : AmazonSSMAgent

Running from path : "C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe"

AWS_SSM_Service.png

This service runs under the LOCAL SYSTEM ACCOUNT in the OS which means highest privileges!! So when AWS Systems Manager gives a command to managed instance (on-Prem) the AWS-Systems-Manager-Role contacts Amazon SSM Agent running locally on server which in turn use Local System Account to execute it. So imagine what can be done and how it can be controlled.

NOTE: Whenever any changes are made locally on server related to AWS Systems Manager restart this service so that changes are recorded by Amazon SSM Agent.

Install AWS CLI V2 on-Prem Windows server.

If you run aws s3 ls from on-Prem server. you will get error.

PS C:\Users\Administrator> aws s3 ls

Unable to locate credentials. You can configure credentials by running "aws configure".

But why?? all permissions and role is set up! lets check the identity which is providing permissions to our AWS shell session.

{
    "UserId": "AROAWB7BAEB5ECI5G2KGV:mi-0a677d17a2e595e06",
    "Account": "123456789101",
    "Arn": "arn:aws:sts::123456789101:assumed-role/AWS-Systems-Manager-Role/mi-0a677d17a2e595e06"
}

Well the role is ok and mi id of instance is same as was in activation output. Still??

That is because it can't detect any defaul AWS credentails which we have not set yet post activation. Each api call to AWS Systems Manager is signed by these credentials. When AWS Systems Manager activation is successful it saves aws credentials at following location in a credentials file on on-Prem server.

C:\Windows\System32\config\systemprofile\.aws\credentials

We will create an environment variable referencing this file, basically reading credentials from it.

setx AWS_SHARED_CREDENTIALS_FILE Complete\PATH\to\file /M

C:\> setx AWS_SHARED_CREDENTIALS_FILE 
C:\Windows\System32\config\systemprofile\.aws\credentails /M

SUCCESS: Specified value was saved.

Setx /M sets the credentials at environment level not user level.

However before moving on verify here that the credentails are set

C:\>echo %AWS_SHARED_CREDENTIALS_FILE%

C:\Windows\System32\config\systemprofile\.aws\credentials

Well file reference is ok now check the actual credentials.

more %AWS_SHARED_CREDENTIALS_FILE%

C:\>more %AWS_SHARED_CREDENTIALS_FILE%
[default]
aws_access_key_id     = ASIAAFRICAB5EOAFRICA
aws_secret_access_key = ZiMBaBWeEC2J21OXinstAncEKyAELbKafKApche8
aws_session_token     = A_BIG_token_should_show_up_here

NOTE: Remember whenever a session token is included with aws credentials that means these credentials are valid for a time. The session token denotes an expiry after a particular time period.

Now check the s3 buckets. It should work. Second bucket is what we have created earlier.

C:\> aws s3 ls
C:\>aws s3 ls
2022-01-17 02:55:10 cloudwatch-logs-2022-001
2022-01-17 20:41:56 ssm-demo-bucket-01

Lets try to upload something to this bucket.

C:\>aws s3 cp Temp\s3-upload-test-doc.txt s3://ssm-demo-bucket-01
upload: Temp\s3-upload-test-doc.txt to s3://ssm-demo-bucket-01/s3-upload-test-doc.txt

Well credentials are set and we have checked these are working.

There is one thing to note here.

If you get following error that means AWS SSM Agent service can't contact AWS Systems Manager and hence credentials are not refreshed. (Remember session token.)

C:\>aws s3 ls

An error occurred (ExpiredToken) when calling the ListBuckets operation: The provided token has expired.

What is with the credential refresh in AWS Systems Manager?

The credentials file updated every 30 mins in with new credentials by Amazon SSM agent.

In case you want to change the default value you can set the config in following location.

C:\Program Files\Amazon\SSM

Here, make a copy of file amazon-ssm-agent.json.template but save it as amazon-ssm-agent.json and open it in notepad.

SSM-Creds.png

Look for Profile change the property KeyAutoRotateDays to required value in place of 0. This is an interesting file worth analysing.

Change_cred_time.png

Save the file and restart AWS SSM agent service to record the changes and communicate it to AWS Systems Manager.

Verification

Let's verify. Go to AWS console and to Systems Manager--> On the left hand side Node Management-->Fleet Manager.

Server is showing in the fleet manager.

mi.JPG

on-Prem server has instace id starting from mi - Managed Instance.

AWS instaces have id starting from i - Instance.

Just in case you do not want this on-Prem server to be managed via AWS Systems Manager just de-register it.

C:\> aws ssm deregister-managed-instance --instance-id "mi-0a677d17a2e595e06"

And to Re-register.

'yes' | & 'C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe' -register -code activation-code -id activation-id -region region; Restart-Service AmazonSSMAgent

This was just about on boarding the on-Prem Windows server to AWS Systems Manager, post that there is plethora of operations that we can do. Both on-Prem and AWS Instances can be mass managed from AWS Systems Manager.

AWS-Systems-Manager-architecture-Diagram.png

That's it.

Conclusion

Hope this knowledge i've shared helps and be of value.

Feedback, Suggestion and criticism is welcome. Keep sharing, Thank you.

0
Subscribe to my newsletter

Read articles from Dilaawez Khan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Dilaawez Khan
Dilaawez Khan

Cloud | IaC | Version | SysAdmin