SSH 进阶:密钥管理、多机配置、端口转发与文件传输
第一篇笔记里 SSH 只讲到「能连上」,这篇补上真正提升效率的部分:多机管理、转发、传文件。
一、密钥:用 ed25519,一把钥匙一台机
ssh-keygen -t ed25519 -C "baize@macbook"
# 一路回车即可,建议设置 passphrase(钥匙丢了还有一层保护)生成的是一对:id_ed25519(私钥,绝不外传)和 id_ed25519.pub(公钥,放到服务器上)。
把 passphrase 交给钥匙串管理,就不用每次输:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519 # macOS
ssh-add ~/.ssh/id_ed25519 # Linux(需先启动 ssh-agent)不要用同一个密钥给所有机器。至少按「用途」分开:个人服务器一把、公司一把、GitHub 一把。
二、ssh config:一次配置,终身省心
~/.ssh/config 是最值得花十分钟的配置文件:
# 通用设置放最上面
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Compression yes
AddKeysToAgent yes
# 主服务器
Host baize
HostName 1.2.3.4
Port 2222
User baize
IdentityFile ~/.ssh/id_ed25519
# 跳板机后面的内网机器
Host inner
HostName 10.0.0.5
User baize
ProxyJump baize配置完之后:
ssh baize # 代替 ssh -p 2222 baize@1.2.3.4
ssh inner # 自动跳板,一条命令进内网
scp ./a.txt baize:/tmp/三、端口转发:临时访问内网服务的救命招
三种转发,记住一句话就够:-L 把远程带到本地,-R 把本地带到远程,-D 是 socks 代理。
# 本地转发:把远程的 3306 映射到本机 13306
# 场景:数据库只监听 127.0.0.1,想在本地用 GUI 客户端连
ssh -L 13306:127.0.0.1:3306 baize -N -f
# 之后连 localhost:13306 就等于连服务器的 3306
# 远程转发:把本机的 3000 暴露到服务器的 8080
# 场景:本地开发要给别人演示 / 收 webhook
ssh -R 8080:127.0.0.1:3000 baize -N -f
# 动态转发:起一个 socks5 代理
ssh -D 1080 baize -N -f
# 浏览器配 socks5://127.0.0.1:1080,流量就走服务器出口参数说明:
| 参数 | 含义 |
|---|---|
-N | 不执行远程命令,只做转发 |
-f | 后台运行 |
-L | 本地转发 local:remote |
-R | 远程转发 |
-D | 动态代理 |
-R默认只绑定远程的 127.0.0.1。想让外网能访问,需要在服务器sshd_config里设GatewayPorts yes。
四、传文件:scp 简单,rsync 更聪明
# 单文件
scp -P 2222 ./site.zip baize@host:/tmp/
scp baize:/var/log/nginx/error.log ./
# 整个目录:优先用 rsync,只传差异,支持断点
rsync -avz --delete ./dist/ baize:/var/www/baize/rsync 常用参数:
| 参数 | 含义 |
|---|---|
-a | 归档模式,保留权限/时间/软链 |
-v | 显示过程 |
-z | 传输时压缩 |
--delete | 删除目标端多余的文件(先加 --dry-run 试跑) |
-P | 显示进度 + 支持断点续传 |
--exclude | 排除文件 |
# 先看会删什么,确认无误再真跑
rsync -avz --delete --dry-run ./dist/ baize:/var/www/baize/
# 排除 node_modules 和 .git
rsync -avz --exclude "node_modules" --exclude ".git" ./ baize:/srv/app/五、常见报错与解法
| 报错 | 原因与解法 |
|---|---|
Permission denied (publickey) | 公钥没放对 / 权限太开放:chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys |
WARNING: UNPROTECTED PRIVATE KEY FILE | 私钥权限不对,chmod 600 id_ed25519 |
Host key verification failed | 服务器重装过,删掉本地 ~/.ssh/known_hosts 里对应行 |
Too many authentication failures | 本地钥匙太多,ssh -o IdentitiesOnly=yes 指定一把 |
| 连上就断 | 加 ServerAliveInterval 60,或路由器 NAT 超时太短 |
# 删掉某个 host 的旧指纹
ssh-keygen -R 1.2.3.4
# 调试连接过程,卡在哪一步一目了然
ssh -vvv baize六、安全补充
- 服务器上禁用密码登录后,私钥就是唯一凭证,务必备份到加密的地方;
~/.ssh/config里可以给高危机器单独限制:IdentitiesOnly yes、ConnectTimeout 10;- 团队场景下用
~/.ssh/authorized_keys里加command=前缀限制该钥匙只能执行固定命令。
# 只允许 rsync,且限定目录(authorized_keys 里的一行)
command="rsync --server -vlogDtprz . /var/www/baize/" ssh-ed25519 AAAA...