Created
April 13, 2023 12:30
-
-
Save hugotkk/a5897367c5e1667ee138acbe4be07b43 to your computer and use it in GitHub Desktop.
Example of aws ec2 describe-instances with curl and aws signature V4
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 datetime | |
import hashlib | |
import hmac | |
import urllib.parse | |
def sign_request(method, url, region, service, access_key, secret_key, data='', headers=None): | |
if headers is None: | |
headers = {} | |
# Create a new datetime object and convert it to ISO format | |
now = datetime.datetime.utcnow() | |
amzdate = now.strftime('%Y%m%dT%H%M%SZ') | |
datestamp = now.strftime('%Y%m%d') | |
# Set the AWS request headers | |
headers['x-amz-date'] = amzdate | |
headers['Host'] = urllib.parse.urlparse(url).hostname | |
# Create a canonical request | |
canonical_uri = urllib.parse.urlparse(url).path or '/' | |
canonical_querystring = urllib.parse.urlparse(url).query | |
canonical_headers = '\n'.join([f"{key.lower()}:{value.strip()}" for key, value in sorted(headers.items())]) | |
payload_hash = hashlib.sha256(data.encode('utf-8')).hexdigest() | |
canonical_request = '\n'.join([ | |
method, | |
canonical_uri, | |
canonical_querystring, | |
canonical_headers, | |
'', | |
'content-type;host;x-amz-date', | |
payload_hash | |
]) | |
# Create a string to sign | |
algorithm = 'AWS4-HMAC-SHA256' | |
credential_scope = f"{datestamp}/{region}/{service}/aws4_request" | |
string_to_sign = '\n'.join([ | |
algorithm, | |
amzdate, | |
credential_scope, | |
hashlib.sha256(canonical_request.encode('utf-8')).hexdigest() | |
]) | |
# Generate the signing key | |
kdate = hmac.new(('AWS4' + secret_key).encode('utf-8'), datestamp.encode('utf-8'), hashlib.sha256).digest() | |
kregion = hmac.new(kdate, region.encode('utf-8'), hashlib.sha256).digest() | |
kservice = hmac.new(kregion, service.encode('utf-8'), hashlib.sha256).digest() | |
ksigning = hmac.new(kservice, b'aws4_request', hashlib.sha256).digest() | |
# Generate the signature | |
signature = hmac.new(ksigning, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest() | |
# Add the authorization header to the request headers | |
headers['Authorization'] = f"{algorithm} Credential={access_key}/{credential_scope}, SignedHeaders=content-type;host;x-amz-date, Signature={signature}" | |
return headers | |
api_action = 'DescribeInstances' | |
api_version = '2016-11-15' | |
endpoint_url = f'https://ec2.amazonaws.com?Action={api_action}&Version={api_version}' | |
data = f'' | |
region = 'us-east-1' | |
access_key = '<ACCESS_KEY>' | |
secret_key = '<SECRET_KEY>' | |
service = 'ec2' | |
method = 'GET' | |
headers = sign_request(method, endpoint_url, region, service, access_key, secret_key, headers={'Content-Type': 'application/x-www-form-urlencoded'}, data=data) | |
curl_command = f"curl -X {method} --location '{endpoint_url}' \\\n" | |
if data: | |
curl_command += f"--data '{data}' \\\n" | |
curl_command += f"--header 'Content-Type: {headers['Content-Type']}' \\\n" | |
curl_command += f"--header 'x-amz-date: {headers['x-amz-date']}' \\\n" | |
curl_command += f"--header 'Authorization: {headers['Authorization']}' \n" | |
print(curl_command) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment