Securing Infrastructure Access at Scale in Large Enterprises
Dec 12
Virtual
Register Now
Teleport logoTry For Free
Fork me on GitHub

Teleport

Web Application Access

Prerequisites

  • A running Teleport cluster version 15.4.22 or above. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.

  • The tctl admin tool and tsh client tool.

    On Teleport Enterprise, you must use the Enterprise version of tctl, which you can download from your Teleport account workspace. Otherwise, visit Installation for instructions on downloading tctl and tsh for Teleport Community Edition.

  • To check that you can connect to your Teleport cluster, sign in with tsh login, then verify that you can run tctl commands using your current credentials. tctl is supported on macOS and Linux machines. For example:
    tsh login --proxy=teleport.example.com --user=email@example.com
    tctl status

    Cluster teleport.example.com

    Version 15.4.22

    CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.
  • Web application to connect to such as Grafana.
  • Host where you will run the Teleport Application Service.

Generate a token

A join token is required to authorize a Teleport Application Service to join the cluster. Generate a short-lived join token and save it for example in /tmp/token:

Log in to your cluster with tsh so you can use tctl from your local machine.

tsh login --user=myuser --proxy=teleport.example.com
tctl tokens add \ --type=app \ --app-name=grafana \ --app-uri=http://localhost:3000

TLS requirements

TLS is required to secure the Teleport Access Platform and any connected applications. When setting up Teleport, the minimum requirement is a certificate for the Teleport Proxy Service and a wildcard certificate for its sub-domain. This is where everyone will log into Teleport.

Application Access and DNS

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.

If you host the Teleport cluster on your own network, you should update your DNS configuration to account for application subdomains. You can update DNS in one of two ways:

  • Create a single DNS address (A) or canonical name (CNAME) record using wildcard substitution for the subdomain name. For example, create a DNS record with the name *.teleport.example.com.
  • Create a separate DNS address (A) or canonical name (CNAME) record for each application subdomain.

Modifying DNS ensures that the certificate authority—for example, Let's Encrypt—can issue a certificate for each subdomain and that clients can verify Teleport hosts regardless of the application they are accessing.

If you use the Teleport cloud platform, no DNS updates are needed because your Teleport cluster automatically provides the subdomains and signed TLS certificates for your applications under your tenant address.

In this example:

  • teleport.example.com hosts the Teleport Auth Service and the Teleport Proxy Service that are the that form the core cluster services of the Teleport Access Platform.
  • *.teleport.example.com hosts all of the applications, for example, grafana.teleport.example.com.

If you are running Teleport on the internet, we recommend using Let's Encrypt to receive your key and certificate automatically. For private networks or custom deployments, use your own private key and certificate.

Let's Encrypt verifies that you control the domain name of your Teleport cluster by communicating with the HTTPS server listening on port 443 of your Teleport Proxy Service.

You can configure the Teleport Proxy Service to complete the Let's Encrypt verification process when it starts up.

On the host where you will start the Teleport Auth Service and Proxy Service, run the following teleport configure command. Assign tele.example.com to the domain name of your Teleport cluster and user@example.com to an email address used for notifications (you can use any domain):

sudo teleport configure -o file \ --acme --acme-email=user@example.com \ --cluster-name=tele.example.com

Port 443 on your Teleport Proxy Service host must allow traffic from all sources.

On your Teleport host, place a valid private key and a certificate chain in /var/lib/teleport/privkey.pem and /var/lib/teleport/fullchain.pem respectively.

The leaf certificate must have a subject that corresponds to the domain of your Teleport host, e.g., *.teleport.example.com.

On the host where you will start the Teleport Auth Service and Proxy Service, run the following teleport configure command. Assign tele.example.com to the domain name of your Teleport cluster.

sudo teleport configure -o file \ --cluster-name=tele.example.com \ --public-addr=tele.example.com:443 \ --cert-file=/var/lib/teleport/fullchain.pem \ --key-file=/var/lib/teleport/privkey.pem

Create a user

A Teleport user needs their role's permission to access an application. Teleport comes with a built-in access role that grants access to all apps:

tctl users add --roles=access appuser

Start the Application Service with CLI flags

Install Teleport:

Install Teleport on your Linux server:

  1. Assign edition to one of the following, depending on your Teleport edition:

    EditionValue
    Teleport Enterprise Cloudcloud
    Teleport Enterprise (Self-Hosted)enterprise
    Teleport Community Editionoss
  2. Get the version of Teleport to install. If you have automatic agent updates enabled in your cluster, query the latest Teleport version that is compatible with the updater:

    TELEPORT_DOMAIN=example.teleport.com
    TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"

    Otherwise, get the version of your Teleport cluster:

    TELEPORT_DOMAIN=example.teleport.com
    TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/ping | jq -r '.server_version')"
  3. Install Teleport on your Linux server:

    curl https://cdn.teleport.dev/install-v15.4.22.sh | bash -s ${TELEPORT_VERSION} edition

    The installation script detects the package manager on your Linux server and uses it to install Teleport binaries. To customize your installation, learn about the Teleport package repositories in the installation guide.

You can start the Teleport Application Service with a single CLI command:

sudo teleport start \ --roles=app \ --token=/tmp/token \ --auth-server=teleport.example.com:3080 \ --app-name="grafana" \ --app-uri="http://localhost:3000" \ --labels=env=dev

Note that the --auth-server flag must point to the Teleport cluster's proxy endpoint because the Application Service always connects back to the cluster over a reverse tunnel.

Application name

An application name should make a valid sub-domain (<=63 characters, no spaces, only a-z 0-9 - allowed).

After Teleport is running, users can access the app at app-name.proxy_public_addr.com e.g. grafana.teleport.example.com. You can also override public_addr e.g grafana.acme.com if you configure the appropriate DNS entry to point to the Teleport proxy server.

Start the Teleport Application Service with a config file

Example teleport.yaml configuration:

version: v3
teleport:
  # Data directory for the Application Proxy service. If running on the same
  # node as Auth/Proxy service, make sure to use different data directories.
  data_dir: /var/lib/teleport-app
  # Instructs the service to load the auth token from the specified file
  # during initial registration with the cluster.
  auth_token: /tmp/token
  # Proxy address to connect to. Note that it has to be the proxy address
  # because the app service always connects to the cluster over a reverse
  # tunnel.
  proxy_server: teleport.example.com:3080
app_service:
    enabled: yes
    # Teleport provides a small debug app called "dumper" that can be used
    # to make sure application access is working correctly. It outputs JWTs,
    #  so it can be useful when extending your application.
    debug_app: true
    # This section contains definitions of all applications proxied by this
    # service. It can contain multiple items.
    apps:
      # Name of the application. Used for identification purposes.
    - name: "grafana"
      # URI and port the application is available at.
      uri: "http://localhost:3000"
      # Optional application public address to override.
      public_addr: "grafana.teleport.example.com"
      # Optional static labels to assign to the app. Used in RBAC.
      labels:
        env: "prod"
      # Optional dynamic labels to assign to the app. Used in RBAC.
      commands:
      - name: "os"
        command: ["/usr/bin/uname"]
        period: "5s"
auth_service:
  enabled: "no"
ssh_service:
  enabled: "no"
proxy_service:
  enabled: "no"

Start the Application Service:

sudo teleport start --config=/path/to/teleport.yaml

Advanced options

Running the dumper application

For testing and debugging purposes, we provide a built-in debug app called "dumper". It can be turned on using debug_app: true.

app_service:
   enabled: yes
   debug_app: true

The dumper app will dump all the request headers in the response.

Customize public address

For self-hosted environments only

The public address of apps cannot be changed or overridden on cloud-hosted Teleport tenants, due to TLS certificate limitations.

For cloud-hosted customers, apps will always be available at https://<app-name>.example.teleport.sh, where example is the name chosen for your cloud-hosted Teleport tenant.

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: true

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"

In a dynamic app resource, configure header rewrites with the spec.rewrite.headers field. The value is a list of mappings that specify the name and value of each header you would like to rewrite.

kind: app
version: v3
metadata:
  name: "dashboard"
spec:
  uri: https://localhost:4321
  public_addr: dashboard.example.com
  rewrite:
    headers:
      # Inject a static header.
      - name: X-Custom-Header
        value: example
      # Inject headers with internal/external user traits.
      - name: X-Internal-Trait
        value: "{{internal.logins}}"
      - name: X-External-Trait
        value: "{{external.env}}"
      # Inject header with Teleport-signed JWT token.
      - name: Authorization
        value: "Bearer {{internal.jwt}}"
      # Override Host header.
      - name: Host
        value: 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. See Integrating with JWTs for more details.

For full details on configuring Teleport roles, including how Teleport populates the external and internal traits, see the Teleport Access Controls Reference.

Configuring the JWT token

By default, Teleport includes a user's roles and traits in the JWT generated for application access. If your application doesn't care about these values, or you are encountering an error due to exceeding the size limit of HTTP headers, you can configure Teleport to omit this information from the token.

- name: "dashboard"
  uri: https://localhost:4321
  public_addr: dashboard.example.com
  rewrite:
    # Specify whether to include roles or traits in the JWT.
    # Options:
    # - roles-and-traits: include both roles and traits
    # - roles: include only roles
    # - traits: include only traits
    # - none: exclude both roles and traits from the JWT token
    # Default: roles-and-traits
    jwt_claims: roles-and-traits
    headers:
    # Inject header with Teleport-signed JWT token.
    - "Authorization: Bearer {{internal.jwt}}"

View applications in Teleport

Teleport provides a UI for quickly launching connected applications.

They can be viewed by navigating to a cluster's web UI and selecting the "Applications" tab. The URL structure looks like this:

https://[cluster-url:cluster-port]/web/cluster/[cluster-name]/apps

Logging out of applications

When you log into an application, you'll get a certificate and login session per your defined RBAC. If you want to force log out before this period you can do so by hitting the /teleport-logout endpoint:

  • https://internal-app.teleport.example.com/teleport-logout