SSH 跳板机详解
2026/3/20大约 8 分钟
SSH 跳板机详解
提示
跳板机(Jump Server / Bastion Host)是企业网络安全架构中的核心组件,它作为访问内网服务器的唯一入口,大幅提升了整体安全性。
什么是跳板机
基本概念
跳板机是一台专门用于中转 SSH 连接的服务器,所有对内网服务器的访问都必须先经过它。
跳板机的别名
- Jump Server:跳转服务器
- Bastion Host:堡垒主机
- Jump Box:跳转盒子
- 中转机 / 代理机
为什么需要跳板机
| 问题 | 无跳板机 | 有跳板机 |
|---|---|---|
| 攻击面 | 每台服务器都暴露公网 | 只有跳板机暴露公网 |
| 审计 | 难以追踪谁访问了哪台机器 | 所有访问都有统一入口日志 |
| 密钥管理 | 每台服务器都需要维护密钥 | 只需在跳板机维护 |
| 访问控制 | 分散管理,易出漏洞 | 统一策略,集中管理 |
| 安全加固 | 需要加固所有服务器 | 重点加固跳板机即可 |
跳板机架构设计
基础架构
企业级架构(高可用)
SSH 跳板机配置
场景说明
方式一:ProxyJump(推荐,OpenSSH 7.3+)
这是最简洁、最推荐的方式。
# ~/.ssh/config
# 跳板机配置
Host jump
HostName 1.2.3.4
Port 22
User deploy
IdentityFile ~/.ssh/id_ed25519
# 可选:保持连接
ServerAliveInterval 60
ServerAliveCountMax 3
# 内网服务器 - 使用通配符
Host internal-*
ProxyJump jump
User deploy
IdentityFile ~/.ssh/id_ed25519
# 具体内网服务器
Host internal-web-01
HostName 10.0.0.10
Host internal-web-02
HostName 10.0.0.11
Host internal-db-master
HostName 10.0.0.20
Host internal-db-slave
HostName 10.0.0.21
使用方式:
# 连接跳板机
ssh jump
# 直接连接内网服务器(自动通过跳板机)
ssh internal-web-01
ssh internal-db-master
# 命令行方式(不使用配置文件)
ssh -J deploy@1.2.3.4 deploy@10.0.0.10
方式二:ProxyCommand(兼容旧版本)
适用于 OpenSSH 7.3 以下版本。
# ~/.ssh/config
Host jump
HostName 1.2.3.4
User deploy
IdentityFile ~/.ssh/id_ed25519
Host internal-*
User deploy
IdentityFile ~/.ssh/id_ed25519
ProxyCommand ssh -W %h:%p jump
Host internal-web-01
HostName 10.0.0.10
方式三:多级跳板机
有时需要经过多个跳板机才能到达目标服务器。
# ~/.ssh/config
Host jump-a
HostName public-jump.company.com
User deploy
IdentityFile ~/.ssh/id_ed25519
Host jump-b
HostName 10.0.0.100
User deploy
IdentityFile ~/.ssh/id_ed25519
ProxyJump jump-a
Host internal-server
HostName 192.168.1.50
User deploy
IdentityFile ~/.ssh/id_ed25519
ProxyJump jump-b
# 或者直接指定多级跳转
Host deep-internal
HostName 192.168.1.50
User deploy
ProxyJump jump-a,jump-b
使用方式:
# 自动经过两级跳板机
ssh internal-server
# 命令行方式
ssh -J deploy@jump-a,deploy@10.0.0.100 deploy@192.168.1.50
跳板机服务端配置
跳板机安全加固
跳板机作为唯一入口,安全性至关重要。
# /etc/ssh/sshd_config.d/bastion.conf
# ========== 认证设置 ==========
# 只允许密钥认证
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
# ========== 访问控制 ==========
# 只允许跳板机用户组
AllowGroups bastion-users
# ========== 功能限制 ==========
# 允许 TCP 转发(跳板机必须开启)
AllowTcpForwarding yes
# 禁止 X11 转发
X11Forwarding no
# 禁止 Agent 转发(安全考虑)
AllowAgentForwarding no
# ========== 连接设置 ==========
# 超时设置
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
MaxAuthTries 3
# ========== 日志审计 ==========
# 详细日志
LogLevel VERBOSE
# ========== 限速保护 ==========
# 限制并发连接
MaxStartups 10:30:60
MaxSessions 10
跳板机用户管理
# 创建跳板机用户组
sudo groupadd bastion-users
# 添加用户到组
sudo usermod -aG bastion-users zhangsan
sudo usermod -aG bastion-users lisi
# 创建受限用户(只能跳转,不能执行命令)
sudo useradd -m -s /bin/rbash jumponly
sudo usermod -aG bastion-users jumponly
限制用户只能跳转
创建一个只能用于跳转的受限 shell:
# /etc/ssh/sshd_config.d/restricted-users.conf
# 特定用户只能做端口转发
Match User jumponly
ForceCommand echo "This account is only for jump access"
AllowTcpForwarding yes
X11Forwarding no
PermitTunnel no
GatewayPorts no
文件传输通过跳板机
SCP 传输
# 通过跳板机上传文件到内网服务器
scp -o ProxyJump=jump local-file.txt internal-web-01:/tmp/
# 通过跳板机下载文件
scp -o ProxyJump=jump internal-web-01:/var/log/app.log ./
# 使用配置文件(如果已配置 ProxyJump)
scp local-file.txt internal-web-01:/tmp/
SFTP 传输
# 通过跳板机启动 SFTP
sftp -o ProxyJump=jump internal-web-01
# 交互式操作
sftp> put local-file.txt /tmp/
sftp> get /var/log/app.log ./
sftp> ls
sftp> quit
Rsync 同步
# 通过跳板机同步目录
rsync -avz -e "ssh -J jump" ./local-dir/ internal-web-01:/data/remote-dir/
# 从内网服务器同步到本地
rsync -avz -e "ssh -J jump" internal-web-01:/data/backup/ ./local-backup/
端口转发通过跳板机
本地端口转发
访问内网服务(如数据库):
# 通过跳板机转发本地端口到内网数据库
ssh -J jump -L 3306:10.0.0.20:3306 internal-web-01 -N
# 然后本地连接
mysql -h 127.0.0.1 -P 3306 -u root -p
# 或者直接指定
ssh -J deploy@1.2.3.4 -L 3306:10.0.0.20:3306 deploy@10.0.0.10 -N
动态端口转发(SOCKS 代理)
# 创建 SOCKS5 代理,通过跳板机访问内网
ssh -J jump -D 1080 internal-web-01 -N
# 配置浏览器或应用使用 SOCKS5 代理
# 地址: 127.0.0.1
# 端口: 1080
SSH 配置文件中的端口转发
# ~/.ssh/config
Host internal-web-01
HostName 10.0.0.10
ProxyJump jump
# 自动建立本地端口转发
LocalForward 8080 localhost:80
LocalForward 3306 10.0.0.20:3306
常见问题排查
连接超时
# 问题:通过跳板机连接内网服务器超时
# 原因:跳板机无法连接内网服务器
# 排查步骤:
# 1. 先确认能连接跳板机
ssh jump
# 2. 在跳板机上测试连接内网服务器
ssh deploy@10.0.0.10
# 3. 检查内网服务器 SSH 服务
sudo systemctl status sshd
# 4. 检查防火墙规则
sudo iptables -L -n
sudo ufw status
权限被拒绝
# 问题:Permission denied (publickey)
# 原因:密钥问题
# 排查步骤:
# 1. 确认密钥权限
ls -la ~/.ssh/
chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh
# 2. 确认公钥已添加到目标服务器
# 跳板机的 authorized_keys
cat ~/.ssh/authorized_keys
# 3. 使用详细模式排查
ssh -vvv jump
ssh -vvv -J jump internal-web-01
Agent 转发问题
# 如果使用 Agent 转发(不推荐,有安全风险)
ssh -A jump
# 在跳板机上检查 Agent
ssh-add -l
# 更安全的替代方案:在每台机器上放置密钥
# 或使用 ProxyJump(不需要 Agent 转发)
连接中断
# 问题:连接空闲一段时间后断开
# 解决:配置心跳
# ~/.ssh/config
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
跳板机安全最佳实践
安全检查清单
审计日志
# 查看 SSH 登录日志
sudo tail -f /var/log/auth.log # Debian/Ubuntu
sudo tail -f /var/log/secure # CentOS/RHEL
# 查看当前登录用户
who
w
# 查看登录历史
last
lastlog
告警配置
# 登录告警脚本 /etc/ssh/login-notify.sh
#!/bin/bash
if [ "$PAM_TYPE" = "open_session" ]; then
SUBJECT="SSH Login: $PAM_USER@$(hostname)"
MESSAGE="User: $PAM_USER\nHost: $(hostname)\nTime: $(date)\nIP: $PAM_RHOST"
echo -e "$MESSAGE" | mail -s "$SUBJECT" admin@company.com
fi
# 添加到 PAM 配置 /etc/pam.d/sshd
session optional pam_exec.so /etc/ssh/login-notify.sh
与堡垒机的区别
| 特性 | SSH 跳板机 | 商业堡垒机 |
|---|---|---|
| 成本 | 免费 | 付费 |
| 审计 | 基础日志 | 完整会话录像 |
| 权限控制 | 系统级用户管理 | 细粒度权限控制 |
| 运维 | 需要自行维护 | 厂商支持 |
| 功能 | SSH 跳转 | 支持多协议 (RDP/VNC 等) |
| 适用场景 | 小团队/个人 | 中大型企业 |