Zero Trust Network Access (ZTNA)
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.
This lab builds on a working Zero-Trust SSO Gateway (Project A) with Authentik. Teleport integrates with Authentik for SAML-based single sign-on.
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.
This guide covers SSH Access (highlighted). Other protocols can be added later.
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!
| 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)
Understanding Teleport terminology before we build.
Teleport has specific architecture and terminology. Understanding these concepts will make the hands-on sections much easier.
| 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 |
Deploy Teleport using Docker.
# 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/
# Generate a secure random token
openssl rand -hex 32
# Example output: a1b2c3d4e5f6g7h8...
# SAVE THIS TOKEN! You'll use it in the next step
Copy this token somewhere safe. You'll need it for:
# 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
YOUR_SECURE_TOKEN_HERE → The token from Step 2teleport.yourdomain.com → Your actual domain# 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
# 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
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
Check Teleport status:
docker exec teleport tctl status
# 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)
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
Connect servers to your Teleport cluster.
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.
# 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
# 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
my-server → A descriptive name (e.g., web-server-1, db-server)YOUR_SECURE_TOKEN → The same token from Phase 3teleport.yourdomain.com → Your Teleport server domain# 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
Back on your Teleport server, verify the node joined:
docker exec teleport tctl nodes ls
Your server is now part of the Teleport cluster. Users with appropriate roles can SSH to it through Teleport.
Common issues and their solutions when working with Teleport.
journalctl -u teleporttctl users lstctl get roles/ROLENAMEtsh login --proxy=teleport.yourdomain.com
Remove Teleport when finished with the lab.
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
This will permanently delete all Teleport configuration, certificates, and session recordings.
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/
# 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
You've implemented enterprise-grade Zero Trust Network Access!