SSH Targets
SSH targets enable command execution on remote servers through secure shell connections. Xec provides advanced SSH features including connection pooling, tunneling, and automatic retry mechanisms.
Basic Configuration​
Define SSH hosts in the targets.hosts section:
targets:
hosts:
web-server:
host: web.example.com
username: deploy
privateKey: ~/.ssh/id_rsa
Connection Properties​
Essential Properties​
targets:
hosts:
server:
# Required
host: server.example.com # Hostname or IP address
# Authentication (at least one required)
username: deploy # SSH username
privateKey: ~/.ssh/id_rsa # Path to private key
password: ${secrets.password} # Password (use secrets!)
# Optional
port: 22 # SSH port (default: 22)
passphrase: ${secrets.phrase} # Key passphrase
Advanced Properties​
targets:
hosts:
advanced:
host: server.example.com
username: admin
# Connection settings
keepAlive: true # Keep connection alive
keepAliveInterval: 30000 # Keep-alive interval (ms)
timeout: 60000 # Connection timeout (ms)
# Execution settings
shell: /bin/bash # Shell to use
encoding: utf8 # Output encoding
maxBuffer: 10485760 # Max output buffer (bytes)
throwOnNonZeroExit: true # Throw on non-zero exit
# Working directory
workdir: /var/www/app # Default directory
cwd: /var/www/app # Alias for workdir
# Environment
env:
NODE_ENV: production
PATH: /usr/local/bin:$PATH
Authentication Methods​
Private Key Authentication​
Most secure and recommended method:
targets:
hosts:
secure:
host: secure.example.com
username: deploy
privateKey: ~/.ssh/deploy_key
passphrase: ${secrets.key_passphrase} # If key is encrypted
Multiple Key Attempts​
targets:
hosts:
multi-key:
host: server.example.com
username: admin
privateKey: |
~/.ssh/id_rsa
~/.ssh/id_ed25519
~/.ssh/deploy_key
Password Authentication​
Less secure, use only when necessary:
targets:
hosts:
legacy:
host: old-server.example.com
username: admin
password: ${secrets.legacy_password} # Never hardcode!
SSH Agent​
Use SSH agent for key management:
targets:
hosts:
agent:
host: server.example.com
username: deploy
# No privateKey specified - uses SSH agent
Connection Pooling​
Optimize performance with connection reuse:
targets:
hosts:
pooled:
host: busy-server.example.com
connectionPool:
enabled: true # Enable pooling
min: 2 # Minimum connections
max: 10 # Maximum connections
idleTimeout: 300000 # Idle timeout (5 min)
acquireTimeout: 30000 # Acquire timeout
Pool Configuration Examples​
# High-traffic server
targets:
hosts:
api:
host: api.example.com
connectionPool:
min: 5
max: 20
idleTimeout: 600000 # 10 minutes
# Low-traffic server
targets:
hosts:
backup:
host: backup.example.com
connectionPool:
min: 0
max: 2
idleTimeout: 60000 # 1 minute
Proxy Connections​
Connect through jump hosts:
targets:
hosts:
# Simple proxy
behind-firewall:
host: internal.example.com
proxy: bastion.example.com
username: deploy
# Proxy with authentication
secured:
host: secure-internal.example.com
proxy: user@jump.example.com:2222
privateKey: ~/.ssh/internal_key
Multi-Hop Proxy​
targets:
hosts:
deep-internal:
host: deep.internal.example.com
proxy: bastion1.example.com,bastion2.example.com
username: deploy
Sudo Execution​
Execute commands with elevated privileges:
targets:
hosts:
admin-server:
host: server.example.com
username: admin
sudo:
enabled: true
method: sudo # or 'su'
password: ${secrets.sudo_password}
Sudo Patterns​
# Passwordless sudo
targets:
hosts:
trusted:
host: trusted.example.com
sudo:
enabled: true
# No password needed
# Custom sudo command
targets:
hosts:
custom:
host: custom.example.com
sudo:
enabled: true
method: "doas" # BSD systems
SFTP Configuration​
Configure secure file transfer:
targets:
hosts:
file-server:
host: files.example.com
sftp:
enabled: true
concurrency: 5 # Parallel transfers
chunkSize: 32768 # Transfer chunk size
fastGet: true # Enable fast download
fastPut: true # Enable fast upload
Environment Variables​
Set environment for all commands:
targets:
hosts:
app-server:
host: app.example.com
env:
# Application settings
NODE_ENV: production
API_URL: https://api.example.com
# Path modifications
PATH: /opt/app/bin:$PATH
LD_LIBRARY_PATH: /opt/app/lib
# Locale settings
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
Working Directory​
Control command execution location:
targets:
hosts:
project:
host: dev.example.com
workdir: /home/deploy/project
# All commands run in workdir
# xec in hosts.project "ls" → runs in /home/deploy/project
Shell Configuration​
Customize shell behavior:
targets:
hosts:
# Use specific shell
zsh-server:
host: modern.example.com
shell: /bin/zsh
# No shell (direct execution)
direct:
host: minimal.example.com
shell: false
# Custom shell command
custom-shell:
host: special.example.com
shell: "/bin/bash --noprofile"
Timeout Configuration​
Prevent hanging connections:
targets:
hosts:
slow-server:
host: slow.example.com
timeout: 300000 # 5 minute timeout
fast-server:
host: fast.example.com
timeout: 5000 # 5 second timeout
Error Handling​
Configure error behavior:
targets:
hosts:
strict:
host: critical.example.com
throwOnNonZeroExit: true # Fail on any error
lenient:
host: test.example.com
throwOnNonZeroExit: false # Continue on error
Host Groups​
Organize related hosts:
targets:
hosts:
# Web servers
web-1:
host: web1.example.com
username: deploy
web-2:
host: web2.example.com
username: deploy
web-3:
host: web3.example.com
username: deploy
# Database servers
db-primary:
host: db1.example.com
username: dba
db-replica:
host: db2.example.com
username: dba
Dynamic Host Discovery​
Discover hosts at runtime:
targets:
hosts:
# From environment variable
$env: SSH_HOSTS
# From command output
$command: "terraform output -json servers | jq -r '.[]'"
# From file
$file: ./hosts.txt
Real-World Examples​
Production Web Server​
targets:
hosts:
production-web:
host: prod-web.example.com
username: deploy
privateKey: ~/.ssh/prod_deploy_key
port: 22
# Performance optimization
keepAlive: true
keepAliveInterval: 30000
connectionPool:
min: 2
max: 10
idleTimeout: 300000
# Environment
workdir: /var/www/app
env:
NODE_ENV: production
PORT: 3000
# Reliability
timeout: 60000
throwOnNonZeroExit: true
Development Server​
targets:
hosts:
dev-server:
host: dev.example.com
username: developer
privateKey: ~/.ssh/id_rsa
# Convenience settings
workdir: ~/projects
env:
NODE_ENV: development
DEBUG: "*"
# Lenient error handling
throwOnNonZeroExit: false
Bastion Access​
targets:
hosts:
internal-api:
host: 10.0.1.50
username: api-user
privateKey: ~/.ssh/internal_key
proxy: bastion.example.com
# Security
sudo:
enabled: false
# Restricted environment
env:
PATH: /usr/local/bin:/usr/bin:/bin
Troubleshooting​
Connection Debugging​
# Test connection
xec test hosts.production
# Verbose SSH output
xec --verbose in hosts.production "echo test"
# Check SSH configuration
xec config show --target hosts.production
Common Issues​
Permission Denied​
# Check authentication
targets:
hosts:
fixed:
host: server.example.com
username: correct_username # Verify username
privateKey: ~/.ssh/correct_key # Verify key path
# Check key permissions: chmod 600 ~/.ssh/correct_key
Connection Timeout​
# Increase timeout
targets:
hosts:
slow:
host: slow.example.com
timeout: 120000 # 2 minutes
keepAlive: true
keepAliveInterval: 10000
Proxy Issues​
# Debug proxy connection
targets:
hosts:
debug-proxy:
host: internal.example.com
proxy: -v bastion.example.com # Add -v for verbose
Security Best Practices​
1. Use Key Authentication​
# Good - key authentication
targets:
hosts:
secure:
privateKey: ~/.ssh/deploy_key
# Avoid - password authentication
targets:
hosts:
insecure:
password: "plaintext" # Never do this!
2. Secure Key Storage​
# Set proper permissions
chmod 600 ~/.ssh/deploy_key
chmod 700 ~/.ssh
3. Use Secrets Management​
targets:
hosts:
managed:
host: server.example.com
passphrase: ${secrets.ssh_passphrase}
sudo:
password: ${secrets.sudo_password}
4. Limit Environment Exposure​
targets:
hosts:
limited:
host: server.example.com
env:
# Only necessary variables
APP_ENV: production
# Avoid sensitive data in env
5. Use Connection Pooling​
# Reuse connections securely
targets:
hosts:
pooled:
connectionPool:
max: 5 # Limit concurrent connections
idleTimeout: 300000 # Close idle connections
Next Steps​
- Docker Targets - Container configuration
- Kubernetes Targets - Pod configuration
See Also​
- SSH Command - SSH-specific commands
- File Transfer - Copying files via SSH
- Port Forwarding - SSH tunneling