
企业运维最怕两件事:权限失控和操作无痕。 一台生产服务器,如果谁都能直连,出了事故根本查不到人;如果每次操作都要审批,效率又会被拖垮。堡垒机的价值,就是在“安全”和“效率”之间架一座桥:统一入口、身份认证、权限控制、全程审计。
Go 语言天生适合做这件事:高并发、网络编程强、编译后单二进制部署,没有虚拟机包袱。下面我们用少量代码,搭一个最小 SSH 审计网关的骨架,理解堡垒机的核心链路。
一个能进企业采购清单的堡垒机,通常包含:
但所有复杂能力,都建立在一条最基础的链路上:用户连堡垒机 → 堡垒机认证 → 堡垒机连目标 → 执行操作 → 记录审计。
下面代码用 golang.org/x/crypto/ssh 实现一个简化版堡垒机。它接受客户端 SSH 连接,认证后把 exec 命令转发到目标服务器,并记录命令。删去了错误处理和完整会话支持,只为展示核心逻辑。
package main
import (
"fmt"
"log"
"net"
"os"
"golang.org/x/crypto/ssh"
)
func main() {
// 1. 读取目标服务器私钥,用于堡垒机免密登录目标
key, _ := os.ReadFile("/root/.ssh/id_rsa")
signer, _ := ssh.ParsePrivateKey(key)
// 2. 读取堡垒机自身 HostKey
hostKey, _ := os.ReadFile("/etc/ssh/ssh_host_rsa_key")
hk, _ := ssh.ParsePrivateKey(hostKey)
config := &ssh.ServerConfig{
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
if c.User() == "admin" && string(pass) == "secret" {
return nil, nil
}
return nil, fmt.Errorf("认证失败")
},
}
config.AddHostKey(hk)
// 3. 监听堡垒机端口
ln, _ := net.Listen("tcp", ":2222")
log.Println("堡垒机监听 :2222")
for {
conn, _ := ln.Accept()
go handle(conn, config, signer)
}
}
func handle(conn net.Conn, config *ssh.ServerConfig, signer ssh.Signer) {
defer conn.Close()
sshConn, chans, reqs, err := ssh.NewServerConn(conn, config)
if err != nil {
return
}
defer sshConn.Close()
go ssh.DiscardRequests(reqs)
// 4. 连接目标服务器
target, err := ssh.Dial("tcp", "10.0.0.10:22", &ssh.ClientConfig{
User: "root",
Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
})
if err != nil {
log.Println("目标连接失败:", err)
return
}
defer target.Close()
// 5. 处理会话,记录命令并转发
for newChan := range chans {
if newChan.ChannelType() != "session" {
newChan.Reject(ssh.UnknownChannelType, "仅支持 session")
continue
}
ch, requests, _ := newChan.Accept()
go func() {
for req := range requests {
if req.Type == "exec" {
cmd := string(req.Payload[4:])
log.Printf("[审计] 用户=%s 命令=%s", sshConn.User(), cmd)
session, _ := target.NewSession()
out, _ := session.CombinedOutput(cmd)
ch.Write(out)
ch.SendRequest("exit-status", false, ssh.Marshal(struct{ Status uint32 }{0}))
ch.Close()
session.Close()
}
}
}()
}
}运行方式:
go mod init bastion
go get golang.org/x/crypto/ssh
go run main.go然后客户端连接:
ssh -p 2222 admin@127.0.0.1 "whoami"堡垒机日志会记录:
[审计] 用户=admin 命令=whoami这个 Demo 很粗糙,但它把堡垒机最核心的“代理 + 审计”跑通了。
上面的代码只能算玩具,离企业级堡垒机还有巨大差距:
rm -rf、DROP TABLE 等高危操作。真正企业级堡垒机,代码量远不止几十行。但所有复杂系统,都是从这条最小链路长出来的。
Go 做企业级堡垒机,优势不在“代码少”,而在“部署快、并发强、易维护”。 上面这几十行,不是让你直接上线,而是帮你理解堡垒机的骨架:认证、代理、审计。 把这条链路跑通,再逐步叠加权限、录像、审批、高可用,才是一条务实的工程路径。
安全无小事,堡垒机尤其如此。示例代码仅用于学习,生产环境请使用成熟方案或经过严格安全评审。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。