Skip to content

Instantly share code, notes, and snippets.

@myoung34
Created April 10, 2017 18:31
Show Gist options
  • Save myoung34/66562bf114cf93435c7389d809bac6c1 to your computer and use it in GitHub Desktop.
Save myoung34/66562bf114cf93435c7389d809bac6c1 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# vault-ec2-auth.sh
# Authenticates an EC2 instance to Hashicorp Vault
#
# configuration stored in environment variables in /etc/vault/client.conf
# expected configuration (defaults are selected below if none is specified):
# VAULT_ADDR = url of vault server
if [[ -e /etc/vault/client.conf ]]; then
source /etc/vault/client.conf
fi
vault_addr="${VAULT_ADDR:-https://vault.redact.com:8200}"
die() { echo "ERROR: $@" >&2; exit 1; }
function get_tag {
instance_id=$(curl --silent http://169.254.169.254/latest/meta-data/instance-id)
tag=$(aws ec2 describe-tags \
--filters 'Name=resource-type,Values=instance' \
"Name=resource-id,Values=${instance_id}" \
"Name=key,Values=$1" \
| grep Value | awk '{print $2}' | sed 's/"\|,//g')
}
[[ $( id -u ) == 0 ]] \
|| die "You must be root to authenticate this instance"
# fetch signed identity document, AMI ID, and IAM profile name from meta-data service
pkcs7=$( curl -Ss http://169.254.169.254/latest/dynamic/instance-identity/pkcs7 |paste -s -d '' )
ami=$( curl -Ss http://169.254.169.254/latest/meta-data/ami-id )
iam_profile=$( curl -s http://169.254.169.254/latest/meta-data/iam/info |jq -r .InstanceProfileArn |cut -d/ -f2- )
EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9][0-9]*\)[a-z]*\$:\\1:'`"
export AWS_DEFAULT_REGION=$EC2_REGION
get_tag 'Role'
role_tag=${tag,,} #name of the node
get_tag 'Environment'
environment_tag=${tag,,} #name of the node
# generate a new nonce unless one already exists
nonce_file=/etc/vault/ec2-auth-nonce
nonce=
if [[ -e $nonce_file ]]; then
nonce=$( <"$nonce_file" )
else
nonce=$( openssl rand -base64 36 )
fi
# prefer role_tag, then instance profile name, then AMI ID
role_name="${role_tag:-${iam_profile:-${ami}}}"
result=$(
curl -k -Ss -XPOST "${vault_addr}/v1/auth/aws-ec2/login" \
-d '{"role":"'"$role_name"'","pkcs7":"'"$pkcs7"'","nonce":"'"$nonce"'"}"'
)
token=$( jq -r .auth.client_token <<< "$result" )
accessor=$( jq -r .auth.accessor <<< "$result" )
if [[ -z $token ]] || [[ $token == null ]]; then
jq . <<< "$result" >&2
die "Could not authenticate"
fi
# write nonce to disk if it didn't already exist
if [[ ! -e $nonce_file ]]; then
mkdir -p "$( dirname "$nonce_file" )"
touch "$nonce_file"
chown root:root "$nonce_file"
chmod 0600 "$nonce_file"
echo "$nonce" > "$nonce_file"
chmod 0400 "$nonce_file"
fi
# write token to tmpfs, readable only to wheel group
touch /var/run/vault-instance-token
chown root:wheel /var/run/vault-instance-token
chmod 0640 /var/run/vault-instance-token
echo "$token" > /var/run/vault-instance-token
# write token accessor to tmpfs, world readable is ok
echo "$accessor" > /var/run/vault-token-accessor
chmod 0644 /var/run/vault-token-accessor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment