github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/installers/installer.sh.tmpl (about) 1 #!/usr/bin/env bash 2 # shellcheck disable=SC1083,SC2215,SC2288 # caused by Go templating, and shellcheck won't parse if the lines are excluded individually 3 4 set -eu 5 6 upgrade_endpoint="{{ .PublicProxyAddr }}/v1/webapi/automaticupgrades/channel/default" 7 8 # upgrade_endpoint_fetch loads the specified value from the upgrade endpoint. the only 9 # currently supported values are 'version' and 'critical'. 10 upgrade_endpoint_fetch() { 11 host_path="${upgrade_endpoint}/${1}" 12 13 if sf_output="$(curl --proto '=https' --tlsv1.2 -sSf "https://${host_path}")"; then 14 # emit output with empty lines and extra whitespace removed 15 echo "$sf_output" | grep -v -e '^[[:space:]]*$' | awk '{$1=$1};1' 16 return 0 17 else 18 return 1 19 fi 20 } 21 22 # get_target_version loads the current value of the /version endpoint. 23 get_target_version() { 24 if tv_output="$(upgrade_endpoint_fetch version)"; then 25 # emit version string with leading 'v' removed if one is present 26 echo "${tv_output#v}" 27 return 0 28 fi 29 return 1 30 } 31 32 on_ec2() { 33 IMDS_TOKEN=$(curl -m5 -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300") 34 [ -z "$IMDS_TOKEN" ] && return 1 35 EC2_STATUS=$(curl -o /dev/null -w "%{http_code}" -m5 -sS -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/meta-data") 36 [ "$EC2_STATUS" = "200" ] 37 } 38 39 on_azure() { 40 AZURE_STATUS=$(curl -o /dev/null -w "%{http_code}" -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2021-02-01") 41 [ "$AZURE_STATUS" = "200" ] 42 } 43 44 on_gcp() { 45 GCP_STATUS=$(curl -o /dev/null -w "%{http_code}" -m5 -sS -H "Metadata-Flavor: Google" "http://metadata.google.internal/") 46 [ "$GCP_STATUS" = "200" ] 47 } 48 49 ( 50 flock -n 9 || exit 1 51 if test -f /usr/local/bin/teleport; then 52 exit 0 53 fi 54 # shellcheck disable=SC1091 55 . /etc/os-release 56 57 TELEPORT_PACKAGE="{{ .TeleportPackage }}" 58 TELEPORT_UPDATER_PACKAGE="{{ .TeleportPackage }}-updater" 59 60 if [ "$ID" = "debian" ] || [ "$ID" = "ubuntu" ]; then 61 # old versions of ubuntu require that keys get added by `apt-key add`, without 62 # adding the key apt shows a key signing error when installing teleport. 63 if [ "$VERSION_CODENAME" = "xenial" ] || [ "$VERSION_CODENAME" = "trusty" ]; then 64 curl -o /tmp/teleport-pubkey.asc https://apt.releases.teleport.dev/gpg 65 sudo apt-key add /tmp/teleport-pubkey.asc 66 echo "deb https://apt.releases.teleport.dev/ubuntu ${VERSION_CODENAME?} {{ .RepoChannel }}" | sudo tee /etc/apt/sources.list.d/teleport.list 67 rm /tmp/teleport-pubkey.asc 68 else 69 sudo curl https://apt.releases.teleport.dev/gpg \ 70 -o /usr/share/keyrings/teleport-archive-keyring.asc 71 echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] https://apt.releases.teleport.dev/${ID?} ${VERSION_CODENAME?} {{ .RepoChannel }}" | sudo tee /etc/apt/sources.list.d/teleport.list >/dev/null 72 fi 73 sudo apt-get update 74 75 # shellcheck disable=SC2050 76 if [ "{{ .AutomaticUpgrades }}" = "true" ]; then 77 # automatic upgrades 78 if ! target_version="$(get_target_version)"; then 79 # error getting the target version 80 sudo apt-get install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE" 81 elif [ "$target_version" == "none" ]; then 82 # no target version advertised 83 sudo apt-get install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE" 84 else 85 # successfully retrieved target version 86 sudo apt-get install -y "$TELEPORT_PACKAGE=$target_version" jq "$TELEPORT_UPDATER_PACKAGE=$target_version" 87 fi 88 else 89 # no automatic upgrades 90 sudo apt-get install -y "$TELEPORT_PACKAGE" jq 91 fi 92 93 elif [ "$ID" = "amzn" ] || [ "$ID" = "rhel" ]; then 94 if [ "$ID" = "rhel" ]; then 95 VERSION_ID=${VERSION_ID//\.*/} # convert version numbers like '7.2' to only include the major version 96 fi 97 sudo yum install -y yum-utils 98 sudo yum-config-manager --add-repo \ 99 "$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/{{ .RepoChannel }}/teleport.repo")" 100 101 # shellcheck disable=SC2050 102 if [ "{{ .AutomaticUpgrades }}" = "true" ]; then 103 # automatic upgrades 104 if ! target_version="$(get_target_version)"; then 105 # error getting the target version 106 sudo yum install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE" 107 elif [ "$target_version" == "none" ]; then 108 # no target version advertised 109 sudo yum install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE" 110 else 111 # successfully retrieved target version 112 sudo yum install -y "$TELEPORT_PACKAGE-$target_version" jq "$TELEPORT_UPDATER_PACKAGE-$target_version" 113 fi 114 else 115 # no automatic upgrades 116 sudo yum install -y "$TELEPORT_PACKAGE" jq 117 fi 118 119 elif [ "$ID" = "sles" ] || [ "$ID" = "opensuse-tumbleweed" ] || [ "$ID" = "opensuse-leap" ]; then 120 if [ "$ID" = "opensuse-tumbleweed" ]; then 121 VERSION_ID="15" # tumbleweed uses dated VERSION_IDs like 20230702 122 else 123 VERSION_ID="${VERSION_ID//.*/}" # convert version numbers like '7.2' to only include the major version 124 fi 125 sudo rpm --import "https://zypper.releases.teleport.dev/gpg" 126 sudo zypper --non-interactive addrepo "$(rpm --eval "https://zypper.releases.teleport.dev/sles/$VERSION_ID/Teleport/%{_arch}/{{ .RepoChannel }}/teleport.repo")" 127 sudo zypper --gpg-auto-import-keys refresh 128 129 # shellcheck disable=SC2050 130 if [ "{{ .AutomaticUpgrades }}" = "true" ]; then 131 # automatic upgrades 132 if ! target_version="$(get_target_version)"; then 133 # error getting the target version 134 sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE" 135 elif [ "$target_version" == "none" ]; then 136 # no target version advertised 137 sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE" jq "$TELEPORT_UPDATER_PACKAGE" 138 else 139 # successfully retrieved target version 140 sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE-$target_version" jq "$TELEPORT_UPDATER_PACKAGE-$target_version" 141 fi 142 else 143 # no automatic upgrades 144 sudo zypper --non-interactive install -y "$TELEPORT_PACKAGE" jq 145 fi 146 else 147 echo "Unsupported distro: $ID" 148 exit 1 149 fi 150 151 if on_azure; then 152 API_VERSION=$(curl -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/versions" | jq -r ".apiVersions[-1]") 153 INSTANCE_INFO=$(curl -m5 -sS -H "Metadata: true" --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=$API_VERSION&format=json") 154 155 REGION="$(echo "$INSTANCE_INFO" | jq -r .compute.location)" 156 RESOURCE_GROUP="$(echo "$INSTANCE_INFO" | jq -r .compute.resourceGroupName)" 157 SUBSCRIPTION_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.subscriptionId)" 158 VM_ID="$(echo "$INSTANCE_INFO" | jq -r .compute.vmId)" 159 160 JOIN_METHOD=azure 161 LABELS="teleport.internal/vm-id=${VM_ID},teleport.internal/subscription-id=${SUBSCRIPTION_ID},teleport.internal/region=${REGION},teleport.internal/resource-group=${RESOURCE_GROUP}" 162 elif on_ec2; then 163 IMDS_TOKEN=$(curl -m5 -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300") 164 INSTANCE_INFO=$(curl -m5 -sS -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/dynamic/instance-identity/document") 165 166 ACCOUNT_ID="$(echo "$INSTANCE_INFO" | jq -r .accountId)" 167 INSTANCE_ID="$(echo "$INSTANCE_INFO" | jq -r .instanceId)" 168 169 JOIN_METHOD=iam 170 LABELS="teleport.dev/instance-id=${INSTANCE_ID},teleport.dev/account-id=${ACCOUNT_ID}" 171 elif on_gcp; then 172 NAME="$(curl -m5 -sS -H "Metadata-Flavor:Google" "http://metadata.google.internal/computeMetadata/v1/instance/name")" 173 # GCP metadata returns fully qualified zone ("projects/<project-id>/zones/<zone>"), so we need to parse the zone name. 174 FULL_ZONE="$(curl -m5 -sS -H "Metadata-Flavor:Google" "http://metadata.google.internal/computeMetadata/v1/instance/zone")" 175 ZONE="$(basename $FULL_ZONE)" 176 PROJECT_ID=$(curl -m5 -sS -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/project/project-id") 177 178 JOIN_METHOD=gcp 179 LABELS="teleport.internal/name=${NAME},teleport.internal/zone=${ZONE},teleport.internal/project-id=${PROJECT_ID}" 180 else 181 echo "Could not determine cloud provider" 182 exit 1 183 fi 184 185 # generate teleport ssh config 186 # token is read as a parameter from the AWS ssm script run and 187 # passed as the first argument to the script 188 sudo /usr/local/bin/teleport node configure \ 189 --proxy="{{ .PublicProxyAddr }}" \ 190 --join-method=${JOIN_METHOD} \ 191 {{- if .AzureClientID }} 192 --azure-client-id="{{ .AzureClientID }}" \ 193 {{ end -}} 194 --token="$1" \ 195 --output=file \ 196 --labels="${LABELS}" 197 198 # enable and start teleport service 199 sudo systemctl enable --now teleport 200 201 ) 9>/var/lock/teleport_install.lock