ssh-ops

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SSH Operations

SSH 操作

Connection Patterns

连接模式

Direct Connection

直接连接

bash
undefined
bash
undefined

Basic 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
undefined
ssh user@host << 'EOF' cd /app ls -la cat config.yaml EOF
undefined

Through Jump Host / Bastion

通过跳转主机/堡垒机

bash
undefined
bash
undefined

ProxyJump (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"
undefined
ssh -J jumpuser@bastion user@target "kubectl get pods"
undefined

SSH Config for Persistent Setup

配置SSH Config实现持久化连接

bash
undefined
bash
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
undefined
bash
undefined

Forward 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
undefined
ssh -L 8080:web:80 -L 5432:db:5432 -L 6379:redis:6379 user@bastion
undefined

Remote Port Forward (expose local service remotely)

远程端口转发(向远程暴露本地服务)

bash
undefined
bash
undefined

Expose 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
undefined
ssh -R 0.0.0.0:8080:localhost:3000 user@host
undefined

Dynamic SOCKS Proxy

动态SOCKS代理

bash
undefined
bash
undefined

Create 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
undefined
HTTPS_PROXY=socks5://localhost:1080 kubectl get pods
undefined

Tunnel in Background

后台运行隧道

bash
undefined
bash
undefined

Background 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"
autossh -M 0 -f -N -L 8080:service:80 user@host
-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>
undefined
ps aux | grep "ssh.*-L" | grep -v grep kill <pid>
undefined

Remote Kubernetes Access

远程Kubernetes访问

Through SSH Tunnel

通过SSH隧道访问

bash
undefined
bash
undefined

Setup: 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
kubectl config set-context tunnel-context
--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
kubectl config set-context tunnel-context
--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
undefined
kill $TUNNEL_PID
undefined

Execute kubectl Remotely

远程执行kubectl命令

bash
undefined
bash
undefined

Single 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
undefined
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
undefined

Interactive k9s Remotely

远程交互式使用k9s

bash
undefined
bash
undefined

Run 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"
undefined
ssh -t user@k8s-master "k9s --context production"
undefined

Remote Script Execution

远程脚本执行

Run Local Script Remotely

在远程主机运行本地脚本

bash
undefined
bash
undefined

Execute 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
undefined
ssh user@host << 'SCRIPT' #!/bin/bash set -euo pipefail echo "Running on $(hostname)" kubectl get pods -n production SCRIPT
undefined

Deploy and Execute

部署并执行脚本

bash
undefined
bash
undefined

Copy 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
undefined
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
undefined

File Transfer

文件传输

SCP

SCP

bash
undefined
bash
undefined

Copy 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/
undefined
scp -i ~/.ssh/mykey file.yaml user@host:/path/
undefined

Rsync over SSH

基于SSH的Rsync同步

bash
undefined
bash
undefined

Sync 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/
undefined
rsync -avz --delete -e ssh ./local/ user@host:/remote/
undefined

Connection Management

连接管理

Keep Connection Alive

保持连接存活

bash
undefined
bash
undefined

In 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
undefined
Host * ServerAliveInterval 60 ServerAliveCountMax 3 TCPKeepAlive yes
undefined

Connection Multiplexing (reuse connections)

连接复用(复用已有连接)

bash
undefined
bash
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
undefined
bash
undefined

Test 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"
undefined
ssh -J jumpuser@bastion -o ConnectTimeout=10 user@target echo "OK"
undefined

Automation Scripts

自动化脚本

Tunnel Manager

隧道管理器

bash
#!/usr/bin/env bash
bash
#!/usr/bin/env bash

tunnel.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
undefined
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
undefined

Remote Health Check

远程健康检查

bash
#!/usr/bin/env bash
bash
#!/usr/bin/env bash

remote-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
undefined
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
undefined

Batch Remote Execution

批量远程执行

bash
#!/usr/bin/env bash
bash
#!/usr/bin/env bash

run-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
undefined
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
undefined

Security Best Practices

安全最佳实践

Key Management

密钥管理

bash
undefined
bash
undefined

Generate 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
undefined
chmod 700 ~/.ssh chmod 600 ~/.ssh/id_* chmod 644 ~/.ssh/*.pub chmod 600 ~/.ssh/config
undefined

Agent Forwarding (careful!)

代理转发(需谨慎!)

bash
undefined
bash
undefined

Enable 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
undefined
ssh -J bastion target # Keys never leave your machine
undefined

Restrict Commands per Key

按密钥限制可执行命令

In remote
~/.ssh/authorized_keys
:
command="kubectl get pods",no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA... readonly-key
在远程主机的
~/.ssh/authorized_keys
中配置:
command="kubectl get pods",no-port-forwarding,no-X11-forwarding ssh-ed25519 AAAA... readonly-key

Troubleshooting

故障排查

Connection Issues

连接问题

bash
undefined
bash
undefined

Verbose 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
undefined
ssh -o PreferredAuthentications=publickey user@host
undefined

Tunnel Issues

隧道问题

bash
undefined
bash
undefined

Check 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
undefined
ssh -v -L 8080:target:80 user@bastion
undefined

Permission Denied

权限拒绝问题

Common causes:
  1. Wrong key permissions:
    chmod 600 ~/.ssh/id_*
  2. Wrong .ssh dir permissions:
    chmod 700 ~/.ssh
  3. Key not in agent:
    ssh-add ~/.ssh/mykey
  4. Server doesn't have public key:
    ssh-copy-id
  5. SELinux/firewall blocking
常见原因:
  1. 密钥权限错误:
    chmod 600 ~/.ssh/id_*
  2. .ssh目录权限错误:
    chmod 700 ~/.ssh
  3. 密钥未添加到代理:
    ssh-add ~/.ssh/mykey
  4. 服务器未添加公钥:
    ssh-copy-id
  5. SELinux/防火墙拦截