Created
July 9, 2024 19:47
-
-
Save infamousjoeg/cd31872088e1c0f38b54727f9664bd9e to your computer and use it in GitHub Desktop.
authn-iam PowerShell Example on EC2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Import the AWS module | |
Import-Module AWSPowerShell.NetCore | |
# Define the region | |
$region = "YOUR_AWS_REGION" | |
# Function to get temporary security credentials from EC2 instance's IAM role | |
function Get-TemporaryCredentials { | |
param ( | |
[string]$region | |
) | |
$instanceProfileCredentials = Get-EC2InstanceMetadata -Category iam/security-credentials/ | |
$roleName = $instanceProfileCredentials.Keys | Select-Object -First 1 | |
$roleCredentials = Get-EC2InstanceMetadata -Category "iam/security-credentials/$roleName" | |
return @{ | |
AccessKeyId = $roleCredentials.AccessKeyId | |
SecretAccessKey = $roleCredentials.SecretAccessKey | |
SessionToken = $roleCredentials.Token | |
} | |
} | |
# Function to generate a timestamp in the required format | |
function Get-Timestamp { | |
return (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") | |
} | |
# Function to create the canonical request components | |
function Get-CanonicalRequest { | |
param ( | |
[string]$method, | |
[string]$canonicalUri, | |
[string]$canonicalQueryString, | |
[string]$canonicalHeaders, | |
[string]$signedHeaders, | |
[string]$payloadHash | |
) | |
return "$method`n$canonicalUri`n$canonicalQueryString`n$canonicalHeaders`n$signedHeaders`n$payloadHash" | |
} | |
# Function to create the string to sign | |
function Get-StringToSign { | |
param ( | |
[string]$algorithm, | |
[string]$timestamp, | |
[string]$credentialScope, | |
[string]$canonicalRequest | |
) | |
return "$algorithm`n$timestamp`n$credentialScope`n" + (ConvertTo-Json $canonicalRequest | Get-FileHash -Algorithm SHA256).Hash.ToLower() | |
} | |
# Function to perform HMAC-SHA256 hashing | |
function HmacSHA256 { | |
param ( | |
[Parameter(Mandatory=$true)][string]$data, | |
[Parameter(Mandatory=$true)][byte[]]$key | |
) | |
$hmacsha256 = New-Object System.Security.Cryptography.HMACSHA256 | |
$hmacsha256.Key = $key | |
$signature = $hmacsha256.ComputeHash([Text.Encoding]::UTF8.GetBytes($data)) | |
return $signature | |
} | |
# Function to create the signing key | |
function Get-SigningKey { | |
param ( | |
[string]$secretKey, | |
[string]$dateStamp, | |
[string]$region, | |
[string]$service | |
) | |
$kSecret = ("AWS4" + $secretKey).ToCharArray() | |
$kDate = HmacSHA256 $dateStamp ([Text.Encoding]::UTF8.GetBytes($kSecret)) | |
$kRegion = HmacSHA256 $region $kDate | |
$kService = HmacSHA256 $service $kRegion | |
$kSigning = HmacSHA256 "aws4_request" $kService | |
return $kSigning | |
} | |
# Function to create the authorization header | |
function Get-AuthorizationHeader { | |
param ( | |
[string]$algorithm, | |
[string]$accessKeyId, | |
[string]$credentialScope, | |
[string]$signedHeaders, | |
[string]$signature | |
) | |
return "$algorithm Credential=$accessKeyId/$credentialScope, SignedHeaders=$signedHeaders, Signature=$signature" | |
} | |
# Get temporary security credentials from EC2 instance's IAM role | |
$credentials = Get-TemporaryCredentials -region $region | |
$temporaryAccessKeyId = $credentials.AccessKeyId | |
$temporarySecretAccessKey = $credentials.SecretAccessKey | |
$sessionToken = $credentials.SessionToken | |
# Generate a timestamp in the required format | |
$timestamp = Get-Timestamp | |
# Define the service and endpoint for STS | |
$service = "sts" | |
$host = "sts.amazonaws.com" | |
$endpoint = "https://$host" | |
# Create the canonical request components | |
$method = "GET" | |
$canonicalUri = "/" | |
$canonicalQueryString = "Action=GetCallerIdentity&Version=2011-06-15" | |
$canonicalHeaders = "host:$host`n" + "x-amz-date:$timestamp`n" | |
$signedHeaders = "host;x-amz-date" | |
$payloadHash = (ConvertTo-Json @{} | Get-FileHash -Algorithm SHA256).Hash.ToLower() | |
$canonicalRequest = Get-CanonicalRequest -method $method -canonicalUri $canonicalUri -canonicalQueryString $canonicalQueryString -canonicalHeaders $canonicalHeaders -signedHeaders $signedHeaders -payloadHash $payloadHash | |
# Create the string to sign | |
$algorithm = "AWS4-HMAC-SHA256" | |
$dateStamp = (Get-Date).ToUniversalTime().ToString("yyyyMMdd") | |
$credentialScope = "$dateStamp/$region/$service/aws4_request" | |
$stringToSign = Get-StringToSign -algorithm $algorithm -timestamp $timestamp -credentialScope $credentialScope -canonicalRequest $canonicalRequest | |
# Create the signing key | |
$kSigning = Get-SigningKey -secretKey $temporarySecretAccessKey -dateStamp $dateStamp -region $region -service $service | |
# Create the signature | |
$signature = HmacSHA256 $stringToSign $kSigning -replace '-','' -replace '^0+(?=[a-f\d])','' | |
# Generate the signed header for the request | |
$authorizationHeader = Get-AuthorizationHeader -algorithm $algorithm -accessKeyId $temporaryAccessKeyId -credentialScope $credentialScope -signedHeaders $signedHeaders -signature $signature | |
# Output the signed header and other necessary headers | |
Write-Output "Authorization: $authorizationHeader" | |
Write-Output "x-amz-date: $timestamp" | |
Write-Output "x-amz-security-token: $sessionToken" | |
# Example usage to make the request | |
$headers = @{ | |
"Authorization" = $authorizationHeader | |
"x-amz-date" = $timestamp | |
"x-amz-security-token" = $sessionToken | |
} | |
# Invoke the REST method with the signed headers to make the STS request | |
Invoke-RestMethod -Uri "$endpoint?$canonicalQueryString" -Headers $headers -Method $method |
Author
infamousjoeg
commented
Jul 9, 2024
- Import the AWS module: This loads the AWS Tools for PowerShell module, which provides cmdlets for interacting with AWS services.
- Define the region: Specifies the AWS region you are operating in.
- Get temporary security credentials from EC2 instance’s IAM role: This function retrieves the temporary security credentials from the EC2 instance metadata, which includes the IAM role’s credentials.
- Generate a timestamp: This function creates a timestamp in the required ISO 8601 format.
- Create the canonical request components: This function constructs the canonical request string, which includes the HTTP method, URI, query string, headers, and payload hash.
- Create the string to sign: This function constructs the string to sign, which is used to generate the signature.
- Define the HmacSHA256 function: A helper function to perform HMAC-SHA256 hashing.
- Create the signing key: This function generates the signing key by performing a series of HMAC operations on the secret key.
- Create the authorization header: This function constructs the Authorization header using the generated signature.
- Get temporary security credentials: Calls the function to retrieve the temporary credentials from the EC2 instance’s IAM role.
- Generate a timestamp: Calls the function to create the timestamp.
- Define the service and endpoint: Specifies the AWS service and endpoint for STS.
- Create the canonical request components: Calls the function to construct the canonical request string.
- Create the string to sign: Calls the function to construct the string to sign.
- Create the signing key: Calls the function to generate the signing key.
- Create the signature: Uses the signing key to create the request signature.
- Generate the signed header: Calls the function to construct the Authorization header.
- Output the headers: Outputs the necessary headers for the request.
- Example usage to make the request: Demonstrates how to use the headers in an actual request to AWS STS.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment