Skip to content

Instantly share code, notes, and snippets.

@aksel
Created April 22, 2024 11:04
Show Gist options
  • Save aksel/bd3352d3f7e3056d6f8165636682964e to your computer and use it in GitHub Desktop.
Save aksel/bd3352d3f7e3056d6f8165636682964e to your computer and use it in GitHub Desktop.
Bash port of aws rds generate-db-auth-token
#!/bin/bash
##########################################
# Bash port of aws rds generate-db-auth-token
#
# Required environment variables:
# AWS Credentials (AWS_ACCESS_KEY_ID; AWS_SECRET_ACCESS_KEY; AWS_SESSION_TOKEN)
# PGUSER: Database user name.
# PGHOST: Database host.
# PGDATABASE: Database name.
# Optional environment variables:
# PGPORT: Database port. Defaults to 5432.
##########################################
generate_db_auth_token() {
local SERVICE="rds-db"
local PGPORT="${PGPORT:-5432}" # Default PGPORT to 5432 if not set already.
local HOST="$PGHOST:$PGPORT"
local DATE=$(date -u '+%Y%m%d')
local DATETIME="$(date -u '+%Y%m%dT%H%M%SZ')"
query="Action=connect&DBUser=$PGUSER&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=$(url_encode "$AWS_ACCESS_KEY_ID/$DATE/$AWS_REGION/$SERVICE/aws4_request")&X-Amz-Date=$DATETIME&X-Amz-Expires=900&X-Amz-Security-Token=$(url_encode "$AWS_SESSION_TOKEN")&X-Amz-SignedHeaders=host"
# Build canonical request
# Note: The canonical request needs a SHA256 digest of the body, even when the body is empty.
canonical_request="GET
/
$query
host:$HOST
host
$(sha256_digest "")"
# Derive signing key
k_date=$(hmac_sha256 "AWS4$AWS_SECRET_ACCESS_KEY" "$DATE")
k_region=$(hmac_sha256_hexkey "$k_date" "$AWS_REGION")
k_service=$(hmac_sha256_hexkey "$k_region" "$SERVICE")
signing_key=$(hmac_sha256_hexkey "$k_service" "aws4_request")
# String to sign
sts="AWS4-HMAC-SHA256
$DATETIME
$DATE/$AWS_REGION/$SERVICE/aws4_request
$(sha256_digest "$canonical_request")"
# Calculate signature
signature=$(hmac_sha256_hexkey "$signing_key" "$sts")
echo "$HOST/?$query&X-Amz-Signature=$signature"
}
##########################################
# SHA256 digest, outputs hex string.
#
# Usage:
# sha256_digest "Hello" → "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969"
##########################################
sha256_digest() {
echo -n "$1" | openssl dgst -sha256 | awk '{print $2}'
}
##########################################
# HMAC SHA256, with string key.
# Outputs resulting hex string.
#
# Usage:
# hmac_sha256 "key" "The quick brown fox jumps over the lazy dog" → "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8"
##########################################
hmac_sha256() {
echo -n "$2" | openssl dgst -sha256 -mac HMAC -macopt key:"$1" | awk '{print $2}'
}
##########################################
# HMAC SHA256, with hex key.
# Outputs resulting hex string.
#
# Usage:
# hmac_sha256_hexkey "6B6579" "The quick brown fox jumps over the lazy dog" → "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8"
##########################################
hmac_sha256_hexkey() {
echo -n "$2" | openssl dgst -sha256 -mac HMAC -macopt hexkey:"$1" | awk '{print $2}'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment