Ansible Script 추가
This commit is contained in:
10
ansible/teleport_setting/ansible.cfg
Executable file
10
ansible/teleport_setting/ansible.cfg
Executable file
@@ -0,0 +1,10 @@
|
||||
[defaults]
|
||||
inventory = inventory
|
||||
roles_path = roles
|
||||
deprecation_warnings = False
|
||||
display_skipped_hosts = no
|
||||
ansible_home = .
|
||||
stdout_callback = debug
|
||||
host_key_checking=False
|
||||
#private_key_file=/root/.ssh/dev2-iac
|
||||
#remote_tmp = /tmp/.ansible/tmp
|
||||
10
ansible/teleport_setting/restart.yml
Normal file
10
ansible/teleport_setting/restart.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: "restart"
|
||||
hosts: all
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Restart teleport service
|
||||
ansible.builtin.systemd:
|
||||
name: teleport
|
||||
enabled: true
|
||||
state: restarted
|
||||
BIN
ansible/teleport_setting/roles/.DS_Store
vendored
Normal file
BIN
ansible/teleport_setting/roles/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
ansible/teleport_setting/roles/teleport/.DS_Store
vendored
Normal file
BIN
ansible/teleport_setting/roles/teleport/.DS_Store
vendored
Normal file
Binary file not shown.
38
ansible/teleport_setting/roles/teleport/README.md
Normal file
38
ansible/teleport_setting/roles/teleport/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
Role Name
|
||||
=========
|
||||
|
||||
A brief description of the role goes here.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
- hosts: servers
|
||||
roles:
|
||||
- { role: username.rolename, x: 42 }
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
# defaults file for teleport
|
||||
teleport_uri: teleport.kr.datasaker.io
|
||||
teleport_version: 13.3.8
|
||||
remove: False
|
||||
update: False
|
||||
install: False
|
||||
custom_labels: []
|
||||
|
||||
10
ansible/teleport_setting/roles/teleport/handlers/main.yml
Normal file
10
ansible/teleport_setting/roles/teleport/handlers/main.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Reload systemd configuration
|
||||
ansible.builtin.systemd:
|
||||
daemon_reload: True
|
||||
|
||||
- name: Restart teleport service
|
||||
ansible.builtin.systemd:
|
||||
name: teleport
|
||||
enabled: true
|
||||
state: restarted
|
||||
52
ansible/teleport_setting/roles/teleport/meta/main.yml
Normal file
52
ansible/teleport_setting/roles/teleport/meta/main.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.1
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
#
|
||||
# Provide a list of supported platforms, and for each platform a list of versions.
|
||||
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
|
||||
# To view available platforms and versions (or releases), visit:
|
||||
# https://galaxy.ansible.com/api/v1/platforms/
|
||||
#
|
||||
# platforms:
|
||||
# - name: Fedora
|
||||
# versions:
|
||||
# - all
|
||||
# - 25
|
||||
# - name: SomePlatform
|
||||
# versions:
|
||||
# - all
|
||||
# - 1.0
|
||||
# - 7
|
||||
# - 99.99
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
33
ansible/teleport_setting/roles/teleport/tasks/main.yml
Normal file
33
ansible/teleport_setting/roles/teleport/tasks/main.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
- name: "Create temporary directory for key manipulation"
|
||||
tempfile:
|
||||
state: directory
|
||||
suffix: keys
|
||||
register: tempdir
|
||||
when:
|
||||
- install == True or update == True
|
||||
- remove == False
|
||||
|
||||
- name: "Include Teleport Agent Install"
|
||||
include_tasks: teleport_install.yml
|
||||
tags: install
|
||||
when:
|
||||
- install == True
|
||||
|
||||
- name: "Include Teleport Agent update"
|
||||
include_tasks: teleport_update.yml
|
||||
tags: remove
|
||||
when:
|
||||
- update == True
|
||||
|
||||
- name: "Remove temporary directory for key manipulation"
|
||||
file:
|
||||
path: "{{ tempdir.path }}"
|
||||
state: absent
|
||||
when:
|
||||
- install == True or update == True
|
||||
|
||||
- name: "Include Teleport Agent remove"
|
||||
include_tasks: teleport_remove.yml
|
||||
tags: remove
|
||||
when:
|
||||
- remove == True
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
- name: "Run tctl nodes add and capture the output"
|
||||
command: tctl nodes add
|
||||
register: tctl_output
|
||||
changed_when: false
|
||||
delegate_to: 127.0.0.1
|
||||
|
||||
- name: "Extract token and ca_pin"
|
||||
set_fact:
|
||||
get_join_token: "{{ (tctl_output.stdout | regex_search('--token=(\\S+)', '\\1'))[0] }}"
|
||||
get_ca_pin: "{{ (tctl_output.stdout | regex_search('--ca-pin=(\\S+)', '\\1'))[0] }}"
|
||||
|
||||
- name: "Debug extracted values"
|
||||
debug:
|
||||
msg:
|
||||
- "join_token: {{ get_join_token }}"
|
||||
- "ca_pin: {{ get_ca_pin }}"
|
||||
|
||||
- name: "Create Teleport install script"
|
||||
template:
|
||||
src: install-node.sh.j2
|
||||
dest: "{{ tempdir.path }}/install-node.sh"
|
||||
|
||||
- name: "Run Teleport Install Script"
|
||||
command: "bash {{ tempdir.path }}/install-node.sh"
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
- name: "Remove Teleport on RedHat-based systems"
|
||||
yum:
|
||||
name: teleport
|
||||
state: absent
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- name: "Remove Teleport on Debian-based systems"
|
||||
apt:
|
||||
name: teleport
|
||||
state: absent
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: "Remove Teleport directories and files"
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
with_items:
|
||||
- /var/lib/teleport
|
||||
- /etc/teleport.yaml
|
||||
- /usr/local/bin/teleport
|
||||
- /usr/local/bin/tctl
|
||||
- /usr/local/bin/tsh
|
||||
|
||||
- name: "Kill Teleport processes"
|
||||
command: pkill -9 teleport
|
||||
ignore_errors: yes
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
|
||||
- name: "Run token the output"
|
||||
shell: "cat /etc/teleport.yaml | grep 'token_name:' | awk '{print $2}'"
|
||||
register: token_output
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Run ca_pin the output"
|
||||
shell: "cat /etc/teleport.yaml | grep 'ca_pin:' | awk '{print $2}'"
|
||||
register: ca_output
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Extract token and ca_pin"
|
||||
set_fact:
|
||||
get_join_token: "{{ token_output.stdout }}"
|
||||
get_ca_pin: "{{ ca_output.stdout }}"
|
||||
|
||||
- name: "Debug extracted values"
|
||||
debug:
|
||||
msg:
|
||||
- "join_token: {{ get_join_token }}"
|
||||
- "ca_pin: {{ get_ca_pin }}"
|
||||
|
||||
- name: "Update Teleport yaml"
|
||||
template:
|
||||
src: teleport.yaml.j2
|
||||
dest: "/etc/teleport.yaml"
|
||||
|
||||
- name: "Update Teleport on RedHat-based systems"
|
||||
yum:
|
||||
name: teleport
|
||||
state: latest
|
||||
when: ansible_os_family == "RedHat"
|
||||
notify:
|
||||
- Reload systemd configuration
|
||||
- Restart teleport service
|
||||
|
||||
- name: "Update Teleport on Debian-based systems"
|
||||
apt:
|
||||
name: teleport
|
||||
state: latest
|
||||
when: ansible_os_family == "Debian"
|
||||
notify:
|
||||
- Reload systemd configuration
|
||||
- Restart teleport service
|
||||
@@ -0,0 +1,999 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
SCRIPT_NAME="teleport-installer"
|
||||
|
||||
# default values
|
||||
ALIVE_CHECK_DELAY=3
|
||||
CONNECTIVITY_TEST_METHOD=""
|
||||
COPY_COMMAND="cp"
|
||||
DISTRO_TYPE=""
|
||||
IGNORE_CONNECTIVITY_CHECK="${TELEPORT_IGNORE_CONNECTIVITY_CHECK:-false}"
|
||||
LAUNCHD_CONFIG_PATH="/Library/LaunchDaemons"
|
||||
LOG_FILENAME="$(mktemp -t ${SCRIPT_NAME}.log.XXXXXXXXXX)"
|
||||
MACOS_STDERR_LOG="/var/log/teleport-stderr.log"
|
||||
MACOS_STDOUT_LOG="/var/log/teleport-stdout.log"
|
||||
SYSTEMD_UNIT_PATH="/lib/systemd/system/teleport.service"
|
||||
TARGET_PORT_DEFAULT=443
|
||||
TELEPORT_ARCHIVE_PATH='teleport'
|
||||
TELEPORT_BINARY_DIR="/usr/local/bin"
|
||||
TELEPORT_BINARY_LIST="teleport tctl tsh"
|
||||
TELEPORT_CONFIG_PATH="/etc/teleport.yaml"
|
||||
TELEPORT_DATA_DIR="/var/lib/teleport"
|
||||
TELEPORT_DOCS_URL="https://goteleport.com/docs/"
|
||||
TELEPORT_FORMAT=""
|
||||
|
||||
# initialise variables (because set -u disallows unbound variables)
|
||||
f=""
|
||||
l=""
|
||||
DISABLE_TLS_VERIFICATION=false
|
||||
NODENAME=$(hostname)
|
||||
IGNORE_CHECKS=false
|
||||
OVERRIDE_FORMAT=""
|
||||
QUIET=false
|
||||
APP_INSTALL_DECISION=""
|
||||
INTERACTIVE=false
|
||||
|
||||
# the default value of each variable is a templatable Go value so that it can
|
||||
# optionally be replaced by the server before the script is served up
|
||||
TELEPORT_VERSION='{{ teleport_version }}'
|
||||
TELEPORT_PACKAGE_NAME='teleport'
|
||||
REPO_CHANNEL=''
|
||||
TARGET_HOSTNAME='{{ teleport_uri }}'
|
||||
TARGET_PORT='443'
|
||||
JOIN_TOKEN='{{ get_join_token }}'
|
||||
JOIN_METHOD=''
|
||||
JOIN_METHOD_FLAG=""
|
||||
[ -n "$JOIN_METHOD" ] && JOIN_METHOD_FLAG="--join-method ${JOIN_METHOD}"
|
||||
|
||||
# inject labels into the configuration
|
||||
# LABELS='teleport.internal/resource-id=0ec993a8-b1ec-4fa6-8fc5-4e73e3e5306e','env=localhost'
|
||||
LABELS='ipaddr={{ansible_default_ipv4.address}},group={{ group_names[-1] }},os={{ ansible_distribution }}{% if custom_labels %},{{ custom_labels }}{% endif %}'
|
||||
LABELS_FLAG=()
|
||||
[ -n "$LABELS" ] && LABELS_FLAG=(--labels "${LABELS}")
|
||||
|
||||
LABELS_FLAG=()
|
||||
[ -n "$LABELS" ] && LABELS_FLAG=(--labels "${LABELS}")
|
||||
|
||||
# When all stanza generators have been updated to use the new
|
||||
# `teleport <service> configure` commands CA_PIN_HASHES can be removed along
|
||||
# with the script passing it in in `join_tokens.go`.
|
||||
CA_PIN_HASHES='{{ get_ca_pin }}'
|
||||
CA_PINS='{{ get_ca_pin }}'
|
||||
ARG_CA_PIN_HASHES=""
|
||||
APP_INSTALL_MODE='false'
|
||||
APP_NAME=''
|
||||
APP_URI=''
|
||||
DB_INSTALL_MODE='false'
|
||||
|
||||
# usage message
|
||||
# shellcheck disable=SC2086
|
||||
usage() { echo "Usage: $(basename $0) [-v teleport_version] [-h target_hostname] [-p target_port] [-j join_token] [-c ca_pin_hash]... [-q] [-l log_filename] [-a app_name] [-u app_uri] " 1>&2; exit 1; }
|
||||
while getopts ":v:h:p:j:c:f:ql:ika:u:" o; do
|
||||
case "${o}" in
|
||||
v) TELEPORT_VERSION=${OPTARG};;
|
||||
h) TARGET_HOSTNAME=${OPTARG};;
|
||||
p) TARGET_PORT=${OPTARG};;
|
||||
j) JOIN_TOKEN=${OPTARG};;
|
||||
c) ARG_CA_PIN_HASHES="${ARG_CA_PIN_HASHES} ${OPTARG}";;
|
||||
f) f=${OPTARG}; if [[ ${f} != "tarball" && ${f} != "deb" && ${f} != "rpm" ]]; then usage; fi;;
|
||||
q) QUIET=true;;
|
||||
l) l=${OPTARG};;
|
||||
i) IGNORE_CHECKS=true; COPY_COMMAND="cp -f";;
|
||||
k) DISABLE_TLS_VERIFICATION=true;;
|
||||
a) APP_INSTALL_MODE=true && APP_NAME=${OPTARG};;
|
||||
u) APP_INSTALL_MODE=true && APP_URI=${OPTARG};;
|
||||
*) usage;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [[ "${ARG_CA_PIN_HASHES}" != "" ]]; then
|
||||
CA_PIN_HASHES="${ARG_CA_PIN_HASHES}"
|
||||
fi
|
||||
|
||||
# function to construct a go template variable
|
||||
# go's template parser is a bit finicky, so we dynamically build the value one character at a time
|
||||
construct_go_template() {
|
||||
OUTPUT="{"
|
||||
OUTPUT+="{"
|
||||
OUTPUT+="."
|
||||
OUTPUT+="${1}"
|
||||
OUTPUT+="}"
|
||||
OUTPUT+="}"
|
||||
echo "${OUTPUT}"
|
||||
}
|
||||
|
||||
# check whether we are root, exit if not
|
||||
assert_running_as_root() {
|
||||
if ! [ "$(id -u)" = 0 ]; then
|
||||
echo "This script must be run as root." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# function to check whether variables are either blank or set to the default go template value
|
||||
# (because they haven't been set by the go script generator or a command line argument)
|
||||
# returns 1 if the variable is set to a default/zero value
|
||||
# returns 0 otherwise (i.e. it needs to be set interactively)
|
||||
check_variable() {
|
||||
VARIABLE_VALUE="${!1}"
|
||||
GO_TEMPLATE_NAME=$(construct_go_template "${2}")
|
||||
if [[ "${VARIABLE_VALUE}" == "" ]] || [[ "${VARIABLE_VALUE}" == "${GO_TEMPLATE_NAME}" ]]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# function to check whether a provided value is "truthy" i.e. it looks like you're trying to say "yes"
|
||||
is_truthy() {
|
||||
declare -a TRUTHY_VALUES
|
||||
TRUTHY_VALUES=("y" "Y" "yes" "YES" "ye" "YE" "yep" "YEP" "ya" "YA")
|
||||
CHECK_VALUE="$1"
|
||||
for ARRAY_VALUE in "${TRUTHY_VALUES[@]}"; do [[ "${CHECK_VALUE}" == "${ARRAY_VALUE}" ]] && return 0; done
|
||||
return 1
|
||||
}
|
||||
|
||||
# function to read input until the value you get is non-empty
|
||||
read_nonblank_input() {
|
||||
INPUT=""
|
||||
VARIABLE_TO_ASSIGN="$1"
|
||||
shift
|
||||
PROMPT="$*"
|
||||
until [[ "${INPUT}" != "" ]]; do
|
||||
echo -n "${PROMPT}"
|
||||
read -r INPUT
|
||||
done
|
||||
printf -v "${VARIABLE_TO_ASSIGN}" '%s' "${INPUT}"
|
||||
}
|
||||
|
||||
# error if we're not root
|
||||
assert_running_as_root
|
||||
|
||||
# set/read values interactively if not provided
|
||||
# users will be prompted to enter their own value if all the following are true:
|
||||
# - the current value is blank, or equal to the default Go template value
|
||||
# - the value has not been provided by command line argument
|
||||
! check_variable TELEPORT_VERSION version && INTERACTIVE=true && read_nonblank_input TELEPORT_VERSION "Enter Teleport version to install (without v): "
|
||||
! check_variable TARGET_HOSTNAME hostname && INTERACTIVE=true && read_nonblank_input TARGET_HOSTNAME "Enter target hostname to connect to: "
|
||||
! check_variable TARGET_PORT port && INTERACTIVE=true && { echo -n "Enter target port to connect to [${TARGET_PORT_DEFAULT}]: "; read -r TARGET_PORT; }
|
||||
! check_variable JOIN_TOKEN token && INTERACTIVE=true && read_nonblank_input JOIN_TOKEN "Enter Teleport join token as provided: "
|
||||
! check_variable CA_PIN_HASHES caPins && INTERACTIVE=true && read_nonblank_input CA_PIN_HASHES "Enter CA pin hash (separate multiple hashes with spaces): "
|
||||
[ -n "${f}" ] && OVERRIDE_FORMAT=${f}
|
||||
[ -n "${l}" ] && LOG_FILENAME=${l}
|
||||
# if app service mode is not set (or is the default value) and we are running interactively (i.e. the user has provided some input already),
|
||||
# prompt the user to choose whether to enable app_service
|
||||
if [[ "${INTERACTIVE}" == "true" ]]; then
|
||||
if ! check_variable APP_INSTALL_MODE appInstallMode; then
|
||||
APP_INSTALL_MODE="false"
|
||||
echo -n "Would you like to enable and configure Teleport's app_service, to use Teleport as a reverse proxy for a web application? [y/n, default: n] "
|
||||
read -r APP_INSTALL_DECISION
|
||||
if is_truthy "${APP_INSTALL_DECISION}"; then
|
||||
APP_INSTALL_MODE="true"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# prompt for extra needed values if we're running in app service mode
|
||||
if [[ "${APP_INSTALL_MODE}" == "true" ]]; then
|
||||
! check_variable APP_NAME appName && read_nonblank_input APP_NAME "Enter app name to install (must be DNS-compatible; less than 63 characters, no spaces, only - or _ as punctuation): "
|
||||
! check_variable APP_URI appURI && read_nonblank_input APP_URI "Enter app URI (the host running the Teleport app service must be able to connect to this): "
|
||||
# generate app public addr by concatenating values
|
||||
APP_PUBLIC_ADDR="${APP_NAME}.${TARGET_HOSTNAME}"
|
||||
fi
|
||||
|
||||
# set default target port if value not provided
|
||||
if [[ "${TARGET_PORT}" == "" ]]; then
|
||||
TARGET_PORT=${TARGET_PORT_DEFAULT}
|
||||
fi
|
||||
|
||||
# clear log file if provided
|
||||
if [[ "${LOG_FILENAME}" != "" ]]; then
|
||||
if [ -f "${LOG_FILENAME}" ]; then
|
||||
echo -n "" > "${LOG_FILENAME}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# log functions
|
||||
log_date() { echo -n "$(date '+%Y-%m-%d %H:%M:%S %Z')"; }
|
||||
log() {
|
||||
LOG_LINE="$(log_date) [${SCRIPT_NAME}] $*"
|
||||
if [[ ${QUIET} != "true" ]]; then
|
||||
echo "${LOG_LINE}"
|
||||
fi
|
||||
if [[ "${LOG_FILENAME}" != "" ]]; then
|
||||
echo "${LOG_LINE}" >> "${LOG_FILENAME}"
|
||||
fi
|
||||
}
|
||||
# writes a line with no timestamp or starting data, always prints
|
||||
log_only() {
|
||||
LOG_LINE="$*"
|
||||
echo "${LOG_LINE}"
|
||||
if [[ "${LOG_FILENAME}" != "" ]]; then
|
||||
echo "${LOG_LINE}" >> "${LOG_FILENAME}"
|
||||
fi
|
||||
}
|
||||
# writes a line by itself as a header
|
||||
log_header() {
|
||||
LOG_LINE="$*"
|
||||
echo ""
|
||||
echo "${LOG_LINE}"
|
||||
echo ""
|
||||
if [[ "${LOG_FILENAME}" != "" ]]; then
|
||||
echo "${LOG_LINE}" >> "${LOG_FILENAME}"
|
||||
fi
|
||||
}
|
||||
# important log lines, print even when -q (quiet) is passed
|
||||
log_important() {
|
||||
LOG_LINE="$(log_date) [${SCRIPT_NAME}] ---> $*"
|
||||
echo "${LOG_LINE}"
|
||||
if [[ "${LOG_FILENAME}" != "" ]]; then
|
||||
echo "${LOG_LINE}" >> "${LOG_FILENAME}"
|
||||
fi
|
||||
}
|
||||
log_cleanup_message() {
|
||||
log_only "This script does not overwrite any existing settings or Teleport installations."
|
||||
log_only "Please clean up by running any of the following steps as necessary:"
|
||||
log_only "- stop any running Teleport processes"
|
||||
log_only " - pkill -f teleport"
|
||||
log_only "- remove any data under ${TELEPORT_DATA_DIR}, along with the directory itself"
|
||||
log_only " - rm -rf ${TELEPORT_DATA_DIR}"
|
||||
log_only "- remove any configuration at ${TELEPORT_CONFIG_PATH}"
|
||||
log_only " - rm -f ${TELEPORT_CONFIG_PATH}"
|
||||
log_only "- remove any Teleport binaries (${TELEPORT_BINARY_LIST}) installed under ${TELEPORT_BINARY_DIR}"
|
||||
for BINARY in ${TELEPORT_BINARY_LIST}; do EXAMPLE_DELETE_COMMAND+="${TELEPORT_BINARY_DIR}/${BINARY} "; done
|
||||
log_only " - rm -f ${EXAMPLE_DELETE_COMMAND}"
|
||||
log_only "Run this installer again when done."
|
||||
log_only
|
||||
}
|
||||
|
||||
# other functions
|
||||
# check whether a named program exists
|
||||
check_exists() { NAME=$1; if type "${NAME}" >/dev/null 2>&1; then return 0; else return 1; fi; }
|
||||
# checks for the existence of a list of named binaries and exits with error if any of them don't exist
|
||||
check_exists_fatal() {
|
||||
for TOOL in "$@"; do
|
||||
if ! check_exists "${TOOL}"; then
|
||||
log_important "Error: cannot find ${TOOL} - it needs to be installed"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
# check connectivity to the given host/port and make a request to see if Teleport is listening
|
||||
# uses the global variable CONNECTIVITY_TEST_METHOD to return the name of the checker, as return
|
||||
# values aren't really a thing that exists in bash
|
||||
check_connectivity() {
|
||||
HOST=$1
|
||||
PORT=$2
|
||||
# check with nc
|
||||
if check_exists nc; then
|
||||
CONNECTIVITY_TEST_METHOD="nc"
|
||||
if nc -z -w3 "${HOST}" "${PORT}" >/dev/null 2>&1; then return 0; else return 1; fi
|
||||
# if there's no nc, check with telnet
|
||||
elif check_exists telnet; then
|
||||
CONNECTIVITY_TEST_METHOD="telnet"
|
||||
if echo -e '\x1dclose\x0d' | telnet "${HOST}" "${PORT}" >/dev/null 2>&1; then return 0; else return 1; fi
|
||||
# if there's no nc or telnet, try and use /dev/tcp
|
||||
elif [ -f /dev/tcp ]; then
|
||||
CONNECTIVITY_TEST_METHOD="/dev/tcp"
|
||||
if (head -1 < "/dev/tcp/${HOST}/${PORT}") >/dev/null 2>&1; then return 0; else return 1; fi
|
||||
else
|
||||
return 255
|
||||
fi
|
||||
}
|
||||
# check whether a teleport DEB is already installed and exit with error if so
|
||||
check_deb_not_already_installed() {
|
||||
check_exists_fatal dpkg awk
|
||||
DEB_INSTALLED=$(dpkg -l | awk '{print $2}' | grep -E ^teleport || true)
|
||||
if [[ ${DEB_INSTALLED} != "" ]]; then
|
||||
log_important "It looks like there is already a Teleport DEB package installed (name: ${DEB_INSTALLED})."
|
||||
log_important "You will need to remove that package before using this script."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
# check whether a teleport RPM is already installed and exit with error if so
|
||||
check_rpm_not_already_installed() {
|
||||
check_exists_fatal rpm
|
||||
RPM_INSTALLED=$(rpm -qa | grep -E ^teleport || true)
|
||||
if [[ ${RPM_INSTALLED} != "" ]]; then
|
||||
log_important "It looks like there is already a Teleport RPM package installed (name: ${RPM_INSTALLED})."
|
||||
log_important "You will need to remove that package before using this script."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
# function to check if given variable is set
|
||||
check_set() {
|
||||
CHECK_KEY=${1} || true
|
||||
CHECK_VALUE=${!1} || true
|
||||
if [[ "${CHECK_VALUE}" == "" ]]; then
|
||||
log "Required variable ${CHECK_KEY} is not set"
|
||||
exit 1
|
||||
else
|
||||
log "${CHECK_KEY}: ${CHECK_VALUE}"
|
||||
fi
|
||||
}
|
||||
# checks that teleport binary can be found in path and runs 'teleport version'
|
||||
check_teleport_binary() {
|
||||
FOUND_TELEPORT_VERSION=$(${TELEPORT_BINARY_DIR}/teleport version)
|
||||
if [[ "${FOUND_TELEPORT_VERSION}" == "" ]]; then
|
||||
log "Cannot find Teleport binary"
|
||||
return 1
|
||||
else
|
||||
log "Found: ${FOUND_TELEPORT_VERSION}";
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
# wrapper to download with curl
|
||||
download() {
|
||||
URL=$1
|
||||
OUTPUT_PATH=$2
|
||||
CURL_COMMAND="curl -fsSL --retry 5 --retry-delay 5"
|
||||
# optionally allow disabling of TLS verification (can be useful on older distros
|
||||
# which often have an out-of-date set of CA certificate bundle which won't validate)
|
||||
if [[ ${DISABLE_TLS_VERIFICATION} == "true" ]]; then
|
||||
CURL_COMMAND+=" -k"
|
||||
fi
|
||||
log "Running ${CURL_COMMAND} ${URL}"
|
||||
log "Downloading to ${OUTPUT_PATH}"
|
||||
# handle errors with curl
|
||||
if ! ${CURL_COMMAND} -o "${OUTPUT_PATH}" "${URL}"; then
|
||||
log_important "curl error downloading ${URL}"
|
||||
log "On an older OS, this may be related to the CA certificate bundle being too old."
|
||||
log "You can pass the hidden -k flag to this script to disable TLS verification - this is not recommended!"
|
||||
exit 1
|
||||
fi
|
||||
# check that the file has a non-zero size as an extra validation
|
||||
check_exists_fatal wc xargs
|
||||
FILE_SIZE="$(wc -c <"${OUTPUT_PATH}" | xargs)"
|
||||
if [ "${FILE_SIZE}" -eq 0 ]; then
|
||||
log_important "The downloaded file has a size of 0 bytes, which means an error occurred. Cannot continue."
|
||||
exit 1
|
||||
else
|
||||
log "Downloaded file size: ${FILE_SIZE} bytes"
|
||||
fi
|
||||
# if we have a hashing utility installed, also download and validate the checksum
|
||||
SHA_COMMAND=""
|
||||
# shasum is installed by default on MacOS and some distros
|
||||
if check_exists shasum; then
|
||||
SHA_COMMAND="shasum -a 256"
|
||||
# sha256sum is installed by default in some other distros
|
||||
elif check_exists sha256sum; then
|
||||
SHA_COMMAND="sha256sum"
|
||||
fi
|
||||
if [[ "${SHA_COMMAND}" != "" ]]; then
|
||||
log "Will use ${SHA_COMMAND} to validate the checksum of the downloaded file"
|
||||
SHA_URL="${URL}.sha256"
|
||||
SHA_PATH="${OUTPUT_PATH}.sha256"
|
||||
${CURL_COMMAND} -o "${SHA_PATH}" "${SHA_URL}"
|
||||
if ${SHA_COMMAND} --status -c "${SHA_PATH}"; then
|
||||
log "The downloaded file's checksum validated correctly"
|
||||
else
|
||||
SHA_EXPECTED=$(cat "${SHA_PATH}")
|
||||
SHA_ACTUAL=$(${SHA_COMMAND} "${OUTPUT_PATH}")
|
||||
if check_exists awk; then
|
||||
SHA_EXPECTED=$(echo "${SHA_EXPECTED}" | awk '{print $1}')
|
||||
SHA_ACTUAL=$(echo "${SHA_ACTUAL}" | awk '{print $1}')
|
||||
fi
|
||||
log_important "Checksum of the downloaded file did not validate correctly"
|
||||
log_important "Expected: ${SHA_EXPECTED}"
|
||||
log_important "Got: ${SHA_ACTUAL}"
|
||||
log_important "Try rerunning this script from the start. If the issue persists, contact Teleport support."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log "shasum/sha256sum utilities not found, will skip checksum validation"
|
||||
fi
|
||||
}
|
||||
# gets the filename from a full path (https://target.site/path/to/file.tar.gz -> file.tar.gz)
|
||||
get_download_filename() { echo "${1##*/}"; }
|
||||
# gets the pid of any running teleport process (and converts newlines to spaces)
|
||||
get_teleport_pid() {
|
||||
check_exists_fatal pgrep xargs
|
||||
pgrep teleport | xargs echo
|
||||
}
|
||||
# returns a command which will start teleport using the config
|
||||
get_teleport_start_command() {
|
||||
echo "${TELEPORT_BINARY_DIR}/teleport start --config=${TELEPORT_CONFIG_PATH}"
|
||||
}
|
||||
# installs the teleport-provided launchd config
|
||||
install_launchd_config() {
|
||||
log "Installing Teleport launchd config to ${LAUNCHD_CONFIG_PATH}"
|
||||
${COPY_COMMAND} ./${TELEPORT_ARCHIVE_PATH}/examples/launchd/com.goteleport.teleport.plist ${LAUNCHD_CONFIG_PATH}/com.goteleport.teleport.plist
|
||||
}
|
||||
# installs the teleport-provided systemd unit
|
||||
install_systemd_unit() {
|
||||
log "Installing Teleport systemd unit to ${SYSTEMD_UNIT_PATH}"
|
||||
${COPY_COMMAND} ./${TELEPORT_ARCHIVE_PATH}/examples/systemd/teleport.service ${SYSTEMD_UNIT_PATH}
|
||||
log "Reloading unit files (systemctl daemon-reload)"
|
||||
systemctl daemon-reload
|
||||
}
|
||||
# formats the arguments as a yaml list
|
||||
get_yaml_list() {
|
||||
name="${1}"
|
||||
list="${2}"
|
||||
indentation="${3}"
|
||||
echo "${indentation}${name}:"
|
||||
for item in ${list}; do
|
||||
echo "${indentation}- ${item}"
|
||||
done
|
||||
}
|
||||
|
||||
# installs the provided teleport config (for app service)
|
||||
install_teleport_app_config() {
|
||||
log "Writing Teleport app service config to ${TELEPORT_CONFIG_PATH}"
|
||||
CA_PINS_CONFIG=$(get_yaml_list "ca_pin" "${CA_PIN_HASHES}" " ")
|
||||
cat << EOF > ${TELEPORT_CONFIG_PATH}
|
||||
version: v3
|
||||
teleport:
|
||||
nodename: ${NODENAME}
|
||||
auth_token: ${JOIN_TOKEN}
|
||||
${CA_PINS_CONFIG}
|
||||
proxy_server: ${TARGET_HOSTNAME}:${TARGET_PORT}
|
||||
log:
|
||||
output: stderr
|
||||
severity: INFO
|
||||
auth_service:
|
||||
enabled: no
|
||||
ssh_service:
|
||||
enabled: no
|
||||
proxy_service:
|
||||
enabled: no
|
||||
app_service:
|
||||
enabled: yes
|
||||
apps:
|
||||
- name: "${APP_NAME}"
|
||||
uri: "${APP_URI}"
|
||||
public_addr: ${APP_PUBLIC_ADDR}
|
||||
EOF
|
||||
}
|
||||
# installs the provided teleport config (for database service)
|
||||
install_teleport_database_config() {
|
||||
log "Writing Teleport database service config to ${TELEPORT_CONFIG_PATH}"
|
||||
CA_PINS_CONFIG=$(get_yaml_list "ca_pin" "${CA_PIN_HASHES}" " ")
|
||||
|
||||
# This file is processed by `shellschek` as part of the lint step
|
||||
# It detects an issue because of un-set variables - $index and $line. This check is called SC2154.
|
||||
# However, that's not an issue, because those variables are replaced when we run go's text/template engine over it.
|
||||
# When executing the script, those are no long variables but actual values.
|
||||
# shellcheck disable=SC2154
|
||||
cat << EOF > ${TELEPORT_CONFIG_PATH}
|
||||
version: v3
|
||||
teleport:
|
||||
nodename: ${NODENAME}
|
||||
auth_token: ${JOIN_TOKEN}
|
||||
${CA_PINS_CONFIG}
|
||||
proxy_server: ${TARGET_HOSTNAME}:${TARGET_PORT}
|
||||
log:
|
||||
output: stderr
|
||||
severity: INFO
|
||||
auth_service:
|
||||
enabled: no
|
||||
ssh_service:
|
||||
enabled: no
|
||||
proxy_service:
|
||||
enabled: no
|
||||
db_service:
|
||||
enabled: "yes"
|
||||
resources:
|
||||
- labels:
|
||||
EOF
|
||||
}
|
||||
# installs the provided teleport config (for node service)
|
||||
install_teleport_node_config() {
|
||||
log "Writing Teleport node service config to ${TELEPORT_CONFIG_PATH}"
|
||||
${TELEPORT_BINARY_DIR}/teleport node configure \
|
||||
--token ${JOIN_TOKEN} \
|
||||
${JOIN_METHOD_FLAG} \
|
||||
--ca-pin ${CA_PINS} \
|
||||
--proxy ${TARGET_HOSTNAME}:${TARGET_PORT} \
|
||||
"${LABELS_FLAG[@]}" \
|
||||
--output ${TELEPORT_CONFIG_PATH}
|
||||
}
|
||||
# checks whether the given host is running MacOS
|
||||
is_macos_host() { if [[ ${OSTYPE} == "darwin"* ]]; then return 0; else return 1; fi }
|
||||
# checks whether teleport is already running on the host
|
||||
is_running_teleport() {
|
||||
check_exists_fatal pgrep
|
||||
TELEPORT_PID=$(get_teleport_pid)
|
||||
if [[ "${TELEPORT_PID}" != "" ]]; then return 0; else return 1; fi
|
||||
}
|
||||
# checks whether the given host is running systemd as its init system
|
||||
is_using_systemd() { if [ -d /run/systemd/system ]; then return 0; else return 1; fi }
|
||||
# prints a warning if the host isn't running systemd
|
||||
no_systemd_warning() {
|
||||
log_important "This host is not running systemd, so Teleport cannot be started automatically when it exits."
|
||||
log_important "Please investigate an alternative way to keep Teleport running."
|
||||
log_important "You can find information in our documentation: ${TELEPORT_DOCS_URL}"
|
||||
log_important "For now, Teleport will be started in the foreground - you can press Ctrl+C to exit."
|
||||
log_only
|
||||
log_only "Run this command to start Teleport in future:"
|
||||
log_only "$(get_teleport_start_command)"
|
||||
log_only
|
||||
log_only "------------------------------------------------------------------------"
|
||||
log_only "| IMPORTANT: TELEPORT WILL STOP RUNNING AFTER YOU CLOSE THIS TERMINAL! |"
|
||||
log_only "| YOU MUST CONFIGURE A SERVICE MANAGER TO MAKE IT RUN ON STARTUP! |"
|
||||
log_only "------------------------------------------------------------------------"
|
||||
log_only
|
||||
}
|
||||
# print a message giving the name of the node and a link to the docs
|
||||
# gives some debugging instructions if the service didn't start successfully
|
||||
print_welcome_message() {
|
||||
log_only ""
|
||||
if is_running_teleport; then
|
||||
log_only "Teleport has been started."
|
||||
log_only ""
|
||||
if is_using_systemd; then
|
||||
log_only "View its status with 'sudo systemctl status teleport.service'"
|
||||
log_only "View Teleport logs using 'sudo journalctl -u teleport.service'"
|
||||
log_only "To stop Teleport, run 'sudo systemctl stop teleport.service'"
|
||||
log_only "To start Teleport again if you stop it, run 'sudo systemctl start teleport.service'"
|
||||
elif is_macos_host; then
|
||||
log_only "View Teleport logs in '${MACOS_STDERR_LOG}' and '${MACOS_STDOUT_LOG}'"
|
||||
log_only "To stop Teleport, run 'sudo launchctl unload ${LAUNCHD_CONFIG_PATH}/com.goteleport.teleport.plist'"
|
||||
log_only "To start Teleport again if you stop it, run 'sudo launchctl load ${LAUNCHD_CONFIG_PATH}/com.goteleport.teleport.plist'"
|
||||
fi
|
||||
log_only ""
|
||||
log_only "You can see this node connected in the Teleport web UI or 'tsh ls' with the name '${NODENAME}'"
|
||||
log_only "Find more details on how to use Teleport here: https://goteleport.com/docs/user-manual/"
|
||||
else
|
||||
log_important "The Teleport service was installed, but it does not appear to have started successfully."
|
||||
if is_using_systemd; then
|
||||
log_important "Check the Teleport service's status with 'systemctl status teleport.service'"
|
||||
log_important "View Teleport logs with 'journalctl -u teleport.service'"
|
||||
elif is_macos_host; then
|
||||
log_important "Check Teleport logs in '${MACOS_STDERR_LOG}' and '${MACOS_STDOUT_LOG}'"
|
||||
fi
|
||||
log_important "Contact Teleport support for further assistance."
|
||||
fi
|
||||
log_only ""
|
||||
}
|
||||
# start teleport in foreground (when there's no systemd)
|
||||
start_teleport_foreground() {
|
||||
log "Starting Teleport in the foreground"
|
||||
# shellcheck disable=SC2091
|
||||
$(get_teleport_start_command)
|
||||
}
|
||||
# start teleport via launchd (after installing config)
|
||||
start_teleport_launchd() {
|
||||
log "Starting Teleport via launchctl. It will automatically be started whenever the system reboots."
|
||||
launchctl load ${LAUNCHD_CONFIG_PATH}/com.goteleport.teleport.plist
|
||||
sleep ${ALIVE_CHECK_DELAY}
|
||||
}
|
||||
# start teleport via systemd (after installing unit)
|
||||
start_teleport_systemd() {
|
||||
log "Starting Teleport via systemd. It will automatically be started whenever the system reboots."
|
||||
systemctl enable teleport.service
|
||||
systemctl start teleport.service
|
||||
sleep ${ALIVE_CHECK_DELAY}
|
||||
}
|
||||
# checks whether teleport binaries exist on the host
|
||||
teleport_binaries_exist() {
|
||||
for BINARY_NAME in teleport tctl tsh; do
|
||||
if [ -f ${TELEPORT_BINARY_DIR}/${BINARY_NAME} ]; then return 0; else return 1; fi
|
||||
done
|
||||
}
|
||||
# checks whether a teleport config exists on the host
|
||||
teleport_config_exists() { if [ -f ${TELEPORT_CONFIG_PATH} ]; then return 0; else return 1; fi; }
|
||||
# checks whether a teleport data dir exists on the host
|
||||
teleport_datadir_exists() { if [ -d ${TELEPORT_DATA_DIR} ]; then return 0; else return 1; fi; }
|
||||
|
||||
# error out if any required values are not set
|
||||
check_set TELEPORT_VERSION
|
||||
check_set TARGET_HOSTNAME
|
||||
check_set TARGET_PORT
|
||||
check_set JOIN_TOKEN
|
||||
check_set CA_PIN_HASHES
|
||||
if [[ "${APP_INSTALL_MODE}" == "true" ]]; then
|
||||
check_set APP_NAME
|
||||
check_set APP_URI
|
||||
check_set APP_PUBLIC_ADDR
|
||||
fi
|
||||
|
||||
###
|
||||
# main script starts here
|
||||
###
|
||||
# check connectivity to teleport server/port
|
||||
if [[ "${IGNORE_CONNECTIVITY_CHECK}" == "true" ]]; then
|
||||
log "TELEPORT_IGNORE_CONNECTIVITY_CHECK=true, not running connectivity check"
|
||||
else
|
||||
log "Checking TCP connectivity to Teleport server (${TARGET_HOSTNAME}:${TARGET_PORT})"
|
||||
if ! check_connectivity "${TARGET_HOSTNAME}" "${TARGET_PORT}"; then
|
||||
# if we don't have a connectivity test method assigned, we know we couldn't run the test
|
||||
if [[ ${CONNECTIVITY_TEST_METHOD} == "" ]]; then
|
||||
log "Couldn't find nc, telnet or /dev/tcp to do a connection test"
|
||||
log "Going to blindly continue without testing connectivity"
|
||||
else
|
||||
log_important "Couldn't open a connection to the Teleport server (${TARGET_HOSTNAME}:${TARGET_PORT}) via ${CONNECTIVITY_TEST_METHOD}"
|
||||
log_important "This issue will need to be fixed before the script can continue."
|
||||
log_important "If you think this is an error, add 'export TELEPORT_IGNORE_CONNECTIVITY_CHECK=true && ' before the curl command which runs the script."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log "Connectivity to Teleport server (via ${CONNECTIVITY_TEST_METHOD}) looks good"
|
||||
fi
|
||||
fi
|
||||
|
||||
# use OSTYPE variable to figure out host type/arch
|
||||
if [[ "${OSTYPE}" == "linux-gnu"* ]]; then
|
||||
# linux host, now detect arch
|
||||
TELEPORT_BINARY_TYPE="linux"
|
||||
ARCH=$(uname -m)
|
||||
log "Detected host: ${OSTYPE}, using Teleport binary type ${TELEPORT_BINARY_TYPE}"
|
||||
if [[ ${ARCH} == "armv7l" ]]; then
|
||||
TELEPORT_ARCH="arm"
|
||||
elif [[ ${ARCH} == "aarch64" ]]; then
|
||||
TELEPORT_ARCH="arm64"
|
||||
elif [[ ${ARCH} == "x86_64" ]]; then
|
||||
TELEPORT_ARCH="amd64"
|
||||
elif [[ ${ARCH} == "i686" ]]; then
|
||||
TELEPORT_ARCH="386"
|
||||
else
|
||||
log_important "Error: cannot detect architecture from uname -m: ${ARCH}"
|
||||
exit 1
|
||||
fi
|
||||
log "Detected arch: ${ARCH}, using Teleport arch ${TELEPORT_ARCH}"
|
||||
# if the download format is already set, we have no need to detect distro
|
||||
if [[ ${TELEPORT_FORMAT} == "" ]]; then
|
||||
# detect distro
|
||||
# if /etc/os-release doesn't exist, we need to use some other logic
|
||||
if [ ! -f /etc/os-release ]; then
|
||||
if [ -f /etc/centos-release ]; then
|
||||
if grep -q 'CentOS release 6' /etc/centos-release; then
|
||||
log_important "Detected host type: CentOS 6 [$(cat /etc/centos-release)]"
|
||||
log_important "Teleport will not work on CentOS 6 -based servers due to the glibc version being too low."
|
||||
exit 1
|
||||
fi
|
||||
elif [ -f /etc/redhat-release ]; then
|
||||
if grep -q 'Red Hat Enterprise Linux Server release 5' /etc/redhat-release; then
|
||||
log_important "Detected host type: RHEL5 [$(cat /etc/redhat-release)]"
|
||||
log_important "Teleport will not work on RHEL5-based servers due to the glibc version being too low."
|
||||
exit 1
|
||||
elif grep -q 'Red Hat Enterprise Linux Server release 6' /etc/redhat-release; then
|
||||
log_important "Detected host type: RHEL6 [$(cat /etc/redhat-release)]"
|
||||
log_important "Teleport will not work on RHEL6-based servers due to the glibc version being too low."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# use ID_LIKE value from /etc/os-release (if set)
|
||||
# this is 'debian' on ubuntu/raspbian, 'centos rhel fedora' on amazon linux etc
|
||||
else
|
||||
check_exists_fatal cut
|
||||
DISTRO_TYPE=$(grep ID_LIKE /etc/os-release | cut -d= -f2) || true
|
||||
if [[ ${DISTRO_TYPE} == "" ]]; then
|
||||
# use exact ID value from /etc/os-release if ID_LIKE is not set
|
||||
DISTRO_TYPE=$(grep -w ID /etc/os-release | cut -d= -f2)
|
||||
fi
|
||||
if [[ ${DISTRO_TYPE} =~ "debian" ]]; then
|
||||
TELEPORT_FORMAT="deb"
|
||||
elif [[ "$DISTRO_TYPE" =~ "amzn"* ]] || [[ ${DISTRO_TYPE} =~ "centos"* ]] || [[ ${DISTRO_TYPE} =~ "rhel" ]] || [[ ${DISTRO_TYPE} =~ "fedora"* ]]; then
|
||||
TELEPORT_FORMAT="rpm"
|
||||
else
|
||||
log "Couldn't match a distro type using /etc/os-release, falling back to tarball installer"
|
||||
TELEPORT_FORMAT="tarball"
|
||||
fi
|
||||
fi
|
||||
log "Detected distro type: ${DISTRO_TYPE}"
|
||||
#suse, also identified as sles, uses a different path for its systemd then other distro types like ubuntu
|
||||
if [[ ${DISTRO_TYPE} =~ "suse"* ]] || [[ ${DISTRO_TYPE} =~ "sles"* ]]; then
|
||||
SYSTEMD_UNIT_PATH="/etc/systemd/system/teleport.service"
|
||||
fi
|
||||
fi
|
||||
elif [[ "${OSTYPE}" == "darwin"* ]]; then
|
||||
# macos host, now detect arch
|
||||
TELEPORT_BINARY_TYPE="darwin"
|
||||
ARCH=$(uname -m)
|
||||
log "Detected host: ${OSTYPE}, using Teleport binary type ${TELEPORT_BINARY_TYPE}"
|
||||
if [[ ${ARCH} == "arm64" ]]; then
|
||||
TELEPORT_ARCH="arm64"
|
||||
elif [[ ${ARCH} == "x86_64" ]]; then
|
||||
TELEPORT_ARCH="amd64"
|
||||
else
|
||||
log_important "Error: unsupported architecture from uname -m: ${ARCH}"
|
||||
exit 1
|
||||
fi
|
||||
log "Detected MacOS ${ARCH} architecture, using Teleport arch ${TELEPORT_ARCH}"
|
||||
TELEPORT_FORMAT="tarball"
|
||||
else
|
||||
log_important "Error - unsupported platform: ${OSTYPE}"
|
||||
exit 1
|
||||
fi
|
||||
log "Using Teleport distribution: ${TELEPORT_FORMAT}"
|
||||
|
||||
# create temporary directory and exit cleanup logic
|
||||
TEMP_DIR=$(mktemp -d -t teleport-XXXXXXXXXX)
|
||||
log "Created temp dir ${TEMP_DIR}"
|
||||
pushd "${TEMP_DIR}" >/dev/null 2>&1
|
||||
|
||||
finish() {
|
||||
popd >/dev/null 2>&1
|
||||
rm -rf "${TEMP_DIR}"
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
# optional format override (mostly for testing)
|
||||
if [[ ${OVERRIDE_FORMAT} != "" ]]; then
|
||||
TELEPORT_FORMAT="${OVERRIDE_FORMAT}"
|
||||
log "Overriding TELEPORT_FORMAT to ${OVERRIDE_FORMAT}"
|
||||
fi
|
||||
|
||||
# check whether teleport is running already
|
||||
# if it is, we exit gracefully with an error
|
||||
if is_running_teleport; then
|
||||
if [[ ${IGNORE_CHECKS} != "true" ]]; then
|
||||
TELEPORT_PID=$(get_teleport_pid)
|
||||
log_header "Warning: Teleport appears to already be running on this host (pid: ${TELEPORT_PID})"
|
||||
log_cleanup_message
|
||||
exit 1
|
||||
else
|
||||
log "Ignoring is_running_teleport as requested"
|
||||
fi
|
||||
fi
|
||||
|
||||
# check for existing config file
|
||||
if teleport_config_exists; then
|
||||
if [[ ${IGNORE_CHECKS} != "true" ]]; then
|
||||
log_header "Warning: There is already a Teleport config file present at ${TELEPORT_CONFIG_PATH}."
|
||||
log_cleanup_message
|
||||
exit 1
|
||||
else
|
||||
log "Ignoring teleport_config_exists as requested"
|
||||
fi
|
||||
fi
|
||||
|
||||
# check for existing data directory
|
||||
if teleport_datadir_exists; then
|
||||
if [[ ${IGNORE_CHECKS} != "true" ]]; then
|
||||
log_header "Warning: Found existing Teleport data directory (${TELEPORT_DATA_DIR})."
|
||||
log_cleanup_message
|
||||
exit 1
|
||||
else
|
||||
log "Ignoring teleport_datadir_exists as requested"
|
||||
fi
|
||||
fi
|
||||
|
||||
# check for existing binaries
|
||||
if teleport_binaries_exist; then
|
||||
if [[ ${IGNORE_CHECKS} != "true" ]]; then
|
||||
log_header "Warning: Found existing Teleport binaries under ${TELEPORT_BINARY_DIR}."
|
||||
log_cleanup_message
|
||||
exit 1
|
||||
else
|
||||
log "Ignoring teleport_binaries_exist as requested"
|
||||
fi
|
||||
fi
|
||||
|
||||
install_from_file() {
|
||||
# select correct URL/installation method based on distro
|
||||
if [[ ${TELEPORT_FORMAT} == "tarball" ]]; then
|
||||
URL="https://get.gravitational.com/${TELEPORT_PACKAGE_NAME}-v${TELEPORT_VERSION}-${TELEPORT_BINARY_TYPE}-${TELEPORT_ARCH}-bin.tar.gz"
|
||||
|
||||
# check that needed tools are installed
|
||||
check_exists_fatal curl tar
|
||||
# download tarball
|
||||
log "Downloading Teleport ${TELEPORT_FORMAT} release ${TELEPORT_VERSION}"
|
||||
DOWNLOAD_FILENAME=$(get_download_filename "${URL}")
|
||||
download "${URL}" "${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
# extract tarball
|
||||
tar -xzf "${TEMP_DIR}/${DOWNLOAD_FILENAME}" -C "${TEMP_DIR}"
|
||||
# install binaries to /usr/local/bin
|
||||
for BINARY in ${TELEPORT_BINARY_LIST}; do
|
||||
${COPY_COMMAND} "${TELEPORT_ARCHIVE_PATH}/${BINARY}" "${TELEPORT_BINARY_DIR}/"
|
||||
done
|
||||
elif [[ ${TELEPORT_FORMAT} == "deb" ]]; then
|
||||
# convert teleport arch to deb arch
|
||||
if [[ ${TELEPORT_ARCH} == "amd64" ]]; then
|
||||
DEB_ARCH="amd64"
|
||||
elif [[ ${TELEPORT_ARCH} == "386" ]]; then
|
||||
DEB_ARCH="i386"
|
||||
elif [[ ${TELEPORT_ARCH} == "arm" ]]; then
|
||||
DEB_ARCH="arm"
|
||||
elif [[ ${TELEPORT_ARCH} == "arm64" ]]; then
|
||||
DEB_ARCH="arm64"
|
||||
fi
|
||||
URL="https://get.gravitational.com/${TELEPORT_PACKAGE_NAME}_${TELEPORT_VERSION}_${DEB_ARCH}.deb"
|
||||
check_deb_not_already_installed
|
||||
# check that needed tools are installed
|
||||
check_exists_fatal curl dpkg
|
||||
# download deb and register cleanup operation
|
||||
log "Downloading Teleport ${TELEPORT_FORMAT} release ${TELEPORT_VERSION}"
|
||||
DOWNLOAD_FILENAME=$(get_download_filename "${URL}")
|
||||
download "${URL}" "${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
# install deb
|
||||
log "Using dpkg to install ${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
dpkg -i "${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
elif [[ ${TELEPORT_FORMAT} == "rpm" ]]; then
|
||||
# convert teleport arch to rpm arch
|
||||
if [[ ${TELEPORT_ARCH} == "amd64" ]]; then
|
||||
RPM_ARCH="x86_64"
|
||||
elif [[ ${TELEPORT_ARCH} == "386" ]]; then
|
||||
RPM_ARCH="i386"
|
||||
elif [[ ${TELEPORT_ARCH} == "arm" ]]; then
|
||||
RPM_ARCH="arm"
|
||||
elif [[ ${TELEPORT_ARCH} == "arm64" ]]; then
|
||||
RPM_ARCH="arm64"
|
||||
fi
|
||||
URL="https://get.gravitational.com/${TELEPORT_PACKAGE_NAME}-${TELEPORT_VERSION}-1.${RPM_ARCH}.rpm"
|
||||
check_rpm_not_already_installed
|
||||
# check for package managers
|
||||
if check_exists dnf; then
|
||||
log "Found 'dnf' package manager, using it"
|
||||
PACKAGE_MANAGER_COMMAND="dnf -y install"
|
||||
elif check_exists yum; then
|
||||
log "Found 'yum' package manager, using it"
|
||||
PACKAGE_MANAGER_COMMAND="yum -y localinstall"
|
||||
else
|
||||
PACKAGE_MANAGER_COMMAND=""
|
||||
log "Cannot find 'yum' or 'dnf' package manager commands, will try installing the rpm manually instead"
|
||||
fi
|
||||
# check that needed tools are installed
|
||||
check_exists_fatal curl
|
||||
log "Downloading Teleport ${TELEPORT_FORMAT} release ${TELEPORT_VERSION}"
|
||||
DOWNLOAD_FILENAME=$(get_download_filename "${URL}")
|
||||
download "${URL}" "${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
# install with package manager if available
|
||||
if [[ ${PACKAGE_MANAGER_COMMAND} != "" ]]; then
|
||||
log "Installing Teleport release from ${TEMP_DIR}/${DOWNLOAD_FILENAME} using ${PACKAGE_MANAGER_COMMAND}"
|
||||
# install rpm with package manager
|
||||
${PACKAGE_MANAGER_COMMAND} "${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
# use rpm if we couldn't find a package manager
|
||||
else
|
||||
# install RPM (in upgrade mode)
|
||||
log "Using rpm to install ${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
rpm -Uvh "${TEMP_DIR}/${DOWNLOAD_FILENAME}"
|
||||
fi
|
||||
else
|
||||
log_important "Can't figure out what Teleport format to use"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_from_repo() {
|
||||
if [[ "${REPO_CHANNEL}" == "" ]]; then
|
||||
# By default, use the current version's channel.
|
||||
REPO_CHANNEL=stable/v"${TELEPORT_VERSION//.*/}"
|
||||
fi
|
||||
|
||||
# Populate $ID, $VERSION_ID, $VERSION_CODENAME and other env vars identifying the OS.
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
|
||||
PACKAGE_LIST=$(package_list)
|
||||
if [ "$ID" == "debian" ] || [ "$ID" == "ubuntu" ]; then
|
||||
# old versions of ubuntu require that keys get added by `apt-key add`, without
|
||||
# adding the key apt shows a key signing error when installing teleport.
|
||||
if [[
|
||||
($ID == "ubuntu" && $VERSION_ID == "16.04") || \
|
||||
($ID == "debian" && $VERSION_ID == "9" )
|
||||
]]; then
|
||||
apt install apt-transport-https gnupg -y
|
||||
curl -fsSL https://apt.releases.teleport.dev/gpg | apt-key add -
|
||||
echo "deb https://apt.releases.teleport.dev/${ID} ${VERSION_CODENAME} ${REPO_CHANNEL}" > /etc/apt/sources.list.d/teleport.list
|
||||
else
|
||||
curl -fsSL https://apt.releases.teleport.dev/gpg \
|
||||
-o /usr/share/keyrings/teleport-archive-keyring.asc
|
||||
echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \
|
||||
https://apt.releases.teleport.dev/${ID} ${VERSION_CODENAME} ${REPO_CHANNEL}" > /etc/apt/sources.list.d/teleport.list
|
||||
fi
|
||||
apt-get update
|
||||
apt-get install -y ${PACKAGE_LIST}
|
||||
elif [ "$ID" = "amzn" ] || [ "$ID" = "rhel" ] || [ "$ID" = "centos" ] ; then
|
||||
if [ "$ID" = "rhel" ]; then
|
||||
VERSION_ID="${VERSION_ID//.*/}" # convert version numbers like '7.2' to only include the major version
|
||||
fi
|
||||
yum install -y yum-utils
|
||||
yum-config-manager --add-repo \
|
||||
"$(rpm --eval "https://yum.releases.teleport.dev/$ID/$VERSION_ID/Teleport/%{_arch}/${REPO_CHANNEL}/teleport.repo")"
|
||||
|
||||
# Remove metadata cache to prevent cache from other channel (eg, prior version)
|
||||
# See: https://github.com/gravitational/teleport/issues/22581
|
||||
yum --disablerepo="*" --enablerepo="teleport" clean metadata
|
||||
|
||||
yum install -y ${PACKAGE_LIST}
|
||||
else
|
||||
echo "Unsupported distro: $ID"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# package_list returns the list of packages to install.
|
||||
# The list of packages can be fed into yum or apt because they already have the expected format when pinning versions.
|
||||
package_list() {
|
||||
TELEPORT_PACKAGE_PIN_VERSION=${TELEPORT_PACKAGE_NAME}
|
||||
TELEPORT_UPDATER_PIN_VERSION="${TELEPORT_PACKAGE_NAME}-updater"
|
||||
|
||||
if [[ "${TELEPORT_FORMAT}" == "deb" ]]; then
|
||||
TELEPORT_PACKAGE_PIN_VERSION+="=${TELEPORT_VERSION}"
|
||||
TELEPORT_UPDATER_PIN_VERSION+="=${TELEPORT_VERSION}"
|
||||
|
||||
elif [[ "${TELEPORT_FORMAT}" == "rpm" ]]; then
|
||||
TELEPORT_YUM_VERSION="${TELEPORT_VERSION//-/_}"
|
||||
TELEPORT_PACKAGE_PIN_VERSION+="-${TELEPORT_YUM_VERSION}"
|
||||
TELEPORT_UPDATER_PIN_VERSION+="-${TELEPORT_YUM_VERSION}"
|
||||
fi
|
||||
|
||||
PACKAGE_LIST=${TELEPORT_PACKAGE_PIN_VERSION}
|
||||
# (warning): This expression is constant. Did you forget the $ on a variable?
|
||||
# Disabling the warning above because expression is templated.
|
||||
# shellcheck disable=SC2050
|
||||
if is_using_systemd && [[ "false" == "true" ]]; then
|
||||
# Teleport Updater requires systemd.
|
||||
PACKAGE_LIST+=" ${TELEPORT_UPDATER_PIN_VERSION}"
|
||||
fi
|
||||
echo ${PACKAGE_LIST}
|
||||
}
|
||||
|
||||
is_repo_available() {
|
||||
if [[ "${OSTYPE}" != "linux-gnu" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Populate $ID, $VERSION_ID and other env vars identifying the OS.
|
||||
# shellcheck disable=SC1091
|
||||
. /etc/os-release
|
||||
|
||||
# The following distros+version have a Teleport repository to install from.
|
||||
case "${ID}-${VERSION_ID}" in
|
||||
ubuntu-16.04* | ubuntu-18.04* | ubuntu-20.04* | ubuntu-22.04* | \
|
||||
debian-9* | debian-10* | debian-11* | \
|
||||
rhel-7* | rhel-8* | rhel-9* | \
|
||||
centos-7* | centos-8* | centos-9* | \
|
||||
amzn-2 | amzn-2023)
|
||||
return 0;;
|
||||
esac
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
if is_repo_available; then
|
||||
log "Installing repo for distro $ID."
|
||||
install_from_repo
|
||||
else
|
||||
log "Installing from binary file."
|
||||
install_from_file
|
||||
fi
|
||||
|
||||
# check that teleport binary can be found and runs
|
||||
if ! check_teleport_binary; then
|
||||
log_important "The Teleport binary could not be found at ${TELEPORT_BINARY_DIR} as expected."
|
||||
log_important "This usually means that there was an error during installation."
|
||||
log_important "Check this log for obvious signs of error and contact Teleport support"
|
||||
log_important "for further assistance."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# install teleport config
|
||||
# check the mode and write the appropriate config type
|
||||
if [[ "${APP_INSTALL_MODE}" == "true" ]]; then
|
||||
install_teleport_app_config
|
||||
elif [[ "${DB_INSTALL_MODE}" == "true" ]]; then
|
||||
install_teleport_database_config
|
||||
else
|
||||
install_teleport_node_config
|
||||
fi
|
||||
|
||||
|
||||
# Used to track whether a Teleport agent was installed using this method.
|
||||
export TELEPORT_INSTALL_METHOD_NODE_SCRIPT="true"
|
||||
|
||||
# install systemd unit if applicable (linux hosts)
|
||||
if is_using_systemd; then
|
||||
log "Host is using systemd"
|
||||
# we only need to manually install the systemd config if teleport was installed via tarball
|
||||
# all other packages will deploy it automatically
|
||||
if [[ ${TELEPORT_FORMAT} == "tarball" ]]; then
|
||||
install_systemd_unit
|
||||
fi
|
||||
start_teleport_systemd
|
||||
print_welcome_message
|
||||
# install launchd config on MacOS hosts
|
||||
elif is_macos_host; then
|
||||
log "Host is running MacOS"
|
||||
install_launchd_config
|
||||
start_teleport_launchd
|
||||
print_welcome_message
|
||||
# not a MacOS host and no systemd available, print a warning
|
||||
# and temporarily start Teleport in the foreground
|
||||
else
|
||||
log "Host does not appear to be using systemd"
|
||||
no_systemd_warning
|
||||
start_teleport_foreground
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
version: v3
|
||||
teleport:
|
||||
nodename: {{ ansible_hostname }}
|
||||
data_dir: /var/lib/teleport
|
||||
join_params:
|
||||
token_name: {{ get_join_token }}
|
||||
method: token
|
||||
proxy_server: {{ teleport_uri }}:443
|
||||
log:
|
||||
output: stderr
|
||||
severity: INFO
|
||||
format:
|
||||
output: text
|
||||
ca_pin: {{ get_ca_pin }}
|
||||
diag_addr: ""
|
||||
auth_service:
|
||||
enabled: "no"
|
||||
ssh_service:
|
||||
enabled: "yes"
|
||||
labels:
|
||||
ipaddr: {{ansible_default_ipv4.address}}
|
||||
group: {{ group_names[-1] }}
|
||||
os: {{ ansible_distribution }}
|
||||
{% if custom_labels %}
|
||||
{{ custom_labels }}
|
||||
{% endif %}
|
||||
commands:
|
||||
- name: hostname
|
||||
command: [hostname]
|
||||
period: 1m0s
|
||||
proxy_service:
|
||||
enabled: "no"
|
||||
https_keypairs: []
|
||||
https_keypairs_reload_interval: 0s
|
||||
acme: {}
|
||||
2
ansible/teleport_setting/roles/teleport/vars/main.yml
Normal file
2
ansible/teleport_setting/roles/teleport/vars/main.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
# vars file for teleport
|
||||
65
ansible/teleport_setting/teleport
Executable file
65
ansible/teleport_setting/teleport
Executable file
@@ -0,0 +1,65 @@
|
||||
[prod-demo-master]
|
||||
10.10.43.100 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[prod-demo-worker]
|
||||
10.10.43.101 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[dev-demo-master]
|
||||
10.10.43.105 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[dev-demo-worker]
|
||||
10.10.43.106 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[saas_mgmt_master]
|
||||
10.10.43.240 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[saas_mgmt_node]
|
||||
10.10.43.[241:243] ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[dsk_dev_master]
|
||||
10.10.43.[111:113] ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[dsk_dev_node]
|
||||
10.10.43.[114:153] ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[bastion]
|
||||
10.10.43.43 ansible_port=2222 ansible_user=havelight
|
||||
|
||||
[agent_host]
|
||||
10.10.43.177 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.178 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.179 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.180 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.181 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.182 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[agent_cri_master]
|
||||
10.10.43.185 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[agent_cri_worker]
|
||||
10.10.43.186 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.187 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.188 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[agent_middleware_master]
|
||||
10.10.43.189 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[agent_middleware_worker]
|
||||
10.10.43.190 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.191 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.192 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.193 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.194 ansible_port=2222 ansible_user=dev2
|
||||
10.10.43.199 ansible_port=2222 ansible_user=dev2
|
||||
|
||||
[all:children]
|
||||
saas_mgmt_master
|
||||
saas_mgmt_node
|
||||
dsk_dev_master
|
||||
dsk_dev_node
|
||||
bastion
|
||||
agent_host
|
||||
agent_cri_master
|
||||
agent_cri_worker
|
||||
agent_middleware_master
|
||||
agent_middleware_worker
|
||||
11
ansible/teleport_setting/teleport.yml
Normal file
11
ansible/teleport_setting/teleport.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- teleport
|
||||
vars:
|
||||
teleport_uri: teleport.kr.datasaker.io
|
||||
# remove: True
|
||||
# custom_labels: 'user=havelight,company=exem'
|
||||
# update: True
|
||||
install: True
|
||||
12
ansible/teleport_setting/teleport_aws.yml
Normal file
12
ansible/teleport_setting/teleport_aws.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
#- hosts: prod-demo-master,prod-demo-worker,dev-demo-master,dev-demo-worker
|
||||
- hosts: all
|
||||
become: true
|
||||
roles:
|
||||
- teleport
|
||||
vars:
|
||||
teleport_uri: teleport.kr.datasaker.io
|
||||
# remove: True
|
||||
# custom_labels: 'user=havelight,company=exem'
|
||||
# update: True
|
||||
install: True
|
||||
Reference in New Issue
Block a user