ssh 命令详解
更新时间:2026-08-28。本文是「一个命令一个文档」系列,聚焦
ssh——网络与远程命令族(见网络命令族)的核心。它远比"连一下服务器"强大。
ssh(Secure Shell,安全外壳)是加密的远程登录协议。它干三件大事:登录远端执行命令、在两端之间安全传文件(配合 scp)、以及端口转发/建隧道——把本地端口的流量经远端转发,这是访问内网、翻越限制、做代理的底层机制。
一、基本登录
ssh user@host # 登录远程主机
ssh user@host -p 2222 # 指定端口(非默认 22)
ssh user@host "uptime" # 不进交互,直接执行一条远程命令后退出
ssh -t user@host "screen -r" # -t 强制分配伪终端,跑需要 tty 的程序
ssh user@host "cmd"这种"执行完即退"的用法,是写运维脚本、批量巡检的基础——不用交互、拿输出就走。如果远程命令需要终端(如 top、vim、screen),加-t强制分配 tty,否则会报"not a terminal"。
二、免密登录:ssh-keygen + ssh-copy-id
每次输入密码既烦又不自动化。正确做法是用密钥对:
ssh-keygen -t ed25519 -C "my-laptop" # 生成密钥(默认 ~/.ssh/id_ed25519)
ssh-copy-id user@host # 把公钥塞进远端 ~/.ssh/authorized_keys优先用
ed25519算法(比传统 RSA 更短更安全);-C只是注释,方便识别这把钥匙是哪来的。生成时若设了 passphrase,可用ssh-agent缓存,避免每次输入。ssh-copy-id 一条就把公钥追加到远端authorized_keys,比手动 scp 再改权限省心——注意远端~/.ssh权限须 700、authorized_keys须 600,否则 sshd 会拒绝,这是免密失败的头号原因。
三、连接复用:ControlMaster
频繁 ssh 连同一台机器,每次握手很慢。开启复用:
# ~/.ssh/config
Host *
ControlMaster auto
ControlPath ~/.ssh/%r@%h:%p
ControlPersist 600这段配置让第一条 ssh 连接保持一个"主控" socket,后续连接直接复用,登录从几百毫秒降到近乎瞬间,批量脚本提速明显。
ControlPersist 600表示主控连接空闲 10 分钟后才关。在多机运维、CI 里几乎是必配。
四、端口转发:ssh 最被低估的能力
这是 ssh 的精髓,三种转发:
# 本地转发 -L:把本地端口映射到远端能访问的地址
ssh -L 8080:localhost:80 user@host # 本地访问 localhost:8080 = 访问 host 的 80
# 远程转发 -R:把远端端口映射回本地
ssh -R 9000:localhost:3000 user@host # 远端访问 9000 = 访问你本机的 3000
# 动态转发 -D:建 SOCKS5 代理
ssh -D 1080 user@host # 本地 1080 成为 SOCKS 代理,流量经 host 出去
-L最常用:比如数据库只允许在服务器本机访问,你ssh -L 3306:localhost:3306 user@db-host,然后本地连localhost:3306就像连在服务器上一样,无需把数据库端口暴露公网。本项目部署时就用ssh -D 1080建 SOCKS 代理,让git push走服务器出口(详见 部署构建架构)。-R适合"把内网服务临时暴露给远端",做演示、调试 Webhook 回调很方便。
五、后台隧道:-f -N
ssh -f -N -D 1080 user@host # -f 后台运行,-N 不执行命令(纯隧道)
ssh -O exit -D 1080 user@host # 关闭对应的后台隧道
-N表示"不执行远程命令",-f让它在认证完后转入后台——合起来就是"只开隧道、不占终端",适合当长期代理用。要关就用-O exit(control 指令)或pkill ssh。本项目里这条命令就是让本地 git 通过服务器代理推 GitHub 的关键。
六、实战:一条命令批量巡检
for h in web1 web2 web3; do
echo "=== $h ==="
ssh -o StrictHostKeyChecking=no $h "uptime; df -h / | tail -1"
done-o StrictHostKeyChecking=no 在已知安全的内部环境里跳过首次 host key 确认,避免交互卡住——但公网环境别这么干,那是中间人攻击的温床。
七、进阶:跳板机与 ProxyJump(部署实战)
多一层网络拓扑时,ssh 的跳转能力是日常刚需。本项目部署就是典型:本地机器不能直接连 GitHub,但服务器能,于是让本地 ssh 经服务器跳一下再连 GitHub。
# ~/.ssh/config:定义跳板,之后 git 走这条通道
Host github-via-bastion
HostName github.com
User git
ProxyCommand ssh -W %h:%p chzhuo@124.221.142.185
# 本地直接推,流量经服务器出口
git push github-via-bastion masterProxyCommand ssh -W %h:%p 跳板 的意思是"建立到目标的 TCP 连接时,先通过跳板机转发"。比老式的 ssh -D 1080 + socks 代理稳得多——不用维护后台隧道,断了重连也简单。多个跳板还能串:ProxyJump A,B,C。
八、配置与排障的延伸
- 连接复用提速:
~/.ssh/config里加ControlMaster auto+ControlPersist 600,首次连接后复用,后续 ssh/scp 秒开,批量运维体感差异巨大。 - 首次 host key 确认:公网务必保留
StrictHostKeyChecking默认(别图省事=no),否则有中间人风险;内网可信环境才跳过。 - 超时与保活:长连接易断,
ServerAliveInterval 30+ServerAliveCountMax 3让客户端主动探活,避免"卡半小时才发现断了"。 - 权限三件套:
.ssh目录 700、authorized_keys600、私钥 600,任一过宽 sshd 会拒绝免密,这是"配了 key 还是让输密码"的头号原因。 - 排障先看
-v:连不上先ssh -v user@host,看卡在 DNS、认证还是转发,比瞎猜快。
本地经跳板连目标的转发模型:
ProxyJump让 ssh 自动串起多层,免密与通道一次配好长期受益。
相关命令
生成密钥用 ssh-keygen;传文件用 scp。
一句话总结
ssh = 加密远程登录,远不止登录:ssh host cmd 免交互执行、ssh-keygen+ssh-copy-id 配免密(注意远端 .ssh 权限)、ControlMaster 复用连接提速;最强的是端口转发——-L 本地映射远端、-R 远端映射本地、-D 建 SOCKS 代理(-f -N 后台纯隧道),这是访问内网与做代理的底层。掌握转发,ssh 才真正好用。