Teleport Workshop

Based on these sites:

What is Teleport?: https://github.com/gravitational/teleport

Dictionary

Since this workshop runs using docker we have:

The host, the system in which docker runs (i.e. the system to which the port mappings from docker will be sent).

The Teleport Server, one of the running containers.

The Teleport Nodes, the other running containers.

The images

This workshop is based on the following container images

quay.io/gravitational/teleport:7

nginx:latest

One net, one love

The idea of this phase is to create this infra:

Using Docker create a subnet and in it create two servers, the Teleport server and an Nginx server.
In the second one run Teleport to connect to the first one.

All of this is in the same LAN (docker subnet), so, the client Teleport will connect straight to the auth server.

The composition

For this part, docker-compose will be used. This is the docker-compose.yaml file:

    version: '2'
    services:
      # This container depends on the config written by the configure container above, so it
      # sleeps for a second on startup to allow the configure container to run first.
      teleport:
        image: quay.io/gravitational/teleport:7
        container_name: teleport
        entrypoint: /bin/sh
        hostname: teleporthost
        command: -c "sleep 2 && /usr/bin/dumb-init teleport start -d -c /etc/teleport/teleport.yaml"
        ports:
          - "3023:3023"
          - "3024:3024"
          - "3025:3025"
          - "3080:3080"
        volumes:
          - ./teleport/config:/etc/teleport
          - ./teleport/data:/var/lib/teleport
        networks:
          teleport:
            aliases:
              - proxy.teleporthost
        depends_on:
          - bootstrap
    
      # The bootstrap container generates certificates and then immediately exits.
      bootstrap:
        image: quay.io/gravitational/teleport:7
        container_name: teleport-bootstrap
        entrypoint: /bin/sh
        hostname: teleporthost
        command: -c "if [ ! -f /etc/teleport/teleport.yaml ]; then teleport configure > /etc/teleport/teleport.yaml; fi"
        volumes:
          - ./teleport/config:/etc/teleport
    
      resource001:
        image: nginx:latest
        container_name: resource001
        hostname: resource001.teleport
        ports:
          - "8080:80"
        volumes:
          - ./resource001/opt:/opt
          - ./resource001/config:/etc/teleport
        networks:
          teleport:
            aliases:
              - resource001.teleport
    
    
    networks:
      teleport:

Now, to start it just run:

    docker-compose up -d

The first time it is launched it will create the teleport.yaml file. Since volumes are being used, the file will be located in the host machine at “./teleport/config”.

Similar for data files, they will be located in the host at “./teleport/data”.

Ensure the teleport.yaml file is like this:

    #
    # A Sample Teleport configuration file.
    # Creates a single proxy, auth and node server.
    #
    # Things to update:
    #  1. license.pem: You only need a license from https://dashboard.goteleport.com
    #     if you are an Enterprise customer.
    #
    teleport:
      nodename: teleporthost
      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
    ssh_service:
      enabled: "yes"
      labels:
        env: example
      commands:
      - name: hostname
        command: [hostname]
        period: 1m0s
    proxy_service:
      enabled: "yes"
      listen_addr: 0.0.0.0:3023
      https_keypairs: []
      acme: {}

First time activities

When running for the first time, a user needs to be created, so we can access Teleport.

To do this run the following command:

    docker exec teleport tctl users add username --roles=editor,access --logins=root,ubuntu,ec2-user

Change “username” to the username you want. (and remember it)

This will throw a message like this:

       User "username" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h:
       https://teleporthost:3080/web/invite/01ebe60134fe0c825f430e8622ba4b56
    
       NOTE: Make sure teleporthost:3080 points at a Teleport proxy which users can access.

Note, since we named the hostname as “teleporthost”, we need to point this hostname to localhost (or just use localhost instead for now).

Note since this is a secure connection with a self-signed cert, you will have to instruct your browser to skip the “Warning: Potential Security Risk Ahead” message!

Go to the address and create a password for the new user (something good, e.g. P4ssM0Rd_s3cuR3), also an MFA has to be set.

Now, the Teleport dashboard can be accessed. Under “servers” only the Teleport server is shown.

The very first added node

A new node (aka the other server, the one we want to access), will be added.

In the docker-compose file there is already a Debian-based Nginx server (name “resource001”) exposed in the host machine’s IP port 8080.

This URL should be showing the Nginx welcome page: http://loccalhost:8080.

First, Teleport should be installed on the new server. Access the server, download Teleport, and install it.

Access the node:

    docker exec -ti resource001 /bin/bash

And run this from inside the node:

    cd /opt
    curl --output teleport_7.1.0_amd64.deb https://get.gravitational.com/teleport_7.1.0_amd64.deb
    dpkg -i teleport_7.1.0_amd64.deb

Note this, if Teleport version was changed in the docker-compose, it hast to be changed here as well.

Now, from the host machine (i.e. from a terminal other than the previous one) this command has to be run in order to get the token from the Teleport Server to add the new node:

    docker exec teleport tctl nodes add

the output should be something like this

     The invite token: f1e21ffc3f6bff662ef60811b147a615
     This token will expire in 30 minutes

     Run this on the new node to join the cluster:

     > teleport start \
       --roles=node \
       --token=f1e21ffc3f6bff662ef60811b147a615 \
       --ca-pin=sha256:e63125bfd0745783713b9f66c2e3b6990baa225e979b4f777a84bc868298f6c6 \
       --auth-server=172.31.0.2:3025

     Please note:

     - This invitation token will expire in 30 minutes
     - 172.31.0.2:3025 must be reachable from the new node

As noted in the post: We could now just execute this command on the node, once teleport is downloaded. But I prefer to add this to a static configuration file, that allows me to run the teleport as a systemd service [when available].

A config file is needed, so inside the container create a file called “/etc/teleport/teleport.yaml” with this content

       teleport:
           nodename: resource001
           data_dir: /var/lib/teleport
           auth_token: <your-auth-token>
           auth_servers:
               - teleporthost:3025
           log:
               output: stderr
               severity: INFO
           ca_pin: <your-ca-pin-hash>
       auth_service:
           enabled: no
       ssh_service:
           enabled: yes
       proxy_service:
           enabled: no

Replace with your “ca-pin” and “auth_token” values with the ones you got from the add node command.

Finally launch Teleport in the node:

    teleport start -c /etc/teleport/teleport.yaml

If no error was thrown, then the node should be visible and accessible from the Teleport Dashboard, go and check it!

In the right side you will see a “connect” button, try it and access your node command line.

Try accessing your node from another system command line.

First, log into teleport:

     tsh login --proxy=teleporthost:3080 --auth=local --user=username --insecure teleporthost

You will be prompted to enter the password and the OTP. (the MFA number you got previously)

Insecure is being used since we are in a home-network!

Access the node with an SSH connection:

    tsh --insecure ssh root@resource001

…and voilà you are in!

Joining foreign participants

Now, for a real-world example, servers in other networks have to be added.

This is the phase 2 schema:

Here, a new Nginx server is added to a different network.

For this case we won’t have access to the auth server directly, instead, the exposed proxy has to be used.

Then, the Teleport in the new server will be contacting the proxy at a public address (in port 3080). For sake of this demo, the host machine’s IP will be used as a public IP (all containers can reach that address).

First, start the container:

   docker run -e "PUBLICIP=192.168.0.3" --name resource002 --hostname resource002.outside -d -v $(pwd)/resource002/opt:/opt -v $(pwd)/resource002/config:/etc/teleport -p 7777:80 nginx:latest

Replace the PUBLICIP value with your actual host IP. This will become handy later.

Now access the container:

   docker exec -it  resource002 /bin/bash

…and download and install Teleport:

   cd /opt
   curl --output teleport_7.1.0_amd64.deb https://get.gravitational.com/teleport_7.1.0_amd64.deb
   dpkg -i teleport_7.1.0_amd64.deb

Still in the container, we need to add the host ip in the “/etc/hosts” file (this will be our poor-man-DNS).

   echo $PUBLICIP teleporthost >> /etc/hosts

Now, back in the host machine run the add node command to get a new token:

   docker exec teleport tctl nodes add

…and back in the container create a file called /etc/teleport/teleport.yaml with this content

    teleport:
        nodename: resource002
        data_dir: /var/lib/teleport
        auth_token: <your-auth-token>
        auth_servers:
            - teleporthost:3080
        log:
            output: stderr
            severity: INFO
        ca_pin: <your-ca-pin-hash>
    auth_service:
        enabled: no
    ssh_service:
        enabled: yes
    proxy_service:
        enabled: no

Replace with your “ca-pin” and “auth_token” values with the ones you got.
Note the auth_server here is the external address, and the port is 3080, which is the one served by the proxy. The used address is the one added to the “/etc/hosts” file, pointing to the host machine IP.

Finally, start Teleport:

    teleport start -c /etc/teleport/teleport.yaml --insecure

Note the usage of the flag –insecure, it is because of this test being run on an internal lan with self signed certificates.

Go to the dashboard to check your new neighbor!

Try to access it in the same way you’ve accessed the first node.

Let the ship pilot become Kubernetes in Greece

For this phase (adding K8s clusters), this doc can be followed.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.

Up ↑