Fork me on GitHub
Teleport

Use Teleport for Application Access

Improve

Connecting Web Applications

Download the latest version of Teleport for your platform from our downloads page and follow the installation instructions.

Start Auth/Proxy service

Create a configuration file for a Teleport service that will be running auth and proxy servers:

teleport:
  data_dir: /var/lib/teleport
auth_service:
  enabled: "yes"
proxy_service:
  enabled: "yes"
  # Set public address proxy will be reachable at.
  public_addr: teleport.example.com:3080
ssh_service:
  enabled: "no"

When running Teleport in production, we recommend that you follow the practices below to avoid security incidents. These practices may differ from the examples used in this guide, which are intended for demo environments:

  • Avoid using sudo in production environments unless it's necessary.
  • Create new, non-root, users and use test instances for experimenting with Teleport.
  • Run Teleport's services as a non-root user unless required. Only the SSH Service requires root access. Note that you will need root permissions (or the CAP_NET_BIND_SERVICE capability) to make Teleport listen on a port numbered < 1024 (e.g. 443).
  • Follow the "Principle of Least Privilege" (PoLP). Don't give users permissive roles when giving them more restrictive roles will do instead. For example, assign users the built-in access,editor roles.
  • When joining a Teleport agent to a cluster, save the invitation token to a file. Otherwise, the token will be visible when examining the teleport command that started the agent, e.g., via the history command on a compromised system.

Start the service:

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

Generate a token

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

tctl tokens add \ --type=app \ --app-name=grafana \ --app-uri=http://localhost:3000

TLS requirements

TLS is required to secure Teleport's Access Plane and any connected applications. When setting up Teleport, the minimum requirement is a certificate for the proxy 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 have configured for Application Access (e.g., grafana.teleport.example.com), so you will need to ensure that a DNS A record exists for each application-specific subdomain so clients can access your applications via Teleport.

You should create either a separate DNS A record for each subdomain or a single record with a wildcard subdomain such as *.teleport.example.com. This way, your certificate authority (e.g., Let's Encrypt) can issue a certificate for each subdomain, enabling clients to verify your Teleport hosts regardless of the application they are accessing.

In our example:

  • teleport.example.com will host the Access Plane.
  • *.teleport.example.com will host all of the applications e.g. grafana.teleport.example.com.

You can either configure Teleport to obtain a TLS certificate via Let's Encrypt or use an existing certificate and private key (e.g. using certbot).

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, where tele.example.com is the domain name of your Teleport cluster and [email protected] is an email address used for notifications (you can use any domain):

DOMAIN=tele.example.com
teleport configure --acme --acme-email=${EMAIL?} --cluster-name=${DOMAIN?} | \ sudo tee /etc/teleport.yaml > /dev/null

The --acme, --acme-email, and --cluster-name flags will add the following settings to your Teleport configuration file:

proxy_service:
  enabled: "yes"
  web_listen_addr: :443
  public_addr: tele.example.com:443
  acme:
    enabled: "yes"
    email: [email protected]

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

If you have obtained certificate/key pairs for your domain they can be provided directly to the proxy service:

proxy_service:
  enabled: "yes"
  web_listen_addr: "0.0.0.0:443"
  public_addr: "teleport.example.com:443"
  https_keypairs:
  - key_file: "/etc/letsencrypt/live/teleport.example.com/privkey.pem"
    cert_file: "/etc/letsencrypt/live/teleport.example.com/fullchain.pem"
  - key_file: "/etc/letsencrypt/live/*.teleport.example.com/privkey.pem"
    cert_file: "/etc/letsencrypt/live/*.teleport.example.com/fullchain.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 --config=/path/to/teleport.yaml users add --roles=access appuser

Start application service with CLI flags

Install Teleport:

Download Teleport's PGP public key

sudo curl https://deb.releases.teleport.dev/teleport-pubkey.asc \ -o /usr/share/keyrings/teleport-archive-keyring.asc

Add the Teleport APT repository

echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] https://deb.releases.teleport.dev/ stable main" \| sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null
sudo apt-get update
sudo apt-get install teleport
sudo yum-config-manager --add-repo https://rpm.releases.teleport.dev/teleport.repo
sudo yum install teleport

Optional: Using DNF on newer distributions

$ sudo dnf config-manager --add-repo https://rpm.releases.teleport.dev/teleport.repo

$ sudo dnf install teleport

curl https://get.gravitational.com/teleport-v9.3.7-linux-amd64-bin.tar.gz.sha256

<checksum> <filename>

curl -O https://get.gravitational.com/teleport-v9.3.7-linux-amd64-bin.tar.gz
shasum -a 256 teleport-v9.3.7-linux-amd64-bin.tar.gz

Verify that the checksums match

tar -xzf teleport-v9.3.7-linux-amd64-bin.tar.gz
cd teleport
sudo ./install
curl https://get.gravitational.com/teleport-v9.3.7-linux-arm-bin.tar.gz.sha256

<checksum> <filename>

curl -O https://get.gravitational.com/teleport-v9.3.7-linux-arm-bin.tar.gz
shasum -a 256 teleport-v9.3.7-linux-arm-bin.tar.gz

Verify that the checksums match

tar -xzf teleport-v9.3.7-linux-arm-bin.tar.gz
cd teleport
sudo ./install
curl https://get.gravitational.com/teleport-v9.3.7-linux-arm64-bin.tar.gz.sha256

<checksum> <filename>

curl -O https://get.gravitational.com/teleport-v9.3.7-linux-arm64-bin.tar.gz
shasum -a 256 teleport-v9.3.7-linux-arm64-bin.tar.gz

Verify that the checksums match

tar -xzf teleport-v9.3.7-linux-arm64-bin.tar.gz
cd teleport
sudo ./install

A Teleport Application Proxy agent can be started 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 application service with a config file

Example teleport.yaml configuration:

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 join 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.
  auth_servers:
  - teleport.example.com:3080
app_service:
    enabled: yes
    # Teleport provides a small debug app that can be used to make sure application
    # access is working correctly. It'll output 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 debug application

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

app_service:
   enabled: yes
   debug_app: true

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

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: 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?namespace=default"
  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.

- 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: X-Teleport-Jwt, Cf-Access-Token, 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.

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