<commit_before>#!/bin/bash
set -x

# Install uuid used for random token generation
apt-get install -y uuid

# Set some curl options so that temporary failures get retried
# More info: https://ec.haxx.se/usingcurl-timeouts.html
CURL_OPTS="-L --retry 100 --retry-delay 0 --connect-timeout 10 --max-time 300"

# Install telegraf to collect stats from influx
curl $CURL_OPTS -o /tmp/telegraf.deb https://dl.influxdata.com/telegraf/releases/telegraf_${telegraf_version}_amd64.deb
dpkg -i /tmp/telegraf.deb
rm -f /tmp/telegraf.deb

# Create teleport user. It is helpful to share the same UID
# to have the same permissions on shared NFS volumes across auth servers and for consistency.
useradd -r teleport -u ${teleport_uid}
adduser teleport adm

# Setup teleport run dir for pid files
mkdir -p /var/run/teleport/
chown -R teleport:adm /var/run/teleport

# Setup teleport data dir used for transient storage
mkdir -p /var/lib/teleport/
chown -R teleport:adm /var/lib/teleport

# Setup teleport auth server config file
LOCAL_IP=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
LOCAL_HOSTNAME=`curl http://169.254.169.254/latest/meta-data/local-hostname`

# Set host UUID so auth server picks it up, as each auth server's
# logs are stored in individual folder /var/lib/teleport/log/<host_uuid>/
# and it will be easy to log forwarders to locate them on every auth server
# note though, that host_uuid MUST be unique, otherwise all sorts of unintended
# things will happen.
echo $${LOCAL_HOSTNAME} > /var/lib/teleport/host_uuid
chown -R teleport:adm /var/lib/teleport

# Download and install teleport from official file server
pushd /tmp
curl $${CURL_OPTS} -o teleport.tar.gz https://get.gravitational.com/teleport/${teleport_version}/teleport-ent-v${teleport_version}-linux-amd64-bin.tar.gz
tar -xzf /tmp/teleport.tar.gz
cp teleport-ent/tctl teleport-ent/tsh teleport-ent/teleport /usr/local/bin
rm -rf /tmp/teleport.tar.gz /tmp/teleport-ent
popd

# Install python to get access to SSM to fetch license file
# that is distributed via SSM parameter store in encrypted form.
curl $${CURL_OPTS} -O https://bootstrap.pypa.io/get-pip.py
python2.7 get-pip.py
pip install awscli
aws ssm get-parameter --with-decryption --name /teleport/${cluster_name}/license --region ${region} --query 'Parameter.Value' --output text > /var/lib/teleport/license.pem 
chown -R teleport:adm /var/lib/teleport/license.pem

# Teleport Auth server is using DynamoDB as a backend
# On AWS, see dynamodb.tf for details
cat >/etc/teleport.yaml <<EOF
teleport:
  nodename: $${LOCAL_HOSTNAME}
  advertise_ip: $${LOCAL_IP}
  log:
    output: stderr
    severity: DEBUG

  data_dir: /var/lib/teleport
  storage:
    type: dynamodb
    region: ${region}
    table_name: ${dynamo_table_name}
    audit_table_name: ${dynamo_events_table_name}
    audit_sessions_uri: s3://${s3_bucket}/records

auth_service:
  enabled: yes
  listen_addr: 0.0.0.0:3025

  authentication:
    second_factor: off
    type: oidc

  cluster_name: ${cluster_name}

ssh_service:
  enabled: no

proxy_service:
  enabled: no
EOF

# Install and start teleport systemd unit.
# Notice that Auth server does not need to run as root
# as it does not handle any interactive sessions,
# only serves HTTPs API server.
cat >/etc/systemd/system/teleport.service <<EOF
[Unit]
Description=Teleport SSH Service
After=network.target 

[Service]
User=teleport
Group=adm
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/teleport start --config=/etc/teleport.yaml --diag-addr=127.0.0.1:3434 --pid-file=/var/run/teleport/teleport.pid
ExecReload=/bin/kill -HUP \$$MAINPID
PIDFile=/var/run/teleport/teleport.pid
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF
systemctl enable teleport
systemctl start teleport


# Script that makes sure that only one auth server processes
# requests at a time, by using dynamodb-backed locking.
# The lock is implemented as item in DynamoDB table:  {"Lock": "lock1", "Expires": "time", "Process": "server1"}
# The auth server node either renews the lease if lock "Process" holds the server id as owner of the lock
# or grabs the lock in case if expires column indicates that the lease has not been renewed after timeout.
# This pattern can be implemented in many different ways, e.g. using ASG group of 1 as a separate process
# or in Kubernetes as a deployment of scale 1.
cat >/usr/local/bin/teleport-lock <<EOF
#!/bin/bash
set -x

LOCK="/teleport/${cluster_name}"
NOW=\$$(date +%s)
TTL=\$$((\$$NOW+3660))
PROCESS="$${LOCAL_HOSTNAME}"
echo locking \$$PROCESS for \$$TTL

# Either renew the lease if agent still holds it, or grab the lease if it's expired
aws dynamodb put-item \
    --region ${region} \
    --table-name ${locks_table_name}\
    --item  "{\"Lock\": {\"S\": \"/auth/servers\"}, \"Expires\": {\"S\": \"\$$TTL\"}, \"Process\": {\"S\": \"\$$PROCESS\"}}" \
    --condition-expression="(attribute_not_exists(Expires) OR Expires <= :timestamp) OR Process = :process"\
    --expression-attribute-values "{\":timestamp\":{\"S\":\"\$$NOW\"}, \":process\":{\"S\":\"\$$PROCESS\"}}"

if [ \$$? -eq 0 ]; then
    echo "Renewed or locked the lease for \$$PROCESS until $(date -d @\$$TTL)"
else
    echo "Could get renew lease, locked by other process"
    exit 255
fi
EOF
chmod 755 /usr/local/bin/teleport-lock

# Install a service that rotates teleport join tokens.
# Teleport join tokens are temporary authentication tokens
# letting nodes and proxies to join to the cluster. Notice that timer
# unit rotates the current token every hour, but tokens are valid for 2 hours
# to handle timing cases.
cat >/usr/local/bin/teleport-ssm-publish-tokens <<EOF
#!/bin/bash
set -e
set -o pipefail

# Proxy token authenticates proxies joining the cluster
PROXY_TOKEN=\$$(uuid)
tctl nodes add --roles=proxy --ttl=4h --token=\$${PROXY_TOKEN}
aws ssm put-parameter --name /teleport/${cluster_name}/tokens/proxy --region ${region} --type="SecureString" --value="\$${PROXY_TOKEN}" --overwrite

# Node token authenticates nodes joining the cluster
NODE_TOKEN=\$$(uuid)
tctl nodes add --roles=node --ttl=4h --token=\$${NODE_TOKEN}
aws ssm put-parameter --name /teleport/${cluster_name}/tokens/node --region ${region} --type="SecureString" --value="\$${NODE_TOKEN}" --overwrite

# Export CA certificate to SSM parameter store
# so nodes and proxies can check the identity of the auth server they are connecting to
CERT=\$$(tctl auth export --type=tls)
aws ssm put-parameter --name /teleport/${cluster_name}/ca --region ${region} --type="String" --value="\$${CERT}" --overwrite
<commit_msg>Use full pathnames in tctl execution (#1972)<commit_after>#!/bin/bash
set -x

# Install uuid used for random token generation
apt-get install -y uuid

# Set some curl options so that temporary failures get retried
# More info: https://ec.haxx.se/usingcurl-timeouts.html
CURL_OPTS="-L --retry 100 --retry-delay 0 --connect-timeout 10 --max-time 300"

# Install telegraf to collect stats from influx
curl $CURL_OPTS -o /tmp/telegraf.deb https://dl.influxdata.com/telegraf/releases/telegraf_${telegraf_version}_amd64.deb
dpkg -i /tmp/telegraf.deb
rm -f /tmp/telegraf.deb

# Create teleport user. It is helpful to share the same UID
# to have the same permissions on shared NFS volumes across auth servers and for consistency.
useradd -r teleport -u ${teleport_uid}
adduser teleport adm

# Setup teleport run dir for pid files
mkdir -p /var/run/teleport/
chown -R teleport:adm /var/run/teleport

# Setup teleport data dir used for transient storage
mkdir -p /var/lib/teleport/
chown -R teleport:adm /var/lib/teleport

# Setup teleport auth server config file
LOCAL_IP=`curl http://1192.168.3.1154/latest/meta-data/local-ipv4`
LOCAL_HOSTNAME=`curl http://169.254.169.254/latest/meta-data/local-hostname`

# Set host UUID so auth server picks it up, as each auth server's
# logs are stored in individual folder /var/lib/teleport/log/<host_uuid>/
# and it will be easy to log forwarders to locate them on every auth server
# note though, that host_uuid MUST be unique, otherwise all sorts of unintended
# things will happen.
echo $${LOCAL_HOSTNAME} > /var/lib/teleport/host_uuid
chown -R teleport:adm /var/lib/teleport

# Download and install teleport from official file server
pushd /tmp
curl $${CURL_OPTS} -o teleport.tar.gz https://get.gravitational.com/teleport/${teleport_version}/teleport-ent-v${teleport_version}-linux-amd64-bin.tar.gz
tar -xzf /tmp/teleport.tar.gz
cp teleport-ent/tctl teleport-ent/tsh teleport-ent/teleport /usr/local/bin
rm -rf /tmp/teleport.tar.gz /tmp/teleport-ent
popd

# Install python to get access to SSM to fetch license file
# that is distributed via SSM parameter store in encrypted form.
curl $${CURL_OPTS} -O https://bootstrap.pypa.io/get-pip.py
python2.7 get-pip.py
pip install awscli
aws ssm get-parameter --with-decryption --name /teleport/${cluster_name}/license --region ${region} --query 'Parameter.Value' --output text > /var/lib/teleport/license.pem 
chown -R teleport:adm /var/lib/teleport/license.pem

# Teleport Auth server is using DynamoDB as a backend
# On AWS, see dynamodb.tf for details
cat >/etc/teleport.yaml <<EOF
teleport:
  nodename: $${LOCAL_HOSTNAME}
  advertise_ip: $${LOCAL_IP}
  log:
    output: stderr
    severity: DEBUG

  data_dir: /var/lib/teleport
  storage:
    type: dynamodb
    region: ${region}
    table_name: ${dynamo_table_name}
    audit_table_name: ${dynamo_events_table_name}
    audit_sessions_uri: s3://${s3_bucket}/records

auth_service:
  enabled: yes
  listen_addr: 0.0.0.0:3025

  authentication:
    second_factor: off
    type: oidc

  cluster_name: ${cluster_name}

ssh_service:
  enabled: no

proxy_service:
  enabled: no
EOF

# Install and start teleport systemd unit.
# Notice that Auth server does not need to run as root
# as it does not handle any interactive sessions,
# only serves HTTPs API server.
cat >/etc/systemd/system/teleport.service <<EOF
[Unit]
Description=Teleport SSH Service
After=network.target 

[Service]
User=teleport
Group=adm
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/local/bin/teleport start --config=/etc/teleport.yaml --diag-addr=127.0.0.1:3434 --pid-file=/var/run/teleport/teleport.pid
ExecReload=/bin/kill -HUP \$$MAINPID
PIDFile=/var/run/teleport/teleport.pid
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF
systemctl enable teleport
systemctl start teleport


# Script that makes sure that only one auth server processes
# requests at a time, by using dynamodb-backed locking.
# The lock is implemented as item in DynamoDB table:  {"Lock": "lock1", "Expires": "time", "Process": "server1"}
# The auth server node either renews the lease if lock "Process" holds the server id as owner of the lock
# or grabs the lock in case if expires column indicates that the lease has not been renewed after timeout.
# This pattern can be implemented in many different ways, e.g. using ASG group of 1 as a separate process
# or in Kubernetes as a deployment of scale 1.
cat >/usr/local/bin/teleport-lock <<EOF
#!/bin/bash
set -x

LOCK="/teleport/${cluster_name}"
NOW=\$$(date +%s)
TTL=\$$((\$$NOW+3660))
PROCESS="$${LOCAL_HOSTNAME}"
echo locking \$$PROCESS for \$$TTL

# Either renew the lease if agent still holds it, or grab the lease if it's expired
aws dynamodb put-item \
    --region ${region} \
    --table-name ${locks_table_name}\
    --item  "{\"Lock\": {\"S\": \"/auth/servers\"}, \"Expires\": {\"S\": \"\$$TTL\"}, \"Process\": {\"S\": \"\$$PROCESS\"}}" \
    --condition-expression="(attribute_not_exists(Expires) OR Expires <= :timestamp) OR Process = :process"\
    --expression-attribute-values "{\":timestamp\":{\"S\":\"\$$NOW\"}, \":process\":{\"S\":\"\$$PROCESS\"}}"

if [ \$$? -eq 0 ]; then
    echo "Renewed or locked the lease for \$$PROCESS until $(date -d @\$$TTL)"
else
    echo "Could get renew lease, locked by other process"
    exit 255
fi
EOF
chmod 755 /usr/local/bin/teleport-lock

# Install a service that rotates teleport join tokens.
# Teleport join tokens are temporary authentication tokens
# letting nodes and proxies to join to the cluster. Notice that timer
# unit rotates the current token every hour, but tokens are valid for 2 hours
# to handle timing cases.
cat >/usr/local/bin/teleport-ssm-publish-tokens <<EOF
#!/bin/bash
set -e
set -o pipefail

# Proxy token authenticates proxies joining the cluster
PROXY_TOKEN=\$$(uuid)
/usr/local/bin/tctl nodes add --roles=proxy --ttl=4h --token=\$${PROXY_TOKEN}
aws ssm put-parameter --name /teleport/${cluster_name}/tokens/proxy --region ${region} --type="SecureString" --value="\$${PROXY_TOKEN}" --overwrite

# Node token authenticates nodes joining the cluster
NODE_TOKEN=\$$(uuid)
/usr/local/bin/tctl nodes add --roles=node --ttl=4h --token=\$${NODE_TOKEN}
aws ssm put-parameter --name /teleport/${cluster_name}/tokens/node --region ${region} --type="SecureString" --value="\$${NODE_TOKEN}" --overwrite

# Export CA certificate to SSM parameter store
# so nodes and proxies can check the identity of the auth server they are connecting to
CERT=\$$(/usr/local/bin/tctl auth export --type=tls)
aws ssm put-parameter --name /teleport/${cluster_name}/ca --region ${region} --type="String" --value="\$${CERT}" --overwrite

{'fraction_non_alphanumeric': 0.12939660400242572, 'fraction_numerical': 0.013038204972710734, 'mean_word_length': 4.0840077071290946, 'pattern_counts': {'":': 30, '<': 23, '<?xml version=': 0, '>': 17, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 8, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '356596', 'n_tokens_mistral': 4517, 'n_tokens_neox': 4315, 'n_words': 1432}