ssh 是什么
ssh 是 OpenSSH 的客户端,用于加密远程登录、远程执行与端口转发。给一个命令作为参数时,它是不带终端的非交互执行,退出码即远端命令的退出码,因此非常适合放进脚本与批量巡检;不加命令时进入交互 shell。理解「有没有分配终端」带来的差异,是避免权限、提示符与 sudo 类报错的关键。
基本信息
| 适用平台 | Linux、macOS、Windows 10+ 均自带 OpenSSH 客户端 |
|---|---|
| 命令语法 | ssh [选项] [user@]host [command] |
| 常用选项 | -p 端口、-i 指定私钥、-J 跳板主机、-t 强制分配终端、-o 传配置项(可多次)、-C 压缩、-N 不执行远程命令(配合转发)、-L/-R/-D 端口转发 |
| 配置文件 | ~/.ssh/config 支持主机别名与常用参数;/etc/ssh/ssh_config 是全局配置,/etc/ssh/sshd_config 是服务端配置 |
| 认证方式 | 默认优先公钥认证,其次口令;密钥指纹与 known_hosts 用于校验服务端身份 |
典型使用场景
- 日常登录:直接进入交互 shell,做排查与运维操作
- 远程执行单条或多条命令:一次连接拿到结果,适合批量巡检与自动化
- 跳板访问:-J 经堡垒机直达内网主机,不必手工两跳
- 端口转发:把远端数据库或内网服务映射到本地,供本地工具连接
- 文件传输:sftp、scp 的通道与认证完全复用 SSH 配置
- 固定主机别名:在 config 里写好主机、用户、端口与密钥,命令缩短成 ssh 别名
常用示例
常用示例
ssh ops@10.0.0.5
ssh ops@10.0.0.5 'uptime; df -h /'
ssh -J jump.example.com:22 ops@10.0.0.9 'systemctl is-active nginx'
ssh -i ~/.ssh/id_ed25519 -p 2222 ops@10.0.0.5
ssh -o ConnectTimeout=5 -o BatchMode=yes ops@10.0.0.5 'hostname' # 脚本友好
ssh -t ops@10.0.0.5 'sudo systemctl restart nginx' # 需要终端
ssh -L 13306:db.internal:3306 ops@jump # 本地端口转发
ssh -N -f -L 8080:10.0.0.9:80 ops@jump # 后台静默转发
ssh-keygen -t ed25519 -C 'ops@example.com' # 生成密钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub ops@10.0.0.5 # 分发公钥脚本常用选项
| 选项 | 作用 | 为什么需要 |
|---|---|---|
| BatchMode=yes | 禁止任何交互式提问 | 避免脚本卡在口令或确认提示上 |
| ConnectTimeout | 连接建立的超时秒数 | 防止不可达主机拖住整个流程 |
| StrictHostKeyChecking | 对未知主机密钥的处理策略 | 默认 ask 会交互;脚本里可设 accept-new 兼顾安全与自动化 |
| ServerAliveInterval | 定时发送保活包 | 避免 NAT 或防火墙切断空闲连接 |
| ControlMaster/ControlPath | 复用同一条底层连接 | 批量执行多条命令时显著加速 |
| IdentityFile | 指定私钥文件 | 替代 -i,便于写进 config |
~/.ssh/config 的写法:Host db 段里写 HostName、User、Port、IdentityFile、ProxyJump,之后直接 ssh db 即可。多台机器管理时,config 能消掉大量重复参数,也让密钥与跳板策略集中可查。
远程命令里的变量展开位置要明确:ssh host 'echo $HOME' 由远端 shell 展开,ssh host "echo $HOME" 会先被本地 shell 展开再发送。两种行为都有用途,但写脚本时必须想清楚哪一端该展开,否则会得到空值或错误路径。
不要为了让脚本跑通就关闭主机密钥校验(StrictHostKeyChecking=no 与 UserKnownHostsFile=/dev/null 的组合),这会让中间人攻击无法被发现。首次部署可临时使用 accept-new,稳定后应把已知主机指纹固化到 known_hosts 或集中分发。
批量巡检的写法:循环里对多台主机执行 ssh 时必须加 -o BatchMode=yes、-o ConnectTimeout=5,首次连接用 StrictHostKeyChecking=accept-new,再配合 ControlMaster 与 ControlPath 复用底层连接,可以把上百台主机的检查时间从分钟级压缩到秒级。规模继续变大就该上 Ansible 这类工具,而不是堆 shell 循环。
密钥文件权限有硬性要求:私钥必须是 0600,~/.ssh 建议 0700,权限过宽时 SSH 会拒绝使用该密钥并提示 UNPROTECTED PRIVATE KEY FILE。排查「为什么还要输口令」时用 ssh -v 看认证尝试顺序,比反复怀疑配置快得多。