Go标准库net/rpc本身不加密,必须通过TLS实现传输安全:服务端用tls.Listen加载证书并禁用旧协议,客户端用tls.Dial校验证书;推荐生产环境使用gRPC,其原生支持TLS、mTLS及拦截器统一认证。

Go 语言标准库的 net/rpc 本身不加密,必须靠 TLS 套在连接层实现传输安全。不加 TLS 的 RPC 调用等同于明文裸奔,任何中间节点都可读写、篡改请求和响应。
用 tls.Listen 替换 net.Listen 启动服务
这是最直接有效的加密入口。服务端不能继续用 net.Listen("tcp", ":1234"),而要加载证书后走 TLS 监听:
-
tls.LoadX509KeyPair("server.crt", "server.key")必须成功,路径错误或权限不足会导致 panic -
tls.Config中建议显式禁用老旧协议:设置MinVersion: tls.VersionTLS12 - 若需双向认证(mTLS),加上
ClientAuth: tls.RequireAndVerifyClientCert和ClientCAs字段 - 监听器传给
rpc.ServeListener,不是rpc.Accept—— 后者不支持自定义net.Conn封装
客户端用 tls.Dial 连接并校验证书
客户端不能用 net.Dial,否则会直连未加密通道。关键点在于证书验证逻辑:
- 生产环境必须设
&tls.Config{InsecureSkipVerify: false},且ServerName要与证书Subject.CommonName或DNSNames匹配 - 自签名证书测试时可临时设
InsecureSkipVerify: true,但代码里必须加明显注释并限制构建标签(如// +build dev) - 连接后需包装为
io.ReadWriteCloser,再传给rpc.NewClientWithCodec+jsonrpc.NewClientCodec(若用 JSON-RPC) - 忘记关闭
conn.Close()会导致 TLS 连接泄漏,尤其在短连接高频调用场景下
gRPC 比 net/rpc 更适合生产级安全需求
原生 net/rpc 的 TLS 支持是“能用”,但缺乏细粒度控制和生态支撑。gRPC 是更现实的选择:
立即学习“go语言免费学习笔记(深入)”;
- 服务端启用 TLS 只需一行:
grpc.Creds(credentials.NewServerTLSFromFile("server.crt", "server.key")) - 客户端校验服务端证书:
credentials.NewClientTLSFromFile("ca.crt", "example.com"),主机名检查自动生效 - 支持 mTLS:服务端加
credentials.NewServerTLSFromFile+ 客户端提供证书,服务端用credentials.NewClientTLSFromFile配合grpc.WithTransportCredentials - 拦截器(Interceptor)可统一注入 JWT 校验、日志、限流,不用在每个方法里重复写
if !validToken() { return ... }
证书管理最容易被忽略的三个细节
加密通道是否真安全,一半取决于代码,另一半取决于证书生命周期管理:
- 私钥文件权限必须是
0600,放在容器里时注意挂载方式(如secret卷而非 configmap) - 证书过期前 30 天必须触发告警;
tls.Config不会主动 reload,需重启服务或实现热更新逻辑 - 开发环境用自签名证书没问题,但 CI/CD 流水线中若出现
InsecureSkipVerify: true且未被dev构建标签隔离,等于埋雷


















