The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
UG4anS3JspYD

写了个 Go 库:在 TCP 应用协议开始前做认证,也支持端口敲门

  •  
  •   UG4anS3JspYD · 17h 40m ago · 952 views

    最近整理了一个 Go 库,叫 libknock 。

    它解决的问题比较窄: 有些 TCP 服务不太想让随机连接直接打到应用协议解析层,比如内部管理端口、agent/collector 、私有 RPC 、gRPC 服务、自定义 TCP 协议之类。

    传统做法一般是:

    • 直接暴露 TCP 端口,让 TLS / HTTP / gRPC / 业务协议自己处理
    • 前面再套一层 proxy / gateway
    • 靠防火墙、VPN 、内网环境隔离
    • 或者用 port knocking 临时放行来源 IP

    libknock 的思路是把这类能力做成 Go 里的底层网络库,放在 net.Listener / net.Dialer 这一层。

    服务端大概是:

    ln, _ := net.Listen("tcp", ":9000")
    ln = libknock.WrapListener(ln, knockCfg)
    
    for {
        conn, err := ln.Accept()
        if err != nil {
            return err
        }
    
        go handleConn(conn)
    }
    

    客户端大概是:

    d := libknock.Dialer{
        Base: &net.Dialer{},
        Config: knockCfg,
    }
    
    conn, err := d.DialContext(ctx, "tcp", "example.com:9000")
    

    连接建立后,客户端先发一个 binary auth frame 。服务端验证 client secret 、timestamp 、nonce 、replay cache ,通过以后才把一个干净的 net.Conn 交给上层程序。

    也就是说,上层协议不用知道 libknock 存在。 如果后面是 TLS ,TLS 看到的还是正常 ClientHello ;如果后面是自定义 TCP 协议,业务 handler 看到的就是自己的业务首包。

    除了 TCP 前置认证,也可以组合 port knocking / firewall gate:

    client
      -> knock
      -> temporary allow / session
      -> TCP connect
      -> TCP pre-auth
      -> application protocol
    

    不过它不是传统意义上的“端口敲门工具”。port knocking 只是可选的一层 gate ;核心还是 Go 程序可嵌入的 TCP pre-application authentication SDK 。

    主要特性:

    • Go 原生 net.Listener / net.Dialer 包装
    • TCP 建连后、应用协议开始前认证
    • binary auth frame
    • client secret 校验
    • timestamp window
    • nonce replay 防护
    • 认证失败默认直接关闭连接
    • 不解析、不修改上层应用协议
    • 可用于普通 TCP 、自定义二进制协议、TLS 、HTTP 、gRPC
    • 可选 port knocking / firewall gate / relay gateway

    适合的场景大概是:

    • 内部管理端口
    • agent / collector 长连接
    • 私有 RPC / gRPC 服务
    • 自定义 TCP 协议
    • 数据采集、边缘节点、运维控制面
    • 不想让应用协议解析器直接面对随机 TCP 输入的服务

    不适合的场景:

    • 想要开箱即用保护任意未改造二进制程序,这种更适合 relay/gateway
    • 想替代 TLS / mTLS / 业务鉴权
    • 想做 VPN 或完整隧道
    • 只想要一个传统 knockd 替代品

    现在还在早期阶段,主要想看看有没有人对这种“TCP pre-application authentication + optional port knocking”的组合有类似需求。

    仓库地址: https://github.com/libknock/libknock

    欢迎拍砖,尤其是 Go API 设计、net.Conn 包装方式、port knocking 和 TCP auth 的边界、安全默认值这几块。

    4 replies    2026-05-19 10:23:14 +08:00
    povsister
        1
    povsister  
       17h 23m ago via iPhone
    我们在生产环境遇到过有 bug 应用创建 slow tcp 和半开连接,导致目标应用 oom 。所以有没有什么能在 ip 层防御的,不进协议栈的那种
    lesismal
        2
    lesismal  
       16h 7m ago
    我之前有写个自己用着玩的,如果只是简单的握手、tcp 连接后先发个密码、校验就可以了,但是后续流量防不住流量监控、如果流量加密则不需要刚开始的握手阶段密码校验了,所以只做了加密,但是支持用户自己传入 Listen 、Dial:
    https://github.com/lesismal/pipe

    另外,握手阶段简单密码校验,前阵子刚好有这个需求,懒得自己写,发给 AI ,AI 几分钟就完整实现了一层 wrapper ,几十行代码,并且一把过:
    https://gist.github.com/lesismal/2f7f1fbec4c73282f19124b2cb6c1254
    lesismal
        3
    lesismal  
       15h 53m ago
    AI 太强了,去年中 sonnet 4.0 还是 4.1 之后,我就基本放弃自己手写了、但去年还偶尔自己写一点点。

    之前觉得 golang 如果用标准库 sql 要手写很多 for 循环,根据 sql 语句生成 golang 代码的库涉及到复杂业务逻辑中间夹杂很多 sql 的,修改之类的也是很麻烦,sqlx 、ent 以及那几个 orm 库过于啰嗦而且很多没必要的东西增加学习成本而且性能、隐藏细节带来的工程问题远大于 orm 之类的所谓便利性,即使其他语言我也是抵制使用 orm 这类脏东西的(小项目谁爱用都 ok ,因为没有瓶颈)。
    其实标准库 sql 包主要就是需要手写 for 循环 rows scan 这块麻烦,binding 搞好就轻松的多,所以自己搞了个 https://github.com/lesismal/sqlw ,以前自己用这个。

    但是 AI 来了,AI 不怕手写 for rows scan 这些的麻烦,所以现在我连自己的 sqlw 都不用了,全丢给 AI ,代码我也不 review ,让 AI 自己加适当的日志、监控各种,然后让 AI 自己分析慢日志之类的进行优化。剩下的就是自己测试一些不容易被 AI 自动化发现的问题、然后反馈给 AI 让它修复和优化。

    最近一些人吐槽 bun 换 rust ,infoq 文章评论区里,infoq 的人竟然还用 viber coding 之前的方式去评价不可能那么快合并到主分支——这相当于九品芝麻官里李总管那句“你用前朝的尚方宝剑斩本朝的官”,结果第二天就合并了。

    反正,我大概至少 8 、9 个月没有自己写过代码了。因为会聪明反被聪明误、自己觉得自己行非要瞎鼓捣然后耽误自己使用 AI 进步速度、也耽误自己和 AI 的配合度。

    让 AI 飞吧。
    zuokanyunqishi
        4
    zuokanyunqishi  
       2h 32m ago
    古法编程,一去不回头啦...
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3440 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 106ms · UTC 04:55 · PVG 12:55 · LAX 21:55 · JFK 00:55
    ♥ Do have faith in what you're doing.