直接结论:你不需要改系统级配置,只需在 ~/.ssh/config 里写好 Host 段,ssh 命令就会自动读取并生效;该文件权限必须为600、属主为当前用户,且按从上到下首次匹配原则解析,支持别名、通配符和连接复用等高级功能。

直接结论:你不需要改系统级配置,只需在 ~/.ssh/config 里写好 Host 段,ssh 命令就会自动读取并生效。
为什么 ~/.ssh/config 是首选路径
OpenSSH 客户端默认按顺序查找配置文件:/etc/ssh/ssh_config → ~/.ssh/config。后者是用户私有配置,权限可控、不干扰他人、可覆盖全局设置。系统级配置(/etc/ssh/ssh_config)通常只用于统一策略(如强制禁用密码登录),日常个性化连接完全没必要碰它。
-
~/.ssh/config必须由当前用户拥有,且权限严格为600(即chmod 600 ~/.ssh/config),否则 OpenSSH 会直接忽略该文件 - 如果
~/.ssh目录不存在,先运行mkdir -p ~/.ssh && chmod 700 ~/.ssh,再创建 config - 文件内所有以
#开头或空行都会被跳过,适合加注释说明用途
Host 段怎么写才不被忽略
OpenSSH 匹配 Host 段是「从上到下、首次匹配即停」,不是「最精确匹配」。这意味着顺序和通配符位置直接影响行为。
- 明确主机别名优先:比如想给
192.168.5.22起名db-prod,就写Host db-prod,下面紧接HostName 192.168.5.22—— 不要写成Host 192.168.5.22,否则你得每次输入 IP 才能触发 - 通配符
*必须放在段末尾:写Host *.example.com可以匹配web.example.com和api.example.com;但Host example.*不匹配任何常见域名格式(DNS 不支持后缀通配) - 多个 Host 名可用空格分隔:
Host prod staging表示这两串命令都走同一组参数 - 一旦某 Host 段匹配成功,后续同名选项不会被覆盖,但未定义的选项会继续继承
Host *段里的值
常见错误:连得上但反复输密码
这几乎全是权限或路径问题,跟密钥本身关系不大。
- 检查
IdentityFile路径是否写错:必须是绝对路径,比如IdentityFile ~/.ssh/id_ed25519,不能写./id_ed25519或漏掉~ - 确认私钥文件权限是
600:chmod 600 ~/.ssh/id_ed25519,OpenSSH 遇到宽松权限(如 644)会静默拒绝使用 - 如果用了
ProxyJump或ProxyCommand,确保跳板机(bastion)上的用户也有对应公钥,并且authorized_keys文件权限是600、所在目录是700 - 临时验证是否走对配置:加
-v参数看调试输出,搜索debug1: Reading configuration data和debug1: Connecting to两行,确认加载的 config 路径和最终解析出的 HostName/Port/User 是否符合预期
ControlMaster 复用连接的实际效果
开启连接复用后,首次 ssh db-prod 会建立控制连接并保持后台进程;后续同目标的 ssh db-prod、scp file db-prod:/tmp/、rsync -e "ssh" local/ db-prod:/data/ 全部复用该 TCP 连接,省去密钥交换和认证开销。
- 必须配三要素:
ControlMaster auto、ControlPath ~/.ssh/sockets/%r@%h:%p(%r是用户名,%h是 HostName,%p是端口)、ControlPersist 600(单位秒,设为yes表示长期驻留) -
ControlPath路径中的目录(如~/.ssh/sockets)需提前mkdir -p并设为700,否则连接失败且错误提示极不明显 - 手动清理残留套接字:
ssh -O exit db-prod(注意是大写 O),不要直接删文件,否则可能留下僵尸连接
真正容易被忽略的是 ControlPath 的路径稳定性 —— 如果你把 %h 换成 %n(即命令行输入的 host 名),而 config 里又用了别名,那复用就失效了;还有人把 ControlPersist 设成 10 秒,结果刚切个终端回来连接就断了。这些细节不试一次根本意识不到。


















