knowledge/technology/applications/web/Teleport.md
2024-08-07 15:56:39 +02:00

13 KiB

obj website repo rev
application https://goteleport.com https://github.com/gravitational/teleport 2024-08-07

Teleport

Teleport provides connectivity, authentication, access controls and audit for infrastructure.

It includes an identity-aware access proxy, a CA that issues short-lived certificates, a unified access control system and a tunneling system to access resources behind the firewall.

Teleport understands the SSH, HTTPS, RDP, Kubernetes API, MySQL, MongoDB and PostgreSQL wire protocols, plus many others. It can integrate with Single Sign-On providers and enables you to apply access policies using infrastructure-as-code and GitOps tools.

Setup

You need a domain pointing at your teleport proxy instance.

Docker-Compose:

version: '3'
services:
  teleport:
    image: public.ecr.aws/gravitational/teleport:14
    restart: unless-stopped
    hostname: <yourdomain.com>
    ports:
      - "3080:3080"  # Web UI
      - "3022:3022"  # SSH
      - "8443:8443"  # HTTPS
    volumes:
      - ./config/teleport.yaml:/etc/teleport/teleport.yaml
      - ./data:/var/lib/teleport

teleport.yml:

version: v3
teleport:
  nodename: <yourdomain.com>
  data_dir: /var/lib/teleport
  log:
    output: stderr
    severity: INFO
    format:
      output: text
  ca_pin: ""
  diag_addr: ""
auth_service:
  enabled: "yes"
  listen_addr: 0.0.0.0:3025
  proxy_listener_mode: multiplex
  authentication:
    type: local
    second_factor: true
    webauthn:
        rp_id: <yourdomain.com>
    connector_name: passwordless
ssh_service:
  enabled: "no"
proxy_service:
  enabled: "yes"
  public_addr: <yourdomain.com>:443
  https_keypairs: []
  https_keypairs_reload_interval: 0s
  acme: {}

Application Setup

Teleport assigns a subdomain to each application you configure for Application Access. For example, if you enroll Grafana as a resource, Teleport assigns the resource to the grafana.teleport.example.com subdomain.

  1. Generate a token
tctl tokens add \
  --type=app \
  --app-name=grafana \
  --app-uri=http://localhost:3000
  1. Install and configure teleport
sudo teleport configure \
--output=file \
--proxy=teleport.example.com:443 \
--token=/tmp/token \
--roles=app \
--app-name=grafana \
--app-uri=http://localhost:3000

Advanced

Customize public address

By default applications are available at <app-name>.<proxy-host>:<proxy-port> address. To override the public address, specify the public_addr field:

- name: "jira"
  uri: "https://localhost:8001"
  public_addr: "jira.example.com"

Skip TLS certificate verification

Danger Zone
This is insecure and not recommended for use in production.

Teleport checks if the certificates presented by the applications are signed by a trusted Certificate Authority. When using self-signed certificates for internal applications, use insecure_skip_verify: true to skip this verification step:

- name: "app"
  uri: "https://localhost:8443"
  public_addr: "app.example.com"
  insecure_skip_verify: tru

Some applications are available in a subdirectory. Examples include the Kubernetes Dashboard.. The URI should be updated to include the subdirectory:

- name: "k8s"
  uri: "http://10.0.1.60:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#/overview"
  public_addr: "k8s.example.com"

Rewrite redirect

To support web apps that perform internal redirects, application access provides an option to rewrite the hostname of the Location header on redirect responses to the application's public address:

- name: "jenkins"
  uri: "https://localhost:8001"
  public_addr: "jenkins.example.com"
  rewrite:
    # Rewrite the "Location" header on redirect responses replacing the
    # host with the public address of this application.
    redirect:
    - "localhost"
    - "jenkins.internal.dev"

Headers passthrough

You can configure application access to inject additional headers in the requests forwarded to a web application.

For apps defined in the teleport.yaml configuration, the headers field of each app is a list of strings. Be careful to quote the entire value to ensure it is parsed correctly.

- name: "dashboard"
  uri: https://localhost:4321
  public_addr: dashboard.example.com
  rewrite:
    headers:
    # Inject a static header.
    - "X-Custom-Header: example"
    # Inject headers with internal/external user traits.
    - "X-Internal-Trait: {{internal.logins}}"
    - "X-External-Trait: {{external.env}}"
    # Inject header with Teleport-signed JWT token.
    - "Authorization: Bearer {{internal.jwt}}"
    # Override Host header.
    - "Host: dashboard.example.com"

Headers injected this way override any headers with the same names that may be sent by an application. The following headers are reserved and can't be rewritten:

  • Teleport-Jwt-Assertion
  • Cf-Access-Token
  • Any header matching the pattern X-Teleport-*
  • Any header matching the pattern X-Forwarded-*

Rewritten header values support the same templating variables as role templates. In the example above, X-Internal-Trait header will be populated with the value of internal user trait logins and X-External-Trait header will get the value of the user's external env trait coming from the identity provider.

Additionally, the {{internal.jwt}} template variable will be replaced with a JWT token signed by Teleport that contains user identity information.

JSON Web Token Integration

Teleport sends a JWT token signed with Teleport's authority with each request to a target application in a Teleport-Jwt-Assertion header.

You can use the JWT token to get information about the authenticated Teleport user, its roles, and its traits. This allows you to:

  • Map Teleport identity/roles/traits onto the identity/roles/traits of your web application.
  • Trust Teleport identity to automatically sign in users into your application.

Example JWT:

{
  "aud": [
    "http://127.0.0.1:34679"
  ],
  "iss": "aws",
  "nbf": 1603835795,
  "sub": "alice",
  // Teleport user name.
  "username": "alice"
  // Teleport user roles.
  "roles": [
    "admin"
  ],
  // Teleport user traits.
  "traits": {
    "logins": [
      "root",
      "ubuntu",
      "ec2-user"
    ]
  },
  // Teleport identity expiration.
  "exp": 1603943800,
}
Validate JWT

Teleport provides a JSON Web Key Set (jwks) endpoint to verify that the JWT can be trusted. This endpoint is https://[cluster-name]:3080/.well-known/jwks.json:

Example jwks.json:

{
  "keys": [
    {
      "kty": "RSA",
      "n": "xk-0VSVZY76QGqeN9TD-FJp32s8jZrpsalnRoFwlZ_JwPbbd5-_bPKcz8o2tv1eJS0Ll6ePxRCyK68Jz2UC4V4RiYaqJCRq_qVpDQMB1sQ7p9M-8qvT82FJ-Rv-W4RNe3xRmBSFDYdXaFm51Uk8OIYfv-oZ0kGptKpkNY390aJOzjHPH2MqSvhk9Xn8GwM8kEbpSllavdJCRPCeNVGJXiSCsWrOA_wsv_jqBP6g3UOA9GnI8R6HR14OxV3C184vb3NxIqxtrW0C4W6UtSbMDcKcNCgajq2l56pHO8In5GoPCrHqlo379LE5QqpXeeHj8uqcjeGdxXTuPrRq1AuBpvQ",
      "e": "AQAB",
      "alg": "RS256"
    }
  ]
}

SSH Agent Setup

  1. Install teleport on your host:
    curl https://goteleport.com/static/install.sh | bash -s 14.2.0
    
  2. On your teleport proxy, create a join token:
    tctl tokens add --type=node --format=text > token.file
    
  3. Join the server to the cluster:
    sudo teleport node configure \
    --output=file:///etc/teleport.yaml \
    --token=/path/to/token.file \
    --proxy=tele.example.com:443
    
  4. Enable Teleport Service
[Unit]
Description=Teleport Service
After=network.target

[Service]
Type=simple
Restart=on-failure
EnvironmentFile=-/etc/default/teleport
ExecStart=/usr/local/bin/teleport start --config /etc/teleport.yaml --pid-file=/run/teleport.pid
ExecReload=/bin/kill -HUP $MAINPID
PIDFile=/run/teleport.pid
LimitNOFILE=524288

[Install]
WantedBy=multi-user.target

Machine ID Setup

Teleport Machine ID enables machines, such as CI/CD workflows, to securely authenticate with your Teleport cluster in order to connect to resources and configure the cluster itself. This is sometimes referred to as machine-to-machine access.

  1. Create a bot user:
tctl bots add robot --roles=access --logins=root
  1. Start Machine ID (or run as Service):
    sudo tbot start \
    --data-dir=/var/lib/teleport/bot \
    --destination-dir=/opt/machine-id \
    --token=abcd123-insecure-do-not-use-this \
    --join-method=token \
    --auth-server=example.teleport.sh:443
    
  2. Use:
ssh -F /opt/machine-id/ssh_config root@node-name.example.com

tctl

Admin tool for the Teleport Access Platform
Usage: tctl [<flags>] <command> [<args> ...]

Commands

users add

Generate a user invitation token.
Usage: tctl users add --roles=ROLES [<flags>] <account>

Options
Option Description
--logins List of allowed SSH logins for the new user

users update

Update user account.
Usage: tctl users update [<flags>] <account>

Options
Option Description
--set-roles List of roles for the user to assume, replaces current roles
--set-logins List of allowed SSH logins for the user, replaces current logins

users ls

Lists all user accounts.
Usage: tctl users ls

users rm

Deletes user accounts.
Usage: tctl users rm <logins>

users reset

Reset user password and generate a new token.
Usage: tctl users reset <account>

get

Print a YAML declaration of various Teleport resources.
Usage: tctl get [<flags>] <resources>

Options
Option Description
--format Output format: yaml, json or text

edit

Edit a Teleport resource.
Usage: tctl edit [<resource type/resource name>]

nodes add

Generate a node invitation token.
Usage: tctl nodes add [<flags>]

Options
Option Description
--roles Comma-separated list of roles for the new node to assume
--ttl Time to live for a generated token

nodes ls

List all active SSH nodes within the cluster.
Usage: tctl nodes ls [<flags>] [<labels>]

tokens add

Create a invitation token.
Usage: tctl tokens add --type=TYPE [<flags>]

Options
Option Description
--type Type(s) of token to add, e.g. --type=node,app,db,proxy,etc
--labels Set token labels, e.g. env=prod,region=us-west
--ttl Set expiration time for token, default is 30 minutes
--format Output format, 'text', 'json', or 'yaml'

tokens rm

Delete/revoke an invitation token.
Usage: tctl tokens rm [<token>]

tokens ls

List node and user invitation tokens.
Usage: tctl tokens ls

bots ls

List all certificate renewal bots registered with the cluster.
Usage: tctl bots ls

bots add

Add a new certificate renewal bot to the cluster.
Usage: tctl bots add --roles ROLES [--logins LOGINS] BOT_NAME

bots rm

Permanently remove a certificate renewal bot from the cluster.
Usage: tctl bots rm BOT_NAME

status

Report cluster status.
Usage: tctl status

tsh

Teleport Command Line client for interacting with your infrastructure.
Usage: tsh [options...] <command> [<args> ...]

Options

Option Description
--proxy Teleport proxy address
--user Teleport user, defaults to current local user

Commands

ssh

Run shell or execute a command on a remote SSH node.
Usage: tsh ssh [<flags>] <[user@]host> [<command>...]

scp

Transfer files to a remote SSH node.
Usage: tsh scp [<flags>] <from, to>...

ls

List remote SSH nodes.
Usage: tsh ls [<flags>] [<labels>]

login

Log in to a cluster and retrieve the session certificate.
Usage: tsh login [<flags>] [<cluster>]

Info: If no passwordless authentification methods are available you can login with --auth=local

logout

Delete a cluster certificate.
Usage: tsh logout

status

Display the list of proxy servers and retrieved certificates.
Usage: tsh status

config

Print SSH config details.
This allows you to use regular ssh command to connect to teleport servers.

tsh config >> ~/.ssh/config