SSH Access to TEE VMs
This guide covers setting up and managing secure SSH access to your Teenode TEE VMs. SSH is the primary method for connecting to and managing your virtual machines.
SSH Key Fundamentals
Understanding SSH Keys
SSH uses asymmetric cryptography with two keys:
- Private Key - Kept secret on your computer (like a password)
- Public Key - Placed on servers you want to access
When you connect, your computer proves it has the private key matching the public key on the server.
Generate SSH Keys
Best Practice: ED25519 Keys
# Generate ED25519 key (modern, secure, compact)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "[email protected]"
# Prompts:
# Enter passphrase (empty for no passphrase): <press Enter or enter passphrase>
# Enter same passphrase again: <confirm>
# Verify keys created
ls -la ~/.ssh/id_ed25519*Output:
-rw------- 1 user staff 419 Oct 19 10:00 ~/.ssh/id_ed25519
-rw-r--r-- 1 user staff 98 Oct 19 10:00 ~/.ssh/id_ed25519.pubAlternative: RSA Keys (for older systems)
# Generate 4096-bit RSA key
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -C "[email protected]"
# List keys
ls -la ~/.ssh/id_rsa*View Your Public Key
# Display public key content
cat ~/.ssh/id_ed25519.pub
# Output looks like:
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHpvbkI3L2c... [email protected]Never share your private key. The public key (ending in .pub) is safe to share.
Add Keys to Teenode
Add First Key
# Add your public key to Teenode
teenode ssh-key add \
--name "My Laptop" \
--key-file ~/.ssh/id_ed25519.pub
# Confirm addition
teenode ssh-key listAdd Multiple Keys
# Add work machine key
teenode ssh-key add \
--name "Work Desktop" \
--key-file ~/.ssh/work_key.pub
# Add personal machine key
teenode ssh-key add \
--name "Personal Laptop" \
--key-file ~/.ssh/personal_key.pub
# View all keys with details
teenode ssh-key list --verboseDelete Old Key
# Remove a key
teenode ssh-key delete "My Old Laptop"
# List updated keys
teenode ssh-key listConnect to TEE VMs
Quick Connection
# Use Teenode CLI to connect
teenode vm ssh my-vm-name
# This automatically uses your first available key
# You’ll be connected as root userDirect SSH Connection
# Get VM IP address
teenode vm describe my-vm-name | grep "IP Address"
# Connect directly
ssh -i ~/.ssh/id_ed25519 [email protected]
# If using default key location (~/.ssh/id_ed25519), you can omit -i
ssh [email protected]Connection Options
# Connect with specific key
ssh -i ~/.ssh/work_key [email protected]
# Connect and forward ports
ssh -i ~/.ssh/id_ed25519 -L 8000:localhost:8080 [email protected]
# Connect with verbose output (debugging)
ssh -vvv -i ~/.ssh/id_ed25519 [email protected]
# Keep connection alive
ssh -i ~/.ssh/id_ed25519 -o ServerAliveInterval=60 [email protected]SSH Configuration
Configure SSH Config File
Create or edit ~/.ssh/config for easier connections:
# Edit SSH config
nano ~/.ssh/config
# Add VM entries:
Host teenode-dev
HostName 203.0.113.42
User root
IdentityFile ~/.ssh/id_ed25519
AddKeysToAgent yes
Host teenode-prod
HostName 203.0.113.43
User root
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
AddKeysToAgent yes
Host teenode-*
StrictHostKeyChecking accept-new
User rootNow connect easily:
# Connect using config
ssh teenode-dev
# Forward port using config
ssh -L 8000:localhost:3000 teenode-devSet Proper Permissions
# SSH config file must have correct permissions
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
# Directory permissions
chmod 700 ~/.ssh
# Verify permissions
ls -la ~/.ssh/SSH will refuse to work if permissions are wrong. Always ensure private keys are 600 and public keys are 644.
SSH Agent for Key Management
Add Key to SSH Agent
# Add key to agent (prompts for passphrase if protected)
ssh-add ~/.ssh/id_ed25519
# View loaded keys
ssh-add -l
# List with fingerprints
ssh-add -l -E md5Persistent SSH Agent on macOS
# Add to ~/.ssh/config for macOS
Host *
AddKeysToAgent yes
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519
# Now ssh-agent will automatically add keys when neededSSH Agent on Linux
# Start SSH agent in bash
eval "$(ssh-agent -s)"
# Or in zsh, add to ~/.zshrc:
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
fi
# Add keys on login
ssh-add ~/.ssh/id_ed25519File Transfer
Upload Files
# Upload single file
scp ./local-file.txt [email protected]:/root/
# Upload directory
scp -r ./my-project [email protected]:/opt/
# Upload with specific key
scp -i ~/.ssh/id_ed25519 ./app.jar [email protected]:/app/Download Files
# Download single file
scp [email protected]:/root/output.txt ./
# Download directory
scp -r [email protected]:/var/log ./logs
# Download with progress
scp -v [email protected]:/root/large-file.zip ./Using rsync for Synchronization
# Sync directory with VM (one-way)
rsync -avz --delete -e ssh ./src [email protected]:/app/
# Sync from VM to local
rsync -avz -e ssh [email protected]:/data ./backup/
# With specific key
rsync -avz -e "ssh -i ~/.ssh/id_ed25519" ./files [email protected]:/data/rsync options:
-a- Archive mode (preserves permissions, timestamps)-v- Verbose-z- Compress during transfer--delete- Delete files on destination that don’t exist in source
Port Forwarding
Local Port Forwarding
Forward a local port to a service on the VM:
# Forward localhost:8000 to VM’s localhost:3000
ssh -i ~/.ssh/id_ed25519 -L 8000:localhost:3000 [email protected]
# Now access the service locally
curl http://localhost:8000
# Or use SSH config:
# LocalForward 8000 localhost:3000Remote Port Forwarding
Forward a VM port to your local machine:
# Forward VM’s port 5432 to localhost:5432
ssh -R 5432:localhost:5432 [email protected]
# Use case: Access local database from VMDynamic Port Forwarding (SOCKS Proxy)
# Create SOCKS proxy through VM
ssh -D 1080 [email protected]
# Configure browser or apps to use SOCKS proxy on localhost:1080Passwordless Authentication Setup
Configure VM for Key-Only Access
SSH into the VM and disable password authentication:
# SSH into VM
ssh [email protected]
# Edit SSH config
sudo nano /etc/ssh/sshd_config
# Make these changes:
# PasswordAuthentication no
# PubkeyAuthentication yes
# PermitRootLogin prohibit-password
# Restart SSH service
sudo systemctl restart ssh
# Log out
exitAlways test key access before disabling password authentication, or you may lock yourself out!
Multi-User SSH Access
Add Team Member SSH Key
Add colleague’s public key to the VM:
# SSH into VM
ssh [email protected]
# Create user for colleague
sudo useradd -m -s /bin/bash alice
# Add their public key
sudo mkdir -p /home/alice/.ssh
sudo touch /home/alice/.ssh/authorized_keys
sudo chmod 600 /home/alice/.ssh/authorized_keys
sudo chmod 700 /home/alice/.ssh
# Paste their public key into authorized_keys
# sudo nano /home/alice/.ssh/authorized_keys
# Fix permissions
sudo chown -R alice:alice /home/alice/.sshRotate Team Keys
# Remove old key
sudo sed -i '/old-key-fingerprint/d' /home/alice/.ssh/authorized_keys
# Add new key
echo "ssh-ed25519 AAAA..." | sudo tee -a /home/alice/.ssh/authorized_keysSSH Security Best Practices
Use Strong Passphrases
# When generating keys, use strong passphrase
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
# Enter passphrase: [something strong with numbers, symbols]Benefits of passphrases:
- If your private key is compromised, it’s still protected
- SSH agent caches the passphrase temporarily
- Works with multiple keys easily
Limit SSH Key Scope
Restrict what a key can do (in ~/.ssh/authorized_keys on server):
# Force command execution only
command="cd /app && npm start",restrict ssh-ed25519 AAAA...
# Allow specific commands only
command="/usr/local/bin/deploy-script.sh" ssh-ed25519 AAAA...
# Disable port forwarding
restrict,command="/bin/bash" ssh-ed25519 AAAA...
# Example full entry:
command="/app/runner.sh",no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAAC3Nza...Use Different Keys for Different Purposes
# Production key (on secure machine)
~/.ssh/prod_key
# Development key (can be less secure)
~/.ssh/dev_key
# Deploy key (restricted permissions)
~/.ssh/deploy_key
# SSH config to use appropriate keys
Host teenode-prod
IdentityFile ~/.ssh/prod_key
Host teenode-dev
IdentityFile ~/.ssh/dev_keyRegular Key Rotation
# Generate new key
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new
# Add new key to Teenode
teenode ssh-key add --name "New Key" --key-file ~/.ssh/id_ed25519_new.pub
# Test new key works
ssh -i ~/.ssh/id_ed25519_new [email protected]
# Remove old key from all VMs
teenode ssh-key delete "Old Key"
# Update SSH config to use new key
# Test that everything still works
# Delete old private key after confirming
rm ~/.ssh/id_ed25519Troubleshooting SSH Issues
Permission Denied (Public Key)
# Check key file permissions
ls -la ~/.ssh/id_ed25519
# Should be: -rw------- (600)
# Fix if needed:
chmod 600 ~/.ssh/id_ed25519
# Check SSH directory permissions
ls -la ~/.ssh/
# Should be: drwx------ (700)
# Fix if needed:
chmod 700 ~/.ssh
# Try again with verbose output
ssh -vvv -i ~/.ssh/id_ed25519 [email protected]VM Not Found or No Response
# Check VM status
teenode vm describe my-vm-name
# Get correct IP address
teenode vm describe my-vm-name | grep "IP Address"
# Check if VM is running
teenode vm list
# Try pinging VM (if allowed)
ping 203.0.113.42
# Test connectivity on specific port
telnet 203.0.113.42 22
# Check firewall rules
teenode vm firewall my-vm-name --listSSH Hangs or Times Out
# Add server alive interval to prevent timeout
ssh -o ServerAliveInterval=60 [email protected]
# Or add to ~/.ssh/config:
# ServerAliveInterval 60
# ServerAliveCountMax 3
# Try with shorter connection timeout
ssh -o ConnectTimeout=10 [email protected]Host Key Verification Failed
# First connection will ask to verify host key
# Type 'yes' to accept
# To skip verification (not recommended):
ssh -o StrictHostKeyChecking=no [email protected]
# To accept new host keys automatically:
ssh -o StrictHostKeyChecking=accept-new [email protected]
# View known hosts
cat ~/.ssh/known_hosts
# Remove specific host
ssh-keygen -R 203.0.113.42Key Not Being Used
# Check which keys SSH is trying
ssh -vvv [email protected] 2>&1 | grep -i "identity"
# Specify exact key to use
ssh -i ~/.ssh/id_ed25519 [email protected]
# Add key to SSH agent
ssh-add ~/.ssh/id_ed25519
# List keys in agent
ssh-add -l
# Remove key from agent if needed
ssh-add -d ~/.ssh/id_ed25519Advanced Configuration
SSH Jump Host (Bastion)
Connect through intermediate server:
# Via command line
ssh -J [email protected] [email protected]
# Or SSH config
Host teenode-prod
HostName 203.0.113.42
ProxyJump bastion.example.com
User rootSSH Certificate Authentication
For team environments, use SSH certificates:
# This requires CA setup
# Advanced setup not covered in this guide
# See OpenSSH documentation for detailsAutomation with SSH
Run Commands Without Interactive Shell
# Run single command
ssh [email protected] "docker ps"
# Run multiple commands
ssh [email protected] "apt update && apt upgrade -y"
# Run command with output capture
ssh [email protected] "uptime" > uptime.txtBatch Operations
# Script to run on multiple VMs
for vm in vm1 vm2 vm3; do
echo "Connecting to $vm..."
ssh root@$(teenode vm describe $vm | grep "IP Address" | awk '{print $NF}') \
"docker restart myapp"
doneNext Steps
You now have a comprehensive understanding of SSH access and key management for Teenode TEE VMs!