Teleport

Zero Trust Network Access (ZTNA)

Teleport SSH Zero Trust Project C
0

What Are We Building?

Understanding Teleport and Zero Trust Access

🔗 Builds on: Project A (Authentik SSO)
🌐
Secure Access Without VPN

SSH, databases, and apps through one secure gateway. Certificate-based, no passwords!

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)

🎯

What You'll Have When Done

  • SSH access without managing SSH keys
  • Short-lived certificates (no permanent passwords)
  • SSO login via Authentik
  • Complete session recording
  • Role-based access control
  • Full audit trail
  • No VPN required!

⚡ The Problem Teleport Solves

Traditional SSH:

  • SSH keys everywhere, never rotated
  • Keys get copied, shared, stolen
  • No audit trail of who accessed what
  • Need VPN to access internal servers

With Teleport: Login once with SSO, get a short-lived certificate, access any server, every session is recorded!

⏱️

Time Investment

Phase Time Difficulty
Understanding Concepts 15-20 min Reading
Teleport Installation 30-45 min Easy
Adding SSH Nodes 20-30 min Easy
Authentik SSO Setup 30-45 min Medium
Roles & Recording 20-30 min Medium

Total: 3-4 hours

1

Core Concepts

Understanding Teleport architecture

🧠
How Teleport Works

Three services work together to provide secure access

🏛️
Auth Service
The brain - issues certificates, manages users, stores audit logs
🚪
Proxy Service
The gateway - handles all client connections, web UI, TLS termination
🖥️
SSH Service
Runs on each server - allows SSH access through Teleport
📜
Certificates
Short-lived certs replace SSH keys. Auto-expire in hours, not years!
🔐

Certificates vs SSH Keys

Traditional SSH Keys Teleport Certificates
Never expire Expire in hours (configurable)
Must be copied to each server Work on any enrolled server
Hard to revoke Instant revocation
No audit trail Every action logged
Manual management Automatic via SSO
🛡️

What is Zero Trust?

"Never trust, always verify"

Zero Trust means:

  • No implicit trust - Being on the network doesn't grant access
  • Verify identity - Authenticate every request
  • Least privilege - Only give access that's needed
  • Assume breach - Design as if attackers are inside
💡
Real World Analogy

Traditional: A key card gets you into the building, then you can go anywhere.
Zero Trust: You need to badge in at every door, and your access is logged.

2

Prerequisites

What you need before starting

Before You Begin

Make sure Project A (Authentik) is working

🔗

Required: Project A Complete

  • Authentik running at https://authentik.yourdomain.com
  • Traefik reverse proxy with HTTPS
  • Docker and Docker Compose installed
  • Domain name with DNS configured
🖥️

Server Requirements

Resource Additional Total with Project A+B
RAM +1 GB ~10 GB minimum
Storage +5 GB ~110 GB minimum
Ports 443, 3023, 3024, 3025 Web + SSH + Tunnel
🌐

DNS Requirements

Add these DNS records pointing to your server:

Record Type Purpose
teleport.yourdomain.com A Main Teleport access
*.teleport.yourdomain.com A Per-node web access
3

Install Teleport

Deploy Teleport with Docker

⚠️ Run Commands on Your SERVER

SSH into your server first. These commands run on the server, not your local machine.

1
Create Teleport Directory
⏱️ 2 min
📁 Create Directory Structure
# Navigate to your homelab directory
cd ~/homelab-iam

# Create Teleport directories
mkdir -p teleport/{config,data}

# Verify structure
ls -la teleport/
2
Create Teleport Configuration
⏱️ 5 min
⚙️ teleport.yaml
cat > ~/homelab-iam/teleport/config/teleport.yaml << 'EOF'
version: v3
teleport:
  nodename: teleport
  data_dir: /var/lib/teleport
  log:
    output: stderr
    severity: INFO

auth_service:
  enabled: true
  cluster_name: homelab
  listen_addr: 0.0.0.0:3025
  tokens:
    - proxy,node,app:your-secure-join-token-here
  # Session recording
  session_recording: node-sync

proxy_service:
  enabled: true
  web_listen_addr: 0.0.0.0:3080
  public_addr: teleport.yourdomain.com:443
  # ACME for Let's Encrypt (or use Traefik)
  https_keypairs: []
  acme:
    enabled: false

ssh_service:
  enabled: true
  labels:
    env: homelab
    role: main
EOF
📝
Replace Values!

Change teleport.yourdomain.com to your actual domain and generate a secure token for your-secure-join-token-here

3
Generate Secure Join Token
⏱️ 1 min
🔑 Generate Token
# Generate a secure random token
openssl rand -hex 32

# Copy the output and replace "your-secure-join-token-here"
# in teleport.yaml with this value

# Example output:
# a1b2c3d4e5f6...
4
Add Teleport to Docker Compose
⏱️ 5 min

Add this service to your docker-compose.yml:

🐳 Docker Compose Service
# Add to docker-compose.yml services section

  # ==========================================
  # TELEPORT - Zero Trust Access
  # ==========================================
  teleport:
    image: public.ecr.aws/gravitational/teleport:15
    container_name: teleport
    restart: unless-stopped
    hostname: teleport
    volumes:
      - ./teleport/config:/etc/teleport
      - ./teleport/data:/var/lib/teleport
    ports:
      - "3023:3023"   # SSH proxy
      - "3024:3024"   # SSH tunnel  
      - "3025:3025"   # Auth service
    command: start --config=/etc/teleport/teleport.yaml
    networks:
      - traefik-public
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.teleport.rule=Host(\`teleport.${DOMAIN}\`)"
      - "traefik.http.routers.teleport.entrypoints=websecure"
      - "traefik.http.routers.teleport.tls.certresolver=letsencrypt"
      - "traefik.http.services.teleport.loadbalancer.server.port=3080"
5
Start Teleport
⏱️ 3 min
🚀 Start the Service
cd ~/homelab-iam

# Pull the Teleport image
docker compose pull teleport

# Start Teleport
docker compose up -d teleport

# Check it's running
docker compose ps teleport

# View logs
docker logs teleport --tail=50
6
Create Admin User
⏱️ 2 min
👤 Create First User
# Create admin user with editor role
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 to set password and configure MFA
🎉
Teleport is Running!

Open the signup URL in your browser to create your admin account with MFA.

4

Add SSH Nodes

Connect servers to Teleport

🖥️
Connect Your Servers

Install Teleport agent on servers you want to access via SSH

1
Install Teleport Agent on Ubuntu
⏱️ 5 min

Run these commands on the SERVER you want to protect (not the Teleport server):

🐧 Ubuntu Agent Installation
# Add Teleport repository
sudo curl https://apt.releases.teleport.dev/gpg \
  -o /usr/share/keyrings/teleport-archive-keyring.asc

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

# Install Teleport
sudo apt update
sudo apt install -y teleport
2
Configure Agent to Join Cluster
⏱️ 5 min
⚙️ Agent Configuration
# Create agent config
sudo cat > /etc/teleport.yaml << 'EOF'
version: v3
teleport:
  nodename: my-server
  data_dir: /var/lib/teleport
  auth_token: your-secure-join-token-here
  auth_server: teleport.yourdomain.com:443

auth_service:
  enabled: false

proxy_service:
  enabled: false

ssh_service:
  enabled: true
  labels:
    env: homelab
    type: server
EOF

# Start Teleport service
sudo systemctl enable teleport
sudo systemctl start teleport

# Check status
sudo systemctl status teleport
📝
Use Your Values!

Replace your-secure-join-token-here with the token from step 3, and yourdomain.com with your actual domain.

3
Verify Node Connected
⏱️ 2 min
Check Node Status
# On the TELEPORT server, list nodes
docker exec teleport tctl nodes ls

# You should see:
# Node Name     Address         Labels
# ----------    -----------     ------
# my-server     192.168.x.x     env=homelab

# Or check in Web UI: Resources → Servers
🎉
Node Connected!

Your server is now protected by Teleport. You can SSH through the web UI or CLI!

4
Connect via tsh CLI
⏱️ 5 min

Install the Teleport client on your local machine:

💻 Install tsh Client
# macOS
brew install teleport

# Ubuntu/Debian (on your LOCAL machine)
curl https://goteleport.com/static/install.sh | bash -s 15.0.0

# Login to Teleport
tsh login --proxy=teleport.yourdomain.com:443

# List available servers
tsh ls

# SSH to a server
tsh ssh ubuntu@my-server
5

Authentik SSO Integration

Login to Teleport using Authentik

🔗
Single Sign-On

Use your Authentik credentials to access Teleport

1
Create SAML Provider in Authentik
⏱️ 5 min
  1. Open Authentik Admin: https://authentik.yourdomain.com
  2. Go to Applications → Providers → Create
  3. Select: SAML Provider
  4. Fill in:
    Field Value
    Name Teleport SAML Provider
    Authorization flow default-provider-authorization-implicit-consent
    ACS URL https://teleport.yourdomain.com/v1/webapi/saml/acs/authentik
    Audience https://teleport.yourdomain.com/v1/webapi/saml/acs/authentik
    Service Provider Binding Post
  5. Click Create
  6. Go back to the provider, click Download Metadata and save the file
2
Create Application in Authentik
⏱️ 2 min
  1. Go to Applications → Applications → Create
  2. Fill in:
    Name Teleport
    Slug teleport
    Provider Teleport SAML Provider
  3. Click Create
3
Configure Teleport SAML Connector
⏱️ 10 min
⚙️ Create SAML Connector
# Create SAML connector config
cat > ~/homelab-iam/teleport/authentik-saml.yaml << 'EOF'
kind: saml
version: v2
metadata:
  name: authentik
spec:
  display: "Login with Authentik"
  acs: https://teleport.yourdomain.com/v1/webapi/saml/acs/authentik
  entity_descriptor_url: https://authentik.yourdomain.com/api/v3/providers/saml/YOUR_PROVIDER_ID/metadata/
  attributes_to_roles:
    - name: "http://schemas.xmlsoap.org/claims/Group"
      value: "admins"
      roles: ["editor", "access"]
    - name: "http://schemas.xmlsoap.org/claims/Group"
      value: "users"
      roles: ["access"]
EOF

# Apply the connector
docker exec teleport tctl create -f /etc/teleport/authentik-saml.yaml

# Note: Copy the yaml file to the teleport config directory first
cp ~/homelab-iam/teleport/authentik-saml.yaml ~/homelab-iam/teleport/config/
📝
Get Provider ID!

Replace YOUR_PROVIDER_ID with the numeric ID from Authentik (visible in the provider URL).

4
Test SSO Login
⏱️ 2 min
  1. Open https://teleport.yourdomain.com
  2. Click "Login with Authentik"
  3. You'll be redirected to Authentik - login with your credentials
  4. After authentication, you'll be back in Teleport!
🎉
SSO Working!

You can now login to Teleport using your Authentik account. One identity, all access!

6

Role-Based Access Control

Define who can access what

🎭
Least Privilege Access

Users only get access to servers they need

1
Create Developer Role
⏱️ 5 min
👨‍💻 Developer Role Definition
# Create developer role
cat > ~/homelab-iam/teleport/config/role-developer.yaml << 'EOF'
kind: role
version: v7
metadata:
  name: developer
spec:
  allow:
    # Can only SSH to servers with env=dev label
    node_labels:
      env: ["dev", "staging"]
    # Can only login as these users
    logins: ["ubuntu", "developer"]
    # SSH rules
    rules:
      - resources: ["session"]
        verbs: ["list", "read"]
  options:
    # Session TTL
    max_session_ttl: 8h
    # Require MFA for SSH
    require_session_mfa: true
EOF

# Apply the role
docker exec teleport tctl create -f /etc/teleport/role-developer.yaml
2
Create Admin Role
⏱️ 5 min
👑 Admin Role Definition
# Create admin role
cat > ~/homelab-iam/teleport/config/role-admin.yaml << 'EOF'
kind: role
version: v7
metadata:
  name: sysadmin
spec:
  allow:
    # Can SSH to any server
    node_labels:
      '*': '*'
    # Can login as root
    logins: ["root", "ubuntu", "admin"]
    # Full access to Teleport resources
    rules:
      - resources: ["*"]
        verbs: ["*"]
  options:
    max_session_ttl: 4h
    require_session_mfa: true
    # Record all sessions
    record_session:
      default: best_effort
EOF

# Apply the role
docker exec teleport tctl create -f /etc/teleport/role-admin.yaml
📊

Role Comparison

Permission Developer SysAdmin
Server Access dev, staging only All servers
Login Users ubuntu, developer root, ubuntu, admin
Session Length 8 hours 4 hours
MFA Required Yes Yes
7

Session Recording

Record and replay SSH sessions

🎬
Complete Audit Trail

Every keystroke recorded. Replay sessions for security review or training!

🔍

What Gets Recorded

  • Every SSH command typed
  • Command output
  • Session start/end times
  • User identity
  • Server accessed
  • Files transferred (SCP)
1
View Session Recordings
⏱️ 2 min

In the Teleport Web UI:

  1. Go to Activity → Session Recordings
  2. Click on any session to replay
  3. Use playback controls to review
💻 CLI Playback
# List recordings
docker exec teleport tctl recordings ls

# Play a specific recording
docker exec -it teleport tctl recordings play SESSION_ID
💡
Compliance Ready

Session recordings help meet compliance requirements like PCI-DSS, HIPAA, and SOC2 which require audit trails of privileged access.

8

Testing & Verification

Make sure everything works

🧪
Test Your Setup

Verify all components are working correctly

Verification Checklist

  • Teleport Web UI accessible
  • Can login with local user
  • Can login with Authentik SSO
  • Nodes appear in Resources → Servers
  • Can SSH via Web UI
  • Can SSH via tsh CLI
  • Session recordings appear
Quick Connectivity Test
🔍 Test Commands
# Check Teleport status
docker exec teleport tctl status

# List all nodes
docker exec teleport tctl nodes ls

# List all users
docker exec teleport tctl users ls

# List all roles
docker exec teleport tctl get roles

# Test SSH (from your local machine)
tsh login --proxy=teleport.yourdomain.com
tsh ssh ubuntu@my-server
🔧

Common Issues

🔴 Node Won't Join Cluster

Cause: Token mismatch or network issue

Solution:
• Verify token matches in both configs
• Check node can reach teleport.yourdomain.com:443
• Check node logs: journalctl -u teleport

🔴 SSO Login Fails

Cause: SAML configuration mismatch

Solution:
• Verify ACS URL matches exactly
• Check entity_descriptor_url is accessible
• Ensure user has groups mapped in Authentik

🔴 Permission Denied on SSH

Cause: Role doesn't allow access

Solution:
• Check user's assigned roles
• Verify node_labels match server labels
• Ensure login user is in allowed logins

🎉

Congratulations!

Zero Trust Network Access is live!

🏆
ZTNA Expert Skills

You've implemented enterprise-grade Zero Trust access!

📊

Skills Demonstrated

  • Zero Trust Network Access (ZTNA)
  • Certificate-based authentication
  • SAML SSO integration
  • Role-based access control (RBAC)
  • Session recording and audit
  • Privileged access management
🚀

Next Steps

  • Add more servers to your Teleport cluster
  • Set up database access through Teleport
  • Configure Kubernetes access
  • Set up application access for web apps
  • Integrate with your SIEM (Project D)
  • Configure access requests workflow