SSH 配置文件有哪些常用选项?如何通过配置文件简化连接管理?
SSH 配置文件(~/.ssh/config 和 /etc/ssh/sshd_config)是管理和简化远程连接的核心工具。掌握常用选项后,可以将冗长的命令行参数转化为可复用的配置块,实现连接复用、跳板代理和端口转发等高级功能,大幅提升日常运维效率。
客户端配置文件(~/.ssh/config)
配置文件位置与优先级
SSH 客户端从三个来源读取配置,优先级从高到低:
- 命令行参数:如
ssh -p 2222 user@host,优先级最高 - 用户配置文件:
~/.ssh/config(最常用,日常管理的核心) - 全局配置文件:
/etc/ssh/ssh_config(系统管理员设置默认值)
三个来源的配置合并后生效,命令行参数覆盖用户配置,用户配置覆盖全局配置。注意:用户配置文件权限必须为 600,否则 SSH 会拒绝读取。
基本连接配置
bash# ~/.ssh/config # 最基本的主机配置 Host server1 HostName 192.168.1.100 User admin Port 2222 IdentityFile ~/.ssh/id_ed25519 # 使用别名简化连接 Host prod HostName prod.example.com User deploy IdentityFile ~/.ssh/prod_key
配置完成后,ssh prod 等价于 ssh -i ~/.ssh/prod_key deploy@prod.example.com,无需记忆每台服务器的连接参数。
通配符与批量配置
Host 指令支持通配符 * 和 ?,可以对一组主机应用相同配置:
bash# 对所有 example.com 主机使用相同用户和密钥 Host *.example.com User webadmin IdentityFile ~/.ssh/web_key # 对所有连接启用连接保持 Host * ServerAliveInterval 60 ServerAliveCountMax 3
关键细节:SSH 按配置文件中的顺序逐段匹配 Host,第一个匹配段中出现的选项生效,不会与后续段合并。因此通配符配置应放在文件末尾,避免被提前匹配覆盖。
连接复用(ControlMaster)
连接复用是 SSH 最实用的性能优化手段。首次连接建立 master 连接并创建 socket 文件,后续到同一主机的连接直接复用该通道,跳过认证和握手过程:
bashHost * ControlMaster auto ControlPath ~/.ssh/sockets/%r@%h-%p ControlPersist 600
各参数含义:
| 参数 | 说明 |
|---|---|
ControlMaster auto | 自动创建新连接或复用已有 master 连接 |
ControlPath | socket 文件路径,%r 远程用户名、%h 主机名、%p 端口 |
ControlPersist 600 | 最后一个会话关闭后,master 连接保持 600 秒 |
使用前需创建 socket 目录:mkdir -p ~/.ssh/sockets。管理命令:ssh -O exit hostname 关闭复用连接,ssh -O check hostname 查看复用状态。
跳板机配置
ProxyJump(推荐,OpenSSH 7.3+)
bashHost jump HostName jump.example.com User jumper IdentityFile ~/.ssh/jump_key Host internal HostName 10.0.0.50 User root ProxyJump jump
ProxyJump 语法简洁,支持多跳串联:ProxyJump jump1,jump2。命令行等价写法:ssh -J jump internal。
ProxyCommand(兼容旧版本)
bashHost internal HostName 10.0.0.50 User root ProxyCommand ssh -W %h:%p jump.example.com
核心区别:ProxyJump 是 ProxyCommand 的高层封装,底层都是通过跳板机建立到目标的 TCP 通道。两者互斥,不能同时配置。OpenSSH 7.3 以下只能用 ProxyCommand。
端口转发配置
SSH 支持三种端口转发,都可以写入配置文件持久化:
bash# 本地端口转发:将远程 Redis 映射到本地 Host db-tunnel HostName db.example.com User admin LocalForward 16379 127.0.0.1:6379 # 远程端口转发:将本地服务暴露到远程 Host expose-local HostName remote.example.com User admin RemoteForward 8080 127.0.0.1:3000 # 动态端口转发:SOCKS5 代理 Host socks-proxy HostName tunnel.example.com User admin DynamicForward 1080
三种转发的区别:
| 类型 | 配置项 | 数据流方向 | 典型场景 |
|---|---|---|---|
| 本地转发 | LocalForward | 本地 → 远程内网 | 访问远程数据库 |
| 远程转发 | RemoteForward | 远程 → 本地 | 将本地服务暴露给远程 |
| 动态转发 | DynamicForward | 本地 → 任意(SOCKS5) | 通过 SSH 安全代理上网 |
Include 指令与配置拆分
OpenSSH 7.3+ 支持 Include 指令,可将配置按项目或环境拆分为多个文件:
bash# ~/.ssh/config Include ~/.ssh/config.d/* # ~/.ssh/config.d/work Host prod-* User deploy IdentityFile ~/.ssh/work_key # ~/.ssh/config.d/personal Host github HostName github.com User git IdentityFile ~/.ssh/personal_key
这种方式便于按项目或环境管理配置,也方便脚本自动化生成。Include 可以出现在配置文件的任何位置,被包含的文件内容在该位置展开。
Token 替换
配置文件中的部分选项支持 Token 动态替换:
| Token | 含义 | 常见用途 |
|---|---|---|
%h | 远程主机名 | ControlPath、ProxyCommand |
%p | 远程端口号 | ControlPath、ProxyCommand |
%r | 远程用户名 | ControlPath |
%d | 本地用户家目录 | IdentityFile 路径 |
%u | 本地用户名 | 日志路径 |
其他常用选项
| 选项 | 默认值 | 说明 |
|---|---|---|
IdentitiesOnly yes | no | 只使用配置的密钥,防止 ssh-agent 干扰 |
Compression yes | no | 启用压缩,低带宽环境有效 |
StrictHostKeyChecking | ask | 主机密钥验证策略:ask/yes/no |
ForwardAgent yes | no | 转发认证代理,用于跳板机链式认证 |
ConnectTimeout 10 | 无 | 连接超时秒数 |
ServerAliveInterval 60 | 0 | 客户端心跳间隔,防止连接被防火墙断开 |
服务器端配置文件(/etc/ssh/sshd_config)
认证与安全加固
bash# /etc/ssh/sshd_config # 认证方式 PasswordAuthentication no # 禁用密码认证,只允许密钥登录 PubkeyAuthentication yes # 启用公钥认证 PermitRootLogin prohibit-password # 允许 root 但禁止密码登录 MaxAuthTries 3 # 限制单次连接认证尝试次数 # 访问控制(白名单优先) AllowUsers admin deploy # 只允许这些用户登录 AllowGroups ssh-users # 只允许这些组登录 DenyUsers test guest # 拒绝这些用户登录
PermitRootLogin prohibit-password 比 no 更灵活:允许 root 通过密钥登录但禁止密码,适合需要 root 权限的自动化脚本。
连接与性能
bashMaxStartups 10:30:100 # 未认证连接速率限制:10个开始拒绝30%,100个全部拒绝 LoginGraceTime 60 # 认证超时时间(秒) ClientAliveInterval 300 # 服务器端心跳间隔(秒) ClientAliveCountMax 2 # 心跳无响应次数上限
功能开关
bashX11Forwarding no # 禁用 X11 转发 AllowTcpForwarding yes # 允许 TCP 转发 GatewayPorts no # 禁止远程转发绑定非本地地址 PermitTunnel no # 禁用 tun 设备
Match 条件块
sshd_config 支持 Match 指令,按条件应用不同配置,实现精细化访问控制:
bash# 内网允许密码认证 Match Address 192.168.1.0/24 PasswordAuthentication yes # 特定用户允许端口转发 Match User deploy AllowTcpForwarding yes GatewayPorts clientspecified # 特定组禁用端口转发 Match Group restricted AllowTcpForwarding no
Match 支持的条件:User、Group、Host、Address,可组合使用。
常见面试追问
ProxyJump 和 ProxyCommand 有什么区别?
ProxyJump 是 ProxyCommand 的高层封装(OpenSSH 7.3+),语法更简洁。底层原理相同:都是通过跳板机建立到目标主机的 TCP 通道。ProxyJump 支持逗号分隔的多跳串联(ProxyJump j1,j2),而 ProxyCommand 实现多跳需要嵌套。两者互斥,不能同时配置。
ControlPath 中 %r %h %p 分别代表什么?
%r 是远程用户名,%h 是远程主机名,%p 是远程端口号。这三个 Token 组合可以确保到不同主机的连接使用不同的 socket 文件,避免复用冲突。
StrictHostKeyChecking 三个值有什么区别?
ask(默认)首次连接时提示确认主机指纹;yes 只允许 known_hosts 中已有的主机连接,未知主机直接拒绝;no 自动接受新主机密钥存入 known_hosts。生产环境建议 ask 或 yes,no 存在中间人攻击风险。
ClientAliveInterval 和 ServerAliveInterval 有什么区别?
两者都是心跳机制,但发起方和用途不同。ServerAliveInterval 由客户端定期发心跳给服务器,防止客户端侧连接被防火墙或 NAT 设备断开。ClientAliveInterval 由服务器定期发心跳给客户端,用于检测客户端是否存活并主动断开僵死连接。