ssh-ops
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSSH Operations
SSH 操作
Connection Patterns
连接模式
Direct Connection
直接连接
bash
undefinedbash
undefinedBasic connection
Basic connection
ssh user@host
ssh user@host
With specific key
With specific key
ssh -i ~/.ssh/id_rsa user@host
ssh -i ~/.ssh/id_rsa user@host
With specific port
With specific port
ssh -p 2222 user@host
ssh -p 2222 user@host
Execute single command
Execute single command
ssh user@host "command"
ssh user@host "command"
Execute multiple commands
Execute multiple commands
ssh user@host << 'EOF'
cd /app
ls -la
cat config.yaml
EOF
undefinedssh user@host << 'EOF'
cd /app
ls -la
cat config.yaml
EOF
undefinedThrough Jump Host / Bastion
通过跳转主机/堡垒机
bash
undefinedbash
undefinedProxyJump (OpenSSH 7.3+) - preferred
ProxyJump (OpenSSH 7.3+) - preferred
ssh -J jumpuser@bastion user@target
ssh -J jumpuser@bastion user@target
Multiple jumps
Multiple jumps
ssh -J jump1@bastion1,jump2@bastion2 user@target
ssh -J jump1@bastion1,jump2@bastion2 user@target
Legacy ProxyCommand
Legacy ProxyCommand
ssh -o ProxyCommand="ssh -W %h:%p jumpuser@bastion" user@target
ssh -o ProxyCommand="ssh -W %h:%p jumpuser@bastion" user@target
Execute command through jump
Execute command through jump
ssh -J jumpuser@bastion user@target "kubectl get pods"
undefinedssh -J jumpuser@bastion user@target "kubectl get pods"
undefinedSSH Config for Persistent Setup
配置SSH Config实现持久化连接
bash
undefinedbash
undefined~/.ssh/config
~/.ssh/config
Host bastion
HostName bastion.example.com
User jumpuser
IdentityFile ~/.ssh/bastion_key
Host target
HostName 10.0.1.50
User admin
ProxyJump bastion
IdentityFile ~/.ssh/target_key
Host k8s-*
User ubuntu
ProxyJump bastion
IdentityFile ~/.ssh/k8s_key
Host k8s-prod
HostName 10.0.1.100
Host k8s-staging
HostName 10.0.2.100
Then simply: `ssh target` or `ssh k8s-prod "kubectl get pods"`Host bastion
HostName bastion.example.com
User jumpuser
IdentityFile ~/.ssh/bastion_key
Host target
HostName 10.0.1.50
User admin
ProxyJump bastion
IdentityFile ~/.ssh/target_key
Host k8s-*
User ubuntu
ProxyJump bastion
IdentityFile ~/.ssh/k8s_key
Host k8s-prod
HostName 10.0.1.100
Host k8s-staging
HostName 10.0.2.100
然后只需执行:`ssh target` 或 `ssh k8s-prod "kubectl get pods"`Port Forwarding / Tunneling
端口转发/隧道
Local Port Forward (access remote service locally)
本地端口转发(在本地访问远程服务)
bash
undefinedbash
undefinedForward local:8080 → remote:80
Forward local:8080 → remote:80
ssh -L 8080:localhost:80 user@host
ssh -L 8080:localhost:80 user@host
Forward to service behind remote host
Forward to service behind remote host
ssh -L 8080:internal-service:80 user@bastion
ssh -L 8080:internal-service:80 user@bastion
Kubernetes API access through tunnel
Kubernetes API access through tunnel
ssh -L 6443:kubernetes.default:443 user@bastion
ssh -L 6443:kubernetes.default:443 user@bastion
Then: kubectl --server=https://localhost:6443 --insecure-skip-tls-verify get pods
Then: kubectl --server=https://localhost:6443 --insecure-skip-tls-verify get pods
Database access
Database access
ssh -L 5432:db.internal:5432 user@bastion
ssh -L 5432:db.internal:5432 user@bastion
Then: psql -h localhost -p 5432 -U dbuser mydb
Then: psql -h localhost -p 5432 -U dbuser mydb
Multiple forwards
Multiple forwards
ssh -L 8080:web:80 -L 5432:db:5432 -L 6379:redis:6379 user@bastion
undefinedssh -L 8080:web:80 -L 5432:db:5432 -L 6379:redis:6379 user@bastion
undefinedRemote Port Forward (expose local service remotely)
远程端口转发(向远程暴露本地服务)
bash
undefinedbash
undefinedExpose local:3000 on remote:8080
Expose local:3000 on remote:8080
ssh -R 8080:localhost:3000 user@host
ssh -R 8080:localhost:3000 user@host
Expose to all interfaces on remote (requires GatewayPorts yes)
Expose to all interfaces on remote (requires GatewayPorts yes)
ssh -R 0.0.0.0:8080:localhost:3000 user@host
undefinedssh -R 0.0.0.0:8080:localhost:3000 user@host
undefinedDynamic SOCKS Proxy
动态SOCKS代理
bash
undefinedbash
undefinedCreate SOCKS5 proxy on local:1080
Create SOCKS5 proxy on local:1080
ssh -D 1080 user@bastion
ssh -D 1080 user@bastion
Use with curl
Use with curl
curl --socks5 localhost:1080 http://internal-service/api
curl --socks5 localhost:1080 http://internal-service/api
Use with kubectl (via proxychains or similar)
Use with kubectl (via proxychains or similar)
HTTPS_PROXY=socks5://localhost:1080 kubectl get pods
undefinedHTTPS_PROXY=socks5://localhost:1080 kubectl get pods
undefinedTunnel in Background
后台运行隧道
bash
undefinedbash
undefinedBackground tunnel with connection keep-alive
Background tunnel with connection keep-alive
ssh -f -N -L 8080:service:80 user@host
ssh -f -N -L 8080:service:80 user@host
With autossh for auto-reconnect (install: brew install autossh)
With autossh for auto-reconnect (install: brew install autossh)
autossh -M 0 -f -N -L 8080:service:80 user@host
-o "ServerAliveInterval 30"
-o "ServerAliveCountMax 3"
-o "ServerAliveInterval 30"
-o "ServerAliveCountMax 3"
autossh -M 0 -f -N -L 8080:service:80 user@host
-o "ServerAliveInterval 30"
-o "ServerAliveCountMax 3"
-o "ServerAliveInterval 30"
-o "ServerAliveCountMax 3"
Kill background tunnel
Kill background tunnel
pkill -f "ssh.*-L 8080"
pkill -f "ssh.*-L 8080"
Or find and kill specific tunnel
Or find and kill specific tunnel
ps aux | grep "ssh.*-L" | grep -v grep
kill <pid>
undefinedps aux | grep "ssh.*-L" | grep -v grep
kill <pid>
undefinedRemote Kubernetes Access
远程Kubernetes访问
Through SSH Tunnel
通过SSH隧道访问
bash
undefinedbash
undefinedSetup: Tunnel to k8s API
Setup: Tunnel to k8s API
ssh -L 6443:kubernetes.default.svc:443 user@bastion -N &
TUNNEL_PID=$!
ssh -L 6443:kubernetes.default.svc:443 user@bastion -N &
TUNNEL_PID=$!
Configure kubectl for tunnel
Configure kubectl for tunnel
kubectl config set-cluster tunnel-cluster
--server=https://localhost:6443
--insecure-skip-tls-verify=true
--server=https://localhost:6443
--insecure-skip-tls-verify=true
kubectl config set-context tunnel-context
--cluster=tunnel-cluster
--user=admin
--cluster=tunnel-cluster
--user=admin
kubectl config use-context tunnel-context
kubectl config set-cluster tunnel-cluster
--server=https://localhost:6443
--insecure-skip-tls-verify=true
--server=https://localhost:6443
--insecure-skip-tls-verify=true
kubectl config set-context tunnel-context
--cluster=tunnel-cluster
--user=admin
--cluster=tunnel-cluster
--user=admin
kubectl config use-context tunnel-context
Use kubectl normally
Use kubectl normally
kubectl get pods -A
kubectl get pods -A
Cleanup
Cleanup
kill $TUNNEL_PID
undefinedkill $TUNNEL_PID
undefinedExecute kubectl Remotely
远程执行kubectl命令
bash
undefinedbash
undefinedSingle command
Single command
ssh user@k8s-master "kubectl get pods -n production"
ssh user@k8s-master "kubectl get pods -n production"
With context
With context
ssh user@k8s-master "kubectl --context=prod get pods"
ssh user@k8s-master "kubectl --context=prod get pods"
Watch (needs pseudo-terminal)
Watch (needs pseudo-terminal)
ssh -t user@k8s-master "kubectl get pods -w"
ssh -t user@k8s-master "kubectl get pods -w"
Logs
Logs
ssh user@k8s-master "kubectl logs -l app=myapp --tail=100"
ssh user@k8s-master "kubectl logs -l app=myapp --tail=100"
Multiple commands
Multiple commands
ssh user@k8s-master << 'EOF'
kubectl get pods -n production
kubectl get events -n production --sort-by='.lastTimestamp' | tail -20
kubectl top pods -n production
EOF
undefinedssh user@k8s-master << 'EOF'
kubectl get pods -n production
kubectl get events -n production --sort-by='.lastTimestamp' | tail -20
kubectl top pods -n production
EOF
undefinedInteractive k9s Remotely
远程交互式使用k9s
bash
undefinedbash
undefinedRun k9s interactively (requires -t for TTY)
Run k9s interactively (requires -t for TTY)
ssh -t user@k8s-master "k9s"
ssh -t user@k8s-master "k9s"
In specific namespace
In specific namespace
ssh -t user@k8s-master "k9s -n production"
ssh -t user@k8s-master "k9s -n production"
Read-only mode
Read-only mode
ssh -t user@k8s-master "k9s --readonly"
ssh -t user@k8s-master "k9s --readonly"
With specific context
With specific context
ssh -t user@k8s-master "k9s --context production"
undefinedssh -t user@k8s-master "k9s --context production"
undefinedRemote Script Execution
远程脚本执行
Run Local Script Remotely
在远程主机运行本地脚本
bash
undefinedbash
undefinedExecute local script on remote
Execute local script on remote
ssh user@host 'bash -s' < local-script.sh
ssh user@host 'bash -s' < local-script.sh
With arguments
With arguments
ssh user@host 'bash -s' < local-script.sh arg1 arg2
ssh user@host 'bash -s' < local-script.sh arg1 arg2
Inline script
Inline script
ssh user@host << 'SCRIPT'
#!/bin/bash
set -euo pipefail
echo "Running on $(hostname)"
kubectl get pods -n production
SCRIPT
undefinedssh user@host << 'SCRIPT'
#!/bin/bash
set -euo pipefail
echo "Running on $(hostname)"
kubectl get pods -n production
SCRIPT
undefinedDeploy and Execute
部署并执行脚本
bash
undefinedbash
undefinedCopy and run
Copy and run
scp deploy.sh user@host:/tmp/
ssh user@host "chmod +x /tmp/deploy.sh && /tmp/deploy.sh"
scp deploy.sh user@host:/tmp/
ssh user@host "chmod +x /tmp/deploy.sh && /tmp/deploy.sh"
Or one-liner with heredoc
Or one-liner with heredoc
ssh user@host << 'EOF'
cat > /tmp/check.sh << 'INNER'
#!/bin/bash
kubectl get pods -A | grep -v Running
kubectl get events -A --field-selector type=Warning | tail -20
INNER
chmod +x /tmp/check.sh
/tmp/check.sh
EOF
undefinedssh user@host << 'EOF'
cat > /tmp/check.sh << 'INNER'
#!/bin/bash
kubectl get pods -A | grep -v Running
kubectl get events -A --field-selector type=Warning | tail -20
INNER
chmod +x /tmp/check.sh
/tmp/check.sh
EOF
undefinedFile Transfer
文件传输
SCP
SCP
bash
undefinedbash
undefinedCopy to remote
Copy to remote
scp file.yaml user@host:/path/
scp file.yaml user@host:/path/
Copy from remote
Copy from remote
scp user@host:/path/file.yaml ./
scp user@host:/path/file.yaml ./
Through jump host
Through jump host
scp -J jumpuser@bastion file.yaml user@target:/path/
scp -J jumpuser@bastion file.yaml user@target:/path/
Recursive directory
Recursive directory
scp -r ./manifests user@host:/deploy/
scp -r ./manifests user@host:/deploy/
With specific key
With specific key
scp -i ~/.ssh/mykey file.yaml user@host:/path/
undefinedscp -i ~/.ssh/mykey file.yaml user@host:/path/
undefinedRsync over SSH
基于SSH的Rsync同步
bash
undefinedbash
undefinedSync directory
Sync directory
rsync -avz -e ssh ./local/ user@host:/remote/
rsync -avz -e ssh ./local/ user@host:/remote/
Through jump host
Through jump host
rsync -avz -e "ssh -J jumpuser@bastion" ./local/ user@target:/remote/
rsync -avz -e "ssh -J jumpuser@bastion" ./local/ user@target:/remote/
Dry run first
Dry run first
rsync -avzn -e ssh ./local/ user@host:/remote/
rsync -avzn -e ssh ./local/ user@host:/remote/
Delete files on remote not in local
Delete files on remote not in local
rsync -avz --delete -e ssh ./local/ user@host:/remote/
undefinedrsync -avz --delete -e ssh ./local/ user@host:/remote/
undefinedConnection Management
连接管理
Keep Connection Alive
保持连接存活
bash
undefinedbash
undefinedIn command
In command
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@host
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@host
In ~/.ssh/config (global)
In ~/.ssh/config (global)
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
undefinedHost *
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
undefinedConnection Multiplexing (reuse connections)
连接复用(复用已有连接)
bash
undefinedbash
undefined~/.ssh/config
~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Create socket directory
Create socket directory
mkdir -p ~/.ssh/sockets
First connection creates socket, subsequent connections reuse it (faster).mkdir -p ~/.ssh/sockets
首次连接会创建套接字,后续连接会复用该套接字(连接速度更快)。Check Connection
检查连接状态
bash
undefinedbash
undefinedTest SSH connectivity
Test SSH connectivity
ssh -o ConnectTimeout=5 -o BatchMode=yes user@host echo "OK" 2>/dev/null && echo "Connected" || echo "Failed"
ssh -o ConnectTimeout=5 -o BatchMode=yes user@host echo "OK" 2>/dev/null && echo "Connected" || echo "Failed"
Verbose connection debugging
Verbose connection debugging
ssh -vvv user@host
ssh -vvv user@host
Test through bastion
Test through bastion
ssh -J jumpuser@bastion -o ConnectTimeout=10 user@target echo "OK"
undefinedssh -J jumpuser@bastion -o ConnectTimeout=10 user@target echo "OK"
undefinedAutomation Scripts
自动化脚本
Tunnel Manager
隧道管理器
bash
#!/usr/bin/env bashbash
#!/usr/bin/env bashtunnel.sh - Manage SSH tunnels
tunnel.sh - Manage SSH tunnels
ACTION="${1:-status}"
TUNNEL_NAME="${2:-default}"
BASTION="user@bastion.example.com"
PIDFILE="/tmp/ssh-tunnel-${TUNNEL_NAME}.pid"
case "$ACTION" in
start)
if [[ -f "$PIDFILE" ]] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
echo "Tunnel already running (PID: $(cat "$PIDFILE"))"
exit 0
fi
case "$TUNNEL_NAME" in
k8s)
ssh -f -N -L 6443:kubernetes:443 "$BASTION" \
-o ServerAliveInterval=30 \
-o ExitOnForwardFailure=yes
;;
db)
ssh -f -N -L 5432:postgres.internal:5432 "$BASTION" \
-o ServerAliveInterval=30 \
-o ExitOnForwardFailure=yes
;;
*)
echo "Unknown tunnel: $TUNNEL_NAME"
exit 1
;;
esac
pgrep -f "ssh.*-L.*$TUNNEL_NAME" > "$PIDFILE"
echo "Tunnel $TUNNEL_NAME started (PID: $(cat "$PIDFILE"))"
;;
stop)
if [[ -f "$PIDFILE" ]]; then
kill "$(cat "$PIDFILE")" 2>/dev/null
rm "$PIDFILE"
echo "Tunnel $TUNNEL_NAME stopped"
else
pkill -f "ssh.*-L.*$TUNNEL_NAME"
echo "Tunnel $TUNNEL_NAME stopped (by pattern)"
fi
;;
status)
if [[ -f "$PIDFILE" ]] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
echo "Tunnel $TUNNEL_NAME: running (PID: $(cat "$PIDFILE"))"
else
echo "Tunnel $TUNNEL_NAME: not running"
fi
;;
*)
echo "Usage: $0 {start|stop|status} [tunnel-name]"
echo "Tunnels: k8s, db"
;;esac
undefinedACTION="${1:-status}"
TUNNEL_NAME="${2:-default}"
BASTION="user@bastion.example.com"
PIDFILE="/tmp/ssh-tunnel-${TUNNEL_NAME}.pid"
case "$ACTION" in
start)
if [[ -f "$PIDFILE" ]] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
echo "Tunnel already running (PID: $(cat "$PIDFILE"))"
exit 0
fi
case "$TUNNEL_NAME" in
k8s)
ssh -f -N -L 6443:kubernetes:443 "$BASTION" \
-o ServerAliveInterval=30 \
-o ExitOnForwardFailure=yes
;;
db)
ssh -f -N -L 5432:postgres.internal:5432 "$BASTION" \
-o ServerAliveInterval=30 \
-o ExitOnForwardFailure=yes
;;
*)
echo "Unknown tunnel: $TUNNEL_NAME"
exit 1
;;
esac
pgrep -f "ssh.*-L.*$TUNNEL_NAME" > "$PIDFILE"
echo "Tunnel $TUNNEL_NAME started (PID: $(cat "$PIDFILE"))"
;;
stop)
if [[ -f "$PIDFILE" ]]; then
kill "$(cat "$PIDFILE")" 2>/dev/null
rm "$PIDFILE"
echo "Tunnel $TUNNEL_NAME stopped"
else
pkill -f "ssh.*-L.*$TUNNEL_NAME"
echo "Tunnel $TUNNEL_NAME stopped (by pattern)"
fi
;;
status)
if [[ -f "$PIDFILE" ]] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
echo "Tunnel $TUNNEL_NAME: running (PID: $(cat "$PIDFILE"))"
else
echo "Tunnel $TUNNEL_NAME: not running"
fi
;;
*)
echo "Usage: $0 {start|stop|status} [tunnel-name]"
echo "Tunnels: k8s, db"
;;esac
undefinedRemote Health Check
远程健康检查
bash
#!/usr/bin/env bashbash
#!/usr/bin/env bashremote-k8s-check.sh - Check k8s cluster health via SSH
remote-k8s-check.sh - Check k8s cluster health via SSH
HOST="${1:?Usage: $0 <ssh-host> [namespace]}"
NS="${2:-default}"
echo "=== Checking $HOST ($NS namespace) ==="
ssh "$HOST" << EOF
echo "--- Pod Status ---"
kubectl get pods -n $NS -o wide
echo ""
echo "--- Non-Running Pods ---"
kubectl get pods -n $NS | grep -v Running | grep -v Completed | grep -v NAME
echo ""
echo "--- Recent Events ---"
kubectl get events -n $NS --sort-by='.lastTimestamp' | tail -15
echo ""
echo "--- Resource Usage ---"
kubectl top pods -n $NS 2>/dev/null || echo "Metrics unavailable"
EOF
undefinedHOST="${1:?Usage: $0 <ssh-host> [namespace]}"
NS="${2:-default}"
echo "=== Checking $HOST ($NS namespace) ==="
ssh "$HOST" << EOF
echo "--- Pod Status ---"
kubectl get pods -n $NS -o wide
echo ""
echo "--- Non-Running Pods ---"
kubectl get pods -n $NS | grep -v Running | grep -v Completed | grep -v NAME
echo ""
echo "--- Recent Events ---"
kubectl get events -n $NS --sort-by='.lastTimestamp' | tail -15
echo ""
echo "--- Resource Usage ---"
kubectl top pods -n $NS 2>/dev/null || echo "Metrics unavailable"
EOF
undefinedBatch Remote Execution
批量远程执行
bash
#!/usr/bin/env bashbash
#!/usr/bin/env bashrun-on-hosts.sh - Run command on multiple hosts
run-on-hosts.sh - Run command on multiple hosts
HOSTS=("k8s-prod" "k8s-staging" "k8s-dev")
CMD="${1:?Usage: $0 'command'}"
for host in "${HOSTS[@]}"; do
echo "=== $host ==="
ssh -o ConnectTimeout=10 "$host" "$CMD" 2>&1 || echo "FAILED: $host"
echo ""
done
undefinedHOSTS=("k8s-prod" "k8s-staging" "k8s-dev")
CMD="${1:?Usage: $0 'command'}"
for host in "${HOSTS[@]}"; do
echo "=== $host ==="
ssh -o ConnectTimeout=10 "$host" "$CMD" 2>&1 || echo "FAILED: $host"
echo ""
done
undefinedSecurity Best Practices
安全最佳实践
Key Management
密钥管理
bash
undefinedbash
undefinedGenerate ed25519 key (preferred)
Generate ed25519 key (preferred)
ssh-keygen -t ed25519 -C "description" -f ~/.ssh/mykey
ssh-keygen -t ed25519 -C "description" -f ~/.ssh/mykey
Copy public key to server
Copy public key to server
ssh-copy-id -i ~/.ssh/mykey.pub user@host
ssh-copy-id -i ~/.ssh/mykey.pub user@host
Restrict key permissions
Restrict key permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
chmod 600 ~/.ssh/config
undefinedchmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
chmod 600 ~/.ssh/config
undefinedAgent Forwarding (careful!)
代理转发(需谨慎!)
bash
undefinedbash
undefinedEnable agent forwarding (only to trusted hosts)
Enable agent forwarding (only to trusted hosts)
ssh -A user@bastion
ssh -A user@bastion
Then on bastion, can SSH to other hosts using local keys
Then on bastion, can SSH to other hosts using local keys
ssh target-server
ssh target-server
Safer: ProxyJump instead of agent forwarding
Safer: ProxyJump instead of agent forwarding
ssh -J bastion target # Keys never leave your machine
undefinedssh -J bastion target # Keys never leave your machine
undefinedRestrict Commands per Key
按密钥限制可执行命令
In remote :
~/.ssh/authorized_keyscommand="kubectl get pods",no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA... readonly-key在远程主机的 中配置:
~/.ssh/authorized_keyscommand="kubectl get pods",no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA... readonly-keyTroubleshooting
故障排查
Connection Issues
连接问题
bash
undefinedbash
undefinedVerbose output
Verbose output
ssh -vvv user@host
ssh -vvv user@host
Check key being offered
Check key being offered
ssh -v user@host 2>&1 | grep "Offering"
ssh -v user@host 2>&1 | grep "Offering"
Test specific key
Test specific key
ssh -i ~/.ssh/specific_key -v user@host
ssh -i ~/.ssh/specific_key -v user@host
Check server allows key auth
Check server allows key auth
ssh -o PreferredAuthentications=publickey user@host
undefinedssh -o PreferredAuthentications=publickey user@host
undefinedTunnel Issues
隧道问题
bash
undefinedbash
undefinedCheck if tunnel port is listening
Check if tunnel port is listening
lsof -i :8080
netstat -an | grep 8080
lsof -i :8080
netstat -an | grep 8080
Test tunnel connectivity
Test tunnel connectivity
nc -zv localhost 8080
nc -zv localhost 8080
Debug tunnel
Debug tunnel
ssh -v -L 8080:target:80 user@bastion
undefinedssh -v -L 8080:target:80 user@bastion
undefinedPermission Denied
权限拒绝问题
Common causes:
- Wrong key permissions:
chmod 600 ~/.ssh/id_* - Wrong .ssh dir permissions:
chmod 700 ~/.ssh - Key not in agent:
ssh-add ~/.ssh/mykey - Server doesn't have public key:
ssh-copy-id - SELinux/firewall blocking
常见原因:
- 密钥权限错误:
chmod 600 ~/.ssh/id_* - .ssh目录权限错误:
chmod 700 ~/.ssh - 密钥未添加到代理:
ssh-add ~/.ssh/mykey - 服务器未添加公钥:
ssh-copy-id - SELinux/防火墙拦截