diff --git a/Dockerfile b/Dockerfile index bcc91af35..678e90d22 100644 --- a/Dockerfile +++ b/Dockerfile @@ -100,12 +100,18 @@ RUN ln -s /usr/local/google-cloud-sdk/completion.bash.inc /etc/bash_completion.d gcloud config set metrics/environment github_docker_image --installation # -# Install aws-vault to easily assume roles (not related to HashiCorp Vault) +# Configure aws-vault to easily assume roles (not related to HashiCorp Vault) # -ENV AWS_VAULT_BACKEND file +ENV AWS_VAULT_ENABLED=true +ENV AWS_VAULT_BACKEND=file ENV AWS_VAULT_ASSUME_ROLE_TTL=1h #ENV AWS_VAULT_FILE_PASSPHRASE= +# +# Configure aws-okta to easily assume roles +# +ENV AWS_OKTA_ENABLED=false + # # Install kubectl # diff --git a/rootfs/etc/profile.d/aws-okta.sh b/rootfs/etc/profile.d/aws-okta.sh new file mode 100755 index 000000000..60eba04f7 --- /dev/null +++ b/rootfs/etc/profile.d/aws-okta.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +if [ "${AWS_OKTA_ENABLED}" == "true" ]; then + if ! which aws-okta >/dev/null; then + echo "aws-okta not installed" + exit 1 + fi + + if [ -n "${AWS_OKTA_PROFILE}" ]; then + export ASSUME_ROLE=${AWS_OKTA_PROFILE} + # Set the Terraform `aws_assume_role_arn` based on our current context + export TF_VAR_aws_assume_role_arn=$(aws sts get-caller-identity --output text --query 'Arn' | sed 's/:sts:/:iam:/g' | sed 's,:assumed-role/,:role/,' | cut -d/ -f1-2) + echo + echo "* Assumed role $(green ${TF_VAR_aws_assume_role_arn})" + else + AWS_VAULT_ARGS=("--assume-role-ttl=${AWS_VAULT_ASSUME_ROLE_TTL}") + [ -d /localhost/.aws-okta ] || mkdir -p /localhost/.aws-okta + ln -sf /localhost/.aws-okta ${HOME} + fi + + PROMPT_HOOKS+=("aws_okta_prompt") + function aws_okta_prompt() { + if [ -z "${AWS_OKTA_PROFILE}" ]; then + echo -e "-> Run '$(green assume-role)' to login to AWS with aws-okta" + fi + } + + # Alias to start a shell or run a command with an assumed role + function aws_okta_assume_role() { + role=${1:-${AWS_DEFAULT_PROFILE}} + + # Do not allow nested roles + if [ -n "${AWS_OKTA_PROFILE}" ]; then + echo "Type '$(green exit)' before attempting to assume another role" + return 1 + fi + + if [ -z "${role}" ]; then + echo "Usage: $0 [role]" + return 1 + fi + # Sync the clock in the Docker Virtual Machine to the system's hardware clock to avoid time drift + # (Only works in privileged mode) + hwclock -s >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "* $(yellow Failed to sync system time from hardware clock)" + fi + + shift + if [ $# -eq 0 ]; then + aws-okta exec ${AWS_OKTA_ARGS[@]} $role -- bash -l + else + aws-okta exec ${AWS_OKTA_ARGS[@]} $role -- $* + fi + } + + function assume-role() { + aws_okta_assume_role $* + } +fi diff --git a/rootfs/etc/profile.d/aws-vault.sh b/rootfs/etc/profile.d/aws-vault.sh index 1afd10b90..854884095 100755 --- a/rootfs/etc/profile.d/aws-vault.sh +++ b/rootfs/etc/profile.d/aws-vault.sh @@ -1,63 +1,70 @@ #!/bin/bash -if [ -n "${AWS_VAULT}" ]; then - # Set the Terraform `aws_assume_role_arn` based on our current context - export TF_VAR_aws_assume_role_arn=$(aws sts get-caller-identity --output text --query 'Arn' | sed 's/:sts:/:iam:/g' | sed 's,:assumed-role/,:role/,' | cut -d/ -f1-2) - echo "* Assumed role $(green ${TF_VAR_aws_assume_role_arn})" -else - AWS_VAULT_ARGS=("--assume-role-ttl=${AWS_VAULT_ASSUME_ROLE_TTL}") - [ -d /localhost/.awsvault ] || mkdir -p /localhost/.awsvault - ln -sf /localhost/.awsvault ${HOME} - if [ "${VAULT_SERVER_ENABLED:-true}" == "true" ]; then - curl -sSL --connect-timeout 0.1 -o /dev/null --stderr /dev/null http://169.254.169.254/latest/meta-data/iam/security-credentials - result=$? - if [ $result -ne 0 ]; then - echo "* Started EC2 metadata service at $(green http://169.254.169.254/latest)" - aws-vault server & - AWS_VAULT_ARGS+=("--server") - else - echo "* EC2 metadata server already running" - fi +if [ "${AWS_VAULT_ENABLED}" == "true" ]; then + if ! which aws-vault >/dev/null; then + echo "aws-vault not installed" + exit 1 fi -fi -PROMPT_HOOKS+=("aws_vault_prompt") -function aws_vault_prompt() { - if [ -z "${AWS_VAULT}" ]; then - echo -e "-> Run '$(green assume-role)' to login to AWS" + if [ -n "${AWS_VAULT}" ]; then + export ASSUME_ROLE=${AWS_VAULT} + # Set the Terraform `aws_assume_role_arn` based on our current context + export TF_VAR_aws_assume_role_arn=$(aws sts get-caller-identity --output text --query 'Arn' | sed 's/:sts:/:iam:/g' | sed 's,:assumed-role/,:role/,' | cut -d/ -f1-2) + echo "* Assumed role $(green ${TF_VAR_aws_assume_role_arn})" + else + AWS_VAULT_ARGS=("--assume-role-ttl=${AWS_VAULT_ASSUME_ROLE_TTL}") + [ -d /localhost/.awsvault ] || mkdir -p /localhost/.awsvault + ln -sf /localhost/.awsvault ${HOME} + if [ "${VAULT_SERVER_ENABLED:-true}" == "true" ]; then + curl -sSL --connect-timeout 0.1 -o /dev/null --stderr /dev/null http://169.254.169.254/latest/meta-data/iam/security-credentials + result=$? + if [ $result -ne 0 ]; then + echo "* Started EC2 metadata service at $(green http://169.254.169.254/latest)" + aws-vault server & + AWS_VAULT_ARGS+=("--server") + else + echo "* EC2 metadata server already running" + fi + fi fi -} -# Alias to start a shell or run a command with an assumed role -function assume-role() { - role=${1:-${AWS_DEFAULT_PROFILE}} + PROMPT_HOOKS+=("aws_vault_prompt") + function aws_vault_prompt() { + if [ -z "${AWS_VAULT}" ]; then + echo -e "-> Run '$(green assume-role)' to login to AWS with aws-vault" + fi + } - # Do not allow nested roles - if [ -n "${AWS_VAULT}" ]; then - echo "Type '$(green exit)' before attempting to assume another role" - return 1 - fi + # Start a shell or run a command with an assumed role + function aws_vault_assume_role() { + role=${1:-${AWS_DEFAULT_PROFILE}} - if [ -z "${role}" ]; then - echo "Usage: $0 [role]" - return 1 - fi - # Sync the clock in the Docker Virtual Machine to the system's hardware clock to avoid time drift - # (Only works in privileged mode) - hwclock -s >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "* $(yellow Failed to sync system time from hardware clock)" - fi + # Do not allow nested roles + if [ -n "${AWS_VAULT}" ]; then + echo "Type '$(green exit)' before attempting to assume another role" + return 1 + fi - shift - if [ $# -eq 0 ]; then - aws-vault exec ${AWS_VAULT_ARGS[@]} $role -- bash -l - else - aws-vault exec ${AWS_VAULT_ARGS[@]} $role -- $* - fi -} + if [ -z "${role}" ]; then + echo "Usage: $0 [role]" + return 1 + fi + # Sync the clock in the Docker Virtual Machine to the system's hardware clock to avoid time drift + # (Only works in privileged mode) + hwclock -s >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "* $(yellow Failed to sync system time from hardware clock)" + fi -# Alias for backwards compatbility -function use-profile() { - assume-role $* -} + shift + if [ $# -eq 0 ]; then + aws-vault exec ${AWS_VAULT_ARGS[@]} $role -- bash -l + else + aws-vault exec ${AWS_VAULT_ARGS[@]} $role -- $* + fi + } + + function assume-role() { + aws_vault_assume_role $* + } +fi diff --git a/rootfs/etc/profile.d/banner.sh b/rootfs/etc/profile.d/banner.sh index d313d67ce..3e64c71e9 100755 --- a/rootfs/etc/profile.d/banner.sh +++ b/rootfs/etc/profile.d/banner.sh @@ -4,8 +4,8 @@ BANNER_COLOR="${BANNER_COLOR:-}" BANNER_INDENT="${BANNER_INDENT:- }" BANNER_FONT="${BANNER_FONT:-Nancyj.flf}" -if [ -z "${AWS_VAULT}" ]; then - # Display a banner message for interactive shells (if we're not in aws-vault) +if [ -z "${ASSUME_ROLE}" ]; then + # Display a banner message for interactive shells (if we're not in aws-vault or aws-okta) if [ -n "${BANNER}" ]; then if [ "$BANNER_COMMAND" == "figlet" ]; then echo "${BANNER_COLOR}" diff --git a/rootfs/etc/profile.d/motd.sh b/rootfs/etc/profile.d/motd.sh index e770f9058..c930e92a6 100755 --- a/rootfs/etc/profile.d/motd.sh +++ b/rootfs/etc/profile.d/motd.sh @@ -1,4 +1,4 @@ -if [ -z "${AWS_VAULT}" ]; then +if [ -z "${ASSUME_ROLE}" ]; then if [ -f "/etc/motd" ]; then cat "/etc/motd" fi diff --git a/rootfs/etc/profile.d/prompt.sh b/rootfs/etc/profile.d/prompt.sh index 4cae3a60f..73915f1ab 100755 --- a/rootfs/etc/profile.d/prompt.sh +++ b/rootfs/etc/profile.d/prompt.sh @@ -31,37 +31,37 @@ function geodesic_prompt() { case $PROMPT_STYLE in plain) # 8859-1 codepoints: - AWS_VAULT_ACTIVE_MARK=$(tput bold)$(tput setab 2)$'»'$(tput sgr0)' ' # green - AWS_VAULT_INACTIVE_MARK=$'· ' + ASSUME_ROLE_ACTIVE_MARK=$(tput bold)$(tput setab 2)$'»'$(tput sgr0)' ' # green + ASSUME_ROLE_INACTIVE_MARK=$'· ' BLACK_RIGHTWARDS_ARROWHEAD=$'=> ' BANNER_MARK=$'§ ' ;; unicode) # unicode - AWS_VAULT_ACTIVE_MARK=$'\u2705 ' # '✅' - AWS_VAULT_INACTIVE_MARK=$'\u274C ' # '❌' + ASSUME_ROLE_ACTIVE_MARK=$'\u2705 ' # '✅' + ASSUME_ROLE_INACTIVE_MARK=$'\u274C ' # '❌' BLACK_RIGHTWARDS_ARROWHEAD=$'\u27A4 ' # '➤', suggest '▶' may be present in more fonts BANNER_MARK=$'\u29C9 ' # '⧉' ;; *) # default - AWS_VAULT_ACTIVE_MARK=$' \x01'$(tput bold)$(tput setaf 2)$'\x02\u2713 \x01'$(tput sgr0)$'\x02' # green bold '✓' - AWS_VAULT_INACTIVE_MARK=$' \x01'$(tput bold)$(tput setaf 1)$'\x02\u2717 \x01'$(tput sgr0)$'\x02' # red bold '✗' - BLACK_RIGHTWARDS_ARROWHEAD=$'\u2a20 ' # '⨠' + ASSUME_ROLE_ACTIVE_MARK=$' \x01'$(tput bold)$(tput setaf 2)$'\x02\u2713 \x01'$(tput sgr0)$'\x02' # green bold '✓' + ASSUME_ROLE_INACTIVE_MARK=$' \x01'$(tput bold)$(tput setaf 1)$'\x02\u2717 \x01'$(tput sgr0)$'\x02' # red bold '✗' + BLACK_RIGHTWARDS_ARROWHEAD=$'\u2a20 ' # '⨠' BANNER_MARK='⧉ ' ;; esac - if [ -n "$AWS_VAULT" ]; then - STATUS=${AWS_VAULT_ACTIVE_MARK} + if [ -n "$ASSUME_ROLE" ]; then + STATUS=${ASSUME_ROLE_ACTIVE_MARK} else - STATUS=${AWS_VAULT_INACTIVE_MARK} + STATUS=${ASSUME_ROLE_INACTIVE_MARK} fi - if [ -n "${AWS_VAULT}" ]; then - ROLE_PROMPT="(${AWS_VAULT})" + if [ -n "${ASSUME_ROLE}" ]; then + ROLE_PROMPT="(${ASSUME_ROLE})" else ROLE_PROMPT="(none)" fi diff --git a/rootfs/etc/profile.d/syslog-ng.sh b/rootfs/etc/profile.d/syslog-ng.sh index bdff633e7..cfc4f61bc 100755 --- a/rootfs/etc/profile.d/syslog-ng.sh +++ b/rootfs/etc/profile.d/syslog-ng.sh @@ -1,5 +1,3 @@ -if pidof syslog-ng >/dev/null; then - echo "* syslog-ng is already running" -else +if ! pidof syslog-ng >/dev/null; then syslog-ng -f /etc/syslog-ng/syslog-ng.conf fi