Teleport

Zero Trust Network Access (ZTNA)

🌐 Teleport 🔐 SSH 🛡️ Zero Trust 📋 Project C

📋 Introduction

Welcome to the Teleport Zero Trust Network Access lab. In this comprehensive exercise, you will deploy enterprise-grade secure access to SSH servers without VPNs, passwords, or managing SSH keys. By the end, you'll have certificate-based authentication, complete session recording, and SSO integration via Authentik.

⚠️
Prerequisite: Project A Required

This lab builds on a working Zero-Trust SSO Gateway (Project A) with Authentik. Teleport integrates with Authentik for SAML-based single sign-on.

🏢
Enterprise Skill Transfer

Teleport is used by enterprises including Goldman Sachs, Snowflake, DoorDash, and Elastic. Zero Trust access skills are in extremely high demand — ZTNA engineers command salaries of $130K-$200K annually. This lab teaches you the exact patterns used in production environments.

🎯 Lab Objectives

🔧 How Teleport Works

👤
You
Anywhere
🔑
Authentik
SSO
🌐
Teleport
Proxy
🖥️
Servers
SSH

🔐 What Teleport Can Protect

🖥️
SSH
Linux servers
💾
Database
PostgreSQL, MySQL
☸️
Kubernetes
K8s clusters
🌐
Web Apps
Internal apps
🪟
Windows
RDP access

This guide covers SSH Access (highlighted). Other protocols can be added later.

💡
The Problem Teleport Solves

Traditional SSH: Keys everywhere, never rotated. Keys get copied, shared, stolen. No audit trail. Need VPN to access internal servers.

With Teleport: Short-lived certificates. SSO authentication. Complete session recording. No VPN required!

⏱️ Time Investment

Phase Focus Time Machine
Phase 1 Core Concepts 15-20 min 📖 Reading
Phase 2 Prerequisites 10-15 min 🖥️ SERVER
Phase 3 Teleport Installation 30-45 min 🖥️ SERVER
Phase 4 Add SSH Nodes 20-30 min 🎯 TARGET Server
Phase 5 SSO Integration 30-45 min 🖥️ SERVER + 🌐 BROWSER
Phase 6 RBAC & Session Recording 30-45 min 🖥️ SERVER

Total: 3-4 hours (can be split across multiple sessions)


📑 Table of Contents

1

Phase 1: Core Concepts

Understanding Teleport terminology before we build.

⏱️ 15-20 minutes 📖 Reading / Understanding

Teleport has specific architecture and terminology. Understanding these concepts will make the hands-on sections much easier.

🧠 Teleport Architecture

🔐
Auth Service
Issues certificates, stores configuration, manages cluster state
🌐
Proxy Service
Entry point for users, handles TLS termination and routing
🖥️
Node (Agent)
Runs on servers you want to access via SSH
📜
Certificate
Short-lived identity proving who you are (replaces SSH keys)
🎭
Role
Defines what servers a user can access and what they can do
🏷️
Labels
Tags on servers (env=prod, team=backend) used for access control

🔑 Why Certificate-Based Authentication?

Traditional SSH Keys Teleport Certificates
❌ Never expire (unless manually rotated) ✅ Expire automatically (minutes to hours)
❌ Stored on disk, can be copied ✅ Generated on-demand, short-lived
❌ No central management ✅ Centrally issued and audited
❌ No visibility into who has access ✅ Complete audit trail
❌ authorized_keys nightmare ✅ Automatic certificate trust

3

Phase 3: Teleport Installation

Deploy Teleport using Docker.

⏱️ 30-45 minutes 🖥️ Performed on: SERVER Machine

Task 3.1: Create Directory Structure

🖥️ SERVER Machine — Via SSH Connection
1
Create Teleport Directories
Bash SERVER
# Navigate to your identity stack directory
cd ~/identity-stack

# Create directory structure for Teleport
mkdir -p teleport/config    # Configuration files
mkdir -p teleport/data      # Persistent data

# Verify structure
tree teleport/ 2>/dev/null || ls -la teleport/

Task 3.2: Generate Secure Join Token

🖥️ SERVER Machine — Via SSH Connection
2
Generate Token for Node Joining
Bash SERVER
# Generate a secure random token
openssl rand -hex 32

# Example output: a1b2c3d4e5f6g7h8...
# SAVE THIS TOKEN! You'll use it in the next step
🚨
Save This Token!

Copy this token somewhere safe. You'll need it for:

  • The Teleport configuration file (next step)
  • Any servers you want to add to the cluster

Task 3.3: Create Teleport Configuration

🖥️ SERVER Machine — Via SSH Connection
3
Create teleport.yaml Configuration
YAML — teleport.yaml SERVER
# Create the Teleport configuration file
cat > ~/identity-stack/teleport/config/teleport.yaml << 'EOF'
# ============================================
# TELEPORT SERVER CONFIGURATION
# ============================================
version: v3

teleport:
  nodename: teleport              # Name of this node
  data_dir: /var/lib/teleport     # Data directory
  log:
    output: stderr
    severity: INFO

# Auth Service - Certificate Authority
auth_service:
  enabled: true
  cluster_name: homelab           # Your cluster name
  listen_addr: 0.0.0.0:3025
  tokens:
    # Join token for nodes - REPLACE WITH YOUR TOKEN
    - proxy,node,app:YOUR_SECURE_TOKEN_HERE
  # Enable session recording
  session_recording: node-sync

# Proxy Service - User entry point
proxy_service:
  enabled: true
  web_listen_addr: 0.0.0.0:3080
  public_addr: teleport.yourdomain.com:443
  https_keypairs: []
  acme:
    enabled: false                # Traefik handles TLS

# SSH Service - This node is also an SSH target
ssh_service:
  enabled: true
  labels:
    env: homelab
    role: main
EOF

# Verify the file was created
cat ~/identity-stack/teleport/config/teleport.yaml
📝
Replace These Values!
  • YOUR_SECURE_TOKEN_HERE → The token from Step 2
  • teleport.yourdomain.com → Your actual domain

Task 3.4: Create Docker Compose Service

🖥️ SERVER Machine — Via SSH Connection
4
Create Teleport Docker Compose File
YAML — docker-compose.teleport.yml SERVER
# Create Docker Compose file for Teleport
cat > ~/identity-stack/docker-compose.teleport.yml << 'EOF'
# ============================================
# TELEPORT - Zero Trust Access Gateway
# ============================================

version: "3.8"

services:
  teleport:
    image: public.ecr.aws/gravitational/teleport:15
    container_name: teleport
    restart: unless-stopped
    hostname: teleport
    volumes:
      - ./teleport/config:/etc/teleport:ro   # Configuration
      - ./teleport/data:/var/lib/teleport    # Persistent data
    ports:
      - "3023:3023"    # SSH proxy
      - "3024:3024"    # SSH tunnel (reverse)
      - "3025:3025"    # Auth service
    command: start --config=/etc/teleport/teleport.yaml
    networks:
      - identity-network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.teleport.rule=Host(\`teleport.yourdomain.com\`)"
      - "traefik.http.routers.teleport.entrypoints=websecure"
      - "traefik.http.routers.teleport.tls.certresolver=letsencrypt"
      - "traefik.http.services.teleport.loadbalancer.server.port=3080"

networks:
  identity-network:
    external: true
EOF
5
Update Domain in Docker Compose
Bash SERVER
# Replace yourdomain.com with your actual domain
sed -i 's/yourdomain.com/YOUR_ACTUAL_DOMAIN.com/g' \
    ~/identity-stack/docker-compose.teleport.yml

# Also update the teleport.yaml
sed -i 's/yourdomain.com/YOUR_ACTUAL_DOMAIN.com/g' \
    ~/identity-stack/teleport/config/teleport.yaml

# Verify the changes
grep "yourdomain\|YOUR_ACTUAL" ~/identity-stack/docker-compose.teleport.yml
grep "yourdomain\|YOUR_ACTUAL" ~/identity-stack/teleport/config/teleport.yaml

Task 3.5: Start Teleport

🖥️ SERVER Machine — Via SSH Connection
6
Start the Teleport Container
Bash SERVER
cd ~/identity-stack

# Pull the Teleport image
docker compose -f docker-compose.teleport.yml pull

# Start Teleport
docker compose -f docker-compose.teleport.yml up -d

# Check container is running
docker compose -f docker-compose.teleport.yml ps

# View logs (look for "Teleport is ready")
docker logs teleport --tail=50
Verification

Check Teleport status:

Bash SERVER
docker exec teleport tctl status
Expected Output:
Cluster homelab Version 15.x.x CA pin sha256:xxxxxx...

Task 3.6: Create Admin User

🖥️ SERVER Machine — Via SSH Connection
7
Create First Admin User
Bash SERVER
# Create admin user with editor and access roles
docker exec teleport tctl users add admin \
    --roles=editor,access \
    --logins=root,ubuntu

# You'll get a signup URL like:
# https://teleport.yourdomain.com:443/web/invite/xxxxx
#
# Open this URL in your browser to:
#   1. Set your password
#   2. Configure MFA (hardware key or TOTP)
🎉
Phase 3 Complete!

Teleport is running! Open the signup URL in your browser to create your admin account with MFA. You can now access the Teleport Web UI at https://teleport.yourdomain.com


4

Phase 4: Add SSH Nodes

Connect servers to your Teleport cluster.

⏱️ 20-30 minutes 🎯 Performed on: TARGET Server (the server you want to access)

Now we'll install the Teleport agent on servers you want to access via SSH. These commands run on the target server, not the Teleport server.

Task 4.1: Install Teleport Agent

🎯 TARGET Server — The server you want to SSH into
1
Add Teleport Repository and Install
Bash — Ubuntu/Debian TARGET
# Add Teleport repository GPG key
sudo curl https://apt.releases.teleport.dev/gpg \
    -o /usr/share/keyrings/teleport-archive-keyring.asc

# Add Teleport repository
echo "deb [signed-by=/usr/share/keyrings/teleport-archive-keyring.asc] \
https://apt.releases.teleport.dev/ubuntu $(lsb_release -cs) stable/v15" | \
sudo tee /etc/apt/sources.list.d/teleport.list > /dev/null

# Update and install
sudo apt update
sudo apt install -y teleport

# Verify installation
teleport version

Task 4.2: Configure Agent

🎯 TARGET Server — The server you want to SSH into
2
Create Agent Configuration
Bash TARGET
# Create agent configuration
sudo cat > /etc/teleport.yaml << 'EOF'
# ============================================
# TELEPORT AGENT CONFIGURATION
# ============================================
version: v3

teleport:
  nodename: my-server              # Descriptive name for this server
  data_dir: /var/lib/teleport
  auth_token: YOUR_SECURE_TOKEN    # Same token from Phase 3
  auth_server: teleport.yourdomain.com:443

# Disable services we don't need on agents
auth_service:
  enabled: false

proxy_service:
  enabled: false

# Enable SSH service with labels
ssh_service:
  enabled: true
  labels:
    env: homelab                   # Environment tag
    type: server                   # Server type
    os: ubuntu                     # Operating system
EOF
📝
Replace These Values!
  • my-server → A descriptive name (e.g., web-server-1, db-server)
  • YOUR_SECURE_TOKEN → The same token from Phase 3
  • teleport.yourdomain.com → Your Teleport server domain
3
Start and Enable Teleport Service
Bash TARGET
# Enable Teleport to start on boot
sudo systemctl enable teleport

# Start Teleport
sudo systemctl start teleport

# Check status
sudo systemctl status teleport

# View logs if needed
sudo journalctl -u teleport -f
Verification

Back on your Teleport server, verify the node joined:

Bash SERVER
docker exec teleport tctl nodes ls
Expected Output:
Nodename UUID Address Labels ----------- ------------------------------------- -------------- ------------------ teleport xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 127.0.0.1:3022 env=homelab,role=main my-server yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy 10.0.0.5:3022 env=homelab,type=server
🎉
Node Connected!

Your server is now part of the Teleport cluster. Users with appropriate roles can SSH to it through Teleport.


🔧 Troubleshooting Guide

Common issues and their solutions when working with Teleport.

🔴 Node Won't Join Cluster
Cause: Token mismatch, network issue, or incorrect auth_server address.
Solutions:
  1. Verify token matches exactly in both configurations
  2. Check node can reach teleport.yourdomain.com:443
  3. Check node logs: journalctl -u teleport
  4. Verify DNS resolves correctly
🔴 SSO Login Fails
Cause: SAML configuration mismatch between Teleport and Authentik.
Solutions:
  1. Verify ACS URL matches exactly in both systems
  2. Check entity_descriptor_url is accessible
  3. Ensure user has groups mapped in Authentik
  4. Check Teleport logs for SAML errors
🔴 Permission Denied on SSH
Cause: Role doesn't allow access to this server or login user.
Solutions:
  1. Check user's assigned roles: tctl users ls
  2. Verify node_labels in role match server labels
  3. Ensure login user is in the role's allowed logins
  4. Check role with: tctl get roles/ROLENAME
🔴 Certificate Expired
Cause: Your Teleport certificate has expired (they're short-lived by design).
Solution: Simply log in again to get a new certificate:
tsh login --proxy=teleport.yourdomain.com

🧹 Cleanup Instructions

Remove Teleport when finished with the lab.

Option A: Stop Teleport (Preserve Data)

🖥️ SERVER Machine
Bash SERVER
cd ~/identity-stack

# Stop Teleport container (data preserved)
docker compose -f docker-compose.teleport.yml stop

# Verify it's stopped
docker compose -f docker-compose.teleport.yml ps

Option B: Complete Removal

⚠️
Warning: Permanent Data Loss

This will permanently delete all Teleport configuration, certificates, and session recordings.

🖥️ SERVER Machine
Bash SERVER
cd ~/identity-stack

# Stop and remove Teleport container
docker compose -f docker-compose.teleport.yml down

# Remove all Teleport data
rm -rf ~/identity-stack/teleport/data/*

# Optionally remove configuration too
# rm -rf ~/identity-stack/teleport/

Remove Agent from Target Servers

🎯 TARGET Server
Bash TARGET
# Stop and disable Teleport
sudo systemctl stop teleport
sudo systemctl disable teleport

# Remove Teleport package
sudo apt remove -y teleport

# Remove data and config
sudo rm -rf /var/lib/teleport
sudo rm -f /etc/teleport.yaml

🎓 Skills Acquired

🏆
Congratulations!

You've implemented enterprise-grade Zero Trust Network Access!

🚀 Next Steps