应在net.listener.accept()后立即对conn进行认证拦截,通过setreaddeadline设超时、io.readfull读固定长度认证头、校验hmac与nonce防重放,认证失败即close连接,全程避免bufio.reader和协议解析混用,确保panic或超时时conn必关闭。

Go net.Conn 上怎么加认证拦截,不让未授权连接进入业务逻辑
认证必须在 conn.Read 处理业务数据前完成,否则攻击者可直接发恶意 payload 绕过校验。常见错误是把认证逻辑塞进 handler 函数里——那时连接已建立、资源已分配,再拒绝等于白忙。
- 用
net.Listener.Accept()后立刻读取固定长度的认证头(比如 16 字节 token 或 4 字节命令 + 12 字节签名) - 设置超时:
conn.SetReadDeadline(time.Now().Add(5 * time.Second)),防止客户端不发认证数据卡死 goroutine - 认证失败直接
conn.Close(),别 return 错误或继续往下走 - 避免在认证阶段解析完整协议帧——只读预期字节数,用
io.ReadFull(conn, buf)而非conn.Read
如何设计轻量但防重放的 TCP 认证协议(不用 TLS)
私有协议没法直接套 TLS,但裸 token 明文传就是送钥匙。核心矛盾:要快(不能每次连都查 DB),又要防截获重放。
- 客户端发:
timestamp(uint32) + nonce(uint32) + hmac-sha256(key, timestamp|nonce|ip),服务端校验时间戳 ±30 秒 + HMAC 是否匹配 +nonce是否已用过(用 LRU cache 存最近 1000 个) - key 不硬编码在代码里,从环境变量或文件读:
os.Getenv("AUTH_KEY"),启动时校验非空 - 别用
math/rand生成 nonce——用crypto/rand.Read(),否则 predictable - 时间戳用
uint32而非time.Now().Unix()全精度,减少对齐和序列化开销
为什么用 bufio.Reader 做认证后,后续协议解析会丢数据
认证时如果用了 bufio.NewReader(conn),又调了 reader.Peek() 或 reader.Discard(),底层 buffer 里的数据可能被提前消费,导致业务层 conn.Read() 读到残缺帧。
本文档主要讲述的是android rtsp流媒体播放介绍;实时流协议(RTSP)是应用级协议,控制实时数据的发送。RTSP提供了一个可扩展框架,使实时数据,如音频与视频,的受控、点播成为可能。数据源包括现场数据与存储在剪辑中数据。该协议目的在于控制多个数据发送连接,为选择发送通道,如UDP、组播UDP与TCP,提供途径,并为选择基于RTP上发送机制提供方法。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- 认证阶段坚持用原始
conn.Read()或io.ReadFull(),绕过任何缓冲层 - 认证成功后,再包一层
bufio.NewReader(conn)交给业务 handler —— 此时连接状态干净 - 如果协议本身有变长包头(如前 4 字节是 body length),认证完立刻用
binary.Read(conn, binary.BigEndian, &length)读长度,别混用 bufio 和 raw conn - 调试时打印
len(buf)和cap(buf),确认没意外读多
goroutine 泄漏:认证超时没关 conn,panic 没 recover 导致连接堆积
Go 的 net.Conn 不会自动回收,一个没 close 的连接会一直占着 fd 和 goroutine 栈内存。线上跑几天就 too many open files。
立即学习“go语言免费学习笔记(深入)”;
- 所有
Accept()得到的conn,必须在 defer 里确保conn.Close(),哪怕认证中途 panic - 用
defer func() { if r := recover(); r != nil { conn.Close() } }()包住认证逻辑 - 监听器启动用
http.Server那套优雅关闭思路不行——TCP server 得自己管,建议封装成 struct 带Shutdown()方法,遍历 active conns 关闭 - 用
lsof -i :port | wc -l定期核对连接数,和你代码里计数器比对,不一致说明有泄漏
认证逻辑越靠近连接入口越好,但 buffer 管理、超时控制、panic 恢复这三件事,漏掉任何一个,服务就不是“带认证”,而是“带幻觉认证”。









