文章列表
5 分钟阅读
更新于

SSH Config 使用指南:别名、跳板机与多服务器管理


系列:Linux 命令基础

第 16 / 16 篇

  1. Tmux 入门教程:让 SSH 断线和多任务终端不再中断
  2. Tree 命令教程:快速查看和导出目录结构
  3. Linux 搜索命令教程:find、grep、locate、rg 应该怎么选
  4. Linux 压缩与解压命令教程:tar、zip、gzip、xz、zstd 一次讲清
  5. Linux 文本处理命令教程:cat、less、head、tail、wc、sort、uniq
  6. Linux 权限命令教程:chmod、chown、umask
  7. Linux 进程查看与管理:ps、top、htop、kill、jobs
  8. Linux 网络排查命令:ss、curl、dig、ping、traceroute
  9. systemctl 与 journalctl 入门:管理服务和查看日志
  10. rsync 使用指南:服务器文件同步与备份
  11. Linux 服务器安全基础:SSH、用户权限、防火墙和 fail2ban
  12. 线上问题排查流程:日志、端口、进程、磁盘、网络怎么一步步看
  13. 深入浅出:Linux 树状目录神器 tree 命令的安装与使用指南
  14. Linux 系统 Vim 编辑器终极指南:从入门到精通
  15. SSH 隧道实战:本地转发、远程转发和动态转发
  16. SSH Config 使用指南:别名、跳板机与多服务器管理

为什么需要 SSH Config

管理多台服务器时,经常要记住不同的 IP、端口、用户名和密钥路径。每次登录敲类似 ssh -p 2222 -i ~/.ssh/keys/server.pem ubuntu@ec2-12-34-56-78.compute.amazonaws.com 这样一长串命令,不仅低效,还容易打错。

SSH 客户端的配置文件 ~/.ssh/config 可以为每台主机定义别名和连接参数,把上面的命令精简成 ssh myserver。它还支持跳板机(ProxyJump)、连接保活、会话复用等功能,这些在终端工作流中能省下大量时间。

本文基于 OpenSSH 客户端,介绍日常高频使用的配置指令和实际场景中的组合用法。

基本语法与核心指令

配置文件由若干个 Host 块组成,每个块定义一台或多台主机的连接参数。先看一个最简例子:

Terminal window
Host myserver
HostName 192.168.1.100
User deploy
Port 22
IdentityFile ~/.ssh/keys/deploy_rsa

保存后,在终端直接执行 ssh myserver 就等同于 ssh -i ~/.ssh/keys/deploy_rsa deploy@192.168.1.100 -p 22

常用指令说明:

指令作用示例
Host定义别名,可以是一个或多个模式Host dev prod-jump
HostName服务器真实地址(IP 或域名)HostName 10.0.0.5
User登录用户名User root
PortSSH 端口Port 2222
IdentityFile指定私钥路径IdentityFile ~/.ssh/id_ed25519

使用通配符管理批量服务器

如果有多台同类型服务器,例如三台开发机 dev-1、dev-2、dev-3,IP 地址在一个网段,可以用通配符一次性匹配:

Terminal window
Host dev-*
User developer
IdentityFile ~/.ssh/dev_rsa
Port 22
Host dev-1
HostName 192.168.1.101
Host dev-2
HostName 192.168.1.102
Host dev-3
HostName 192.168.1.103

此时执行 ssh dev-1 会匹配 dev-* 块继承公共参数,再用 dev-1 块中的 HostName 覆盖。通配符 *? 都可用,Host * 通常用于设置全局默认值:

Terminal window
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
ConnectTimeout 10

这样所有主机的连接都会每 60 秒发送一个心跳包,连续 3 次失败后断开,连接超时设为 10 秒。

通过 ProxyJump 配置跳板机

跳板机是访问内网服务器的常见入口。在 SSH Config 里可以直接用 ProxyJump 指令指定跳板机的别名或地址,语法为 ProxyJump user@jump-host:port

假设有跳板机 bastion 和内网目标机器 db-internal

Terminal window
Host bastion
HostName jump.example.com
User alice
Port 2222
Host db-internal
HostName 192.168.10.5
User postgres
ProxyJump bastion

执行 ssh db-internal 时,SSH 会先连接到 bastion,再通过它建立到 192.168.10.5 的连接。如果跳板机有多层,可以用逗号分隔多个跳板节点:

Terminal window
ProxyJump bastion1,bastion2

所有中间跳板机都会自动建立连接,无需手动链式登录。

跳板机的密钥也可以集中管理。如果跳板机和内网机器使用同一把密钥,只用在内网机器的配置里写 IdentityFile;如果用不同密钥,分别在各自的 Host 块里指定即可。更多跳板机配置参考 OpenSSH Cookbook - Proxies and Jump Hosts

连接复用与持久化

频繁打开和关闭 SSH 连接会产生不小的认证开销。ControlMasterControlPath 指令可以让多个 SSH 会话共享同一个 TCP 连接,大幅减少延迟。在全局配置中加入:

Terminal window
Host *
ControlMaster auto
ControlPath ~/.ssh/control/%C
ControlPersist 10m

参数含义:

  • ControlMaster auto:自动启用主连接,如果已存在则复用。
  • ControlPath ~/.ssh/control/%C:指定控制套接字文件路径,%C 是主机名、用户、端口的哈希值,保证唯一。
  • ControlPersist 10m:主连接在最后一次会话结束后保持 10 分钟,超时后自动关闭。

需要提前创建目录:

Terminal window
mkdir -p ~/.ssh/control

开启后,第二次连接同一台主机时,几乎瞬间进入终端。这对跳板机场景尤其有效,因为经过跳板机访问内网机器只需要保持一条主连接。

为隧道配置快捷指令

结合 SSH 隧道实战:本地转发、远程转发和动态转发 中提到的端口转发,可以在 SSH Config 里固化常用的隧道参数。例如需要经常把远程 MySQL 拉到本地的 3307 端口:

Terminal window
Host mysql-tunnel
HostName 192.168.1.10
User admin
LocalForward 3307 127.0.0.1:3306
IdentityFile ~/.ssh/mysql_admin_rsa

这样直接执行 ssh mysql-tunnel 就等价于 ssh -L 3307:127.0.0.1:3306 admin@192.168.1.10。也可以加上 -f -N 让隧道后台运行:

Terminal window
Host mysql-tunnel-bg
HostName 192.168.1.10
User admin
LocalForward 3307 127.0.0.1:3306
IdentityFile ~/.ssh/mysql_admin_rsa
ForkAfterAuthentication yes
SessionType none

不过简单做法通常是在命令行加 -fN 或将 ssh -fN 写入 systemd 服务,可根据场景选择。

常见问题

1. 配置文件不生效

检查几个常见原因:

  • 文件权限过于宽松。~/.ssh/config 必须为 600 或 644,否则 SSH 会忽略。执行 chmod 600 ~/.ssh/config
  • 文件中存在语法错误。可以用 ssh -G hostname 来检查指定主机的解析结果,如果报错会直接指出问题行。
  • 使用了 Tab 而非空格?两者都允许,但确认缩进统一。

2. IdentityFile 指定的密钥被跳过

可能是密钥权限不对。私钥文件权限必须是 600。此外确保公钥(.pub)已经添加到服务器的 ~/.ssh/authorized_keys 中。如果仍有问题,可以在命令中加 -v 查看认证过程。

3. 通配符规则不按预期匹配

SSH 配置文件的匹配是从文件顶部向下应用的,第一个匹配到的值生效,后续相同指令不会被覆盖。例如:

Terminal window
Host dev-*
User devuser
Port 2222
Host dev-1
HostName 10.0.0.1
Port 22 # 不起作用,因为 dev-1 也匹配 dev-* 的 Port 2222

解决方案是将更具体的 Host 块放在文件上方,或者使用 Match 关键字。另一个方法是确保通配符块只定义公共的、不需要被覆盖的选项,具体主机单独定义端口、HostName。

4. ProxyJump 连接失败,提示“Could not resolve hostname”

跳板机必须能解析内网主机名。如果内网机器没有 DNS 记录,应该在跳板机上配置其 /etc/hosts,或者在 Host 定义中直接使用 IP 地址 HostName 192.168.10.5。如果跳板机使用短主机名,确保跳板机可以解析。

5. 如何在配置中使用环境变量?

SSH Config 文件本身不直接支持环境变量,但可以通过 Match exec 结合外部命令实现简单条件。例如根据所在网络选择不同 ProxyJump:

Terminal window
Match exec "ping -c1 -W1 internal-gateway > /dev/null 2>&1"
ProxyJump none
Host *
ProxyJump external-bastion

这里不做深入,有兴趣可以查阅 OpenSSH 匹配块文档

总结

~/.ssh/config 把一个命令行参数映射成一个好记的别名,累积效应是终端日常工作里最直接的效率提升之一。核心习惯是:每新增一台服务器,就在 Config 里加一段,能用别名就不要手动拼 IP。结合跳板机、连接复用和自动保活,连接管理基本可以做到零负担。

如果需要跨团队共享连接配置,可以考虑将通用部分拆分为模板文件,通过 Include 指令引入(OpenSSH 7.3+ 支持),这样不同项目可以维护单独的配置片段而不互相污染。