一、前言
很多人学习堡垒机,只知道堡垒机是跳板机,但是最核心的"二传手"模型理解不到位。
堡垒机本质不是让你登录到堡垒机shell,再手动ssh连后端服务器(传统跳板模式);现代堡垒机核心是协议代理(二传手):用户的命令发给堡垒机,堡垒机把命令转发给后端目标资产;目标资产输出返回堡垒机,堡垒机再回传给用户。堡垒机充当中间的"二传手",用户和后端服务器之间永远没有直接TCP连接,流量全部经过堡垒机中转、解析、审计。
二传手比喻:
用户把球(指令)传给堡垒机(二传手),堡垒机收到球,校验、记录,再传给目标服务器;服务器回球(输出),再经由堡垒机传回用户。整个过程,用户和目标服务器不直接传球。堡垒机在中间接收、转发、监控,这就是堡垒机的代理二传模型。
传统跳板机:两次独立SSH连接,用户登录跳板机操作系统,再在跳板机上执行ssh连接内网机器。跳板机只是一台中间主机,没有解析协议流量,无法细粒度审计命令。
堡垒机二传手代理模式:应用层代理,解析SSH协议流,流量双向转发;可以实时捕获键盘输入、拦截高危命令、全程录屏审计,这是二者最本质区别。
二、堡垒机二传手架构原理
2.1 网络拓扑
plaintext
运维客户端 ↔【堡垒机(二传手代理层)】 ↔ 内网目标服务器
- 内网服务器不对外开放公网端口,仅允许堡垒机IP访问22端口
- 运维客户端只能访问堡垒机,无法直连内网资产
- 堡垒机作为二传手,维护两条独立连接:
- 连接A:客户端 ↔ 堡垒机
- 连接B:堡垒机 ↔ 目标内网服务器
两个连接互相独立,堡垒机负责把连接A的数据拷贝转发到连接B;连接B的输出拷贝转发回连接A,同时在转发过程中抓包、审计、高危命令拦截。
2.2 二传手完整工作流程
- 身份认证:客户端连接堡垒机,堡垒机校验账号、MFA,确认用户身份。
- 权限校验:查询该用户是否有权访问目标服务器,允许的操作范围。无权限直接拒绝连接。
- 建立后端连接(二传手准备):堡垒机主动发起SSH连接到内网目标服务器(使用托管的资产账号密码,用户无需知道后端服务器密码)。
- 双向流量转发(核心二传阶段)
- 用户输入指令 → 发给堡垒机
- 堡垒机(二传手)读取数据,记录命令日志,匹配高危命令规则(如rm -rf、drop table),命中则阻断
- 校验通过后,堡垒机将指令转发给内网服务器
- 内网服务器执行完成,输出结果返回堡垒机
- 堡垒机记录输出日志,再把结果转发回运维客户端
- 会话结束:任意一方断开连接,堡垒机关闭两条连接,保存完整会话录像与审计日志,用于事后追溯。
2.3 二传手代理 vs 老式跳板机(面试重点)
模式 工作方式 能不能解析命令 审计能力
老式跳板机 两次独立SSH,用户登录跳板操作系统 不能,流量透传,跳板只是TCP转发 只能记录登录跳板的日志,无法审计后端命令
堡垒机二传手代理 堡垒机作为协议代理,中间转发双向流量 可以解析SSH应用层协议 实时命令审计、高危阻断、会话录屏、文件传输审计
关键点:跳板机是"通道";堡垒机二传手是会看懂数据包内容的中间人,不是单纯的TCP管道。
三、简易模拟实现(Go语言,最小二传手模型)
说明:代码仅演示二传手双向转发核心逻辑,不含完善认证、权限、命令审计;生产级堡垒机(JumpServer)在此基础上增加4A能力。
go
package main
import (
"io"
"log"
"net"
)
// 二传手转发函数:双向拷贝数据
func proxyPipe(in io.ReadWriter, out io.ReadWriter, name string) {
go func() {
buf := make(\[\]byte, 1024)
for {
n, err := in.Read(buf)
if err != nil {
log.Printf("%s read closed: %v", name, err)
return
}
log.Printf("%s 捕获流量:%s", name, string(buf:n))
_, err = out.Write(buf:n)
if err != nil {
log.Printf("%s write error: %v", name, err)
return
}
}
}()
}
func handleClient(conn net.Conn) {
defer conn.Close()
log.Println("新客户端接入")
// ========== 二传手:堡垒机主动连接后端目标服务器 ==========
targetAddr := "192.168.1.100:22" //内网目标服务器
config := &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{
ssh.Password("123456"), //资产托管密码,用户不知道
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
targetClient, err := ssh.Dial("tcp", targetAddr, config)
if err != nil {
log.Println("连接后端资产失败:", err)
return
}
defer targetClient.Close()
session, err := targetClient.NewSession()
if err != nil {
log.Println("创建session失败:", err)
return
}
defer session.Close()
// 开启终端
modes := ssh.TerminalModes{
ssh.ECHO: 1,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
}
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
log.Println("请求pty失败", err)
return
}
stdin, _ := session.StdinPipe()
stdout, _ := session.StdoutPipe()
stderr, _ := session.StderrPipe()
if err := session.Shell(); err != nil {
log.Println("start shell err", err)
return
}
//===== 二传手双向转发核心:客户端 <-> 后端服务器 =====
proxyPipe(conn, stdin, "客户端→后端")
proxyPipe(stdout, conn, "后端→客户端")
proxyPipe(stderr, conn, "后端错误输出")
// 阻塞等待会话结束
_ = session.Wait()
log.Println("会话结束")
}
func main() {
listener, err := net.Listen("tcp", "0.0.0.0:2222")
if err != nil {
log.Fatal("监听失败", err)
}
log.Println("堡垒机二传手代理启动,监听 :2222")
for {
conn, err := listener.Accept()
if err != nil {
continue
}
go handleClient(conn)
}
}
代码解读(二传手核心)
- proxyPipe 就是二传手转发函数:一边读、一边写,双向搬运流量;并且打印捕获到的数据,模拟审计。
- 客户端连接堡垒机2222端口;堡垒机内部主动去连接内网目标服务器。
- 两条独立IO流,堡垒机在中间转发,客户端永远拿不到后端服务器账号密码。
- 在 proxyPipe 函数里,我们可以增加规则匹配:检测 rm -rf / 、 truncate 等高危命令,直接阻断写入,实现事中控制。
缺陷:demo仅演示二传转发逻辑,缺少:RBAC权限、MFA认证、会话录像、命令黑白名单、密码自动轮换、日志持久化。生产堡垒机JumpServer、Teleport就是在这个二传代理模型之上完善4A体系。
四、堡垒机二传手模型的安全价值
- 资产凭据托管:运维人员不需要知道内网服务器账号密码,堡垒机二传手代持密码,密码自动轮换,减少泄露风险。
- 切断直连链路:内网服务器不暴露公网,所有访问入口收敛到堡垒机单点。
- 事中实时控制:二传手在转发命令时解析内容,可以实时拦截高危操作,不是只能事后看日志。
- 完整审计追溯:所有输入输出全部经过二传手,可以完整记录、录屏,满足等保2.0运维审计要求。
五、常见误区
误区1:堡垒机=跳板机
跳板机只是两次ssh跳转,没有二传手代理。现代堡垒机核心就是协议代理二传手模型,流量经过堡垒机解析,不是单纯TCP透传。
误区2:堡垒机是中转TCP管道
普通TCP端口转发只是把字节流原样搬运,看不懂内容。堡垒机二传手是应用层协议代理,能读懂SSH协议里的命令字符,这是本质区别。
六、总结
堡垒机最核心思想就是二传手代理模型:堡垒机作为中间人,维护两条独立连接,双向转发客户端与目标资产之间的SSH流量,同时解析流量、权限校验、审计、阻断高危操作。
这个模型,也是JumpServer开源堡垒机底层核心原理。
本文的极简Go代码,剥离了复杂4A模块,只保留二传手转发逻辑,方便理解底层原理。
后续可以扩展:增加命令黑名单阻断、会话录像存储、RDP协议代理、数据库MySQL协议代理。
博主:网络安全开发
标签:#堡垒机 #JumpServer #二传手 #协议代理 #Go实战 #运维