RPC 调用涉及网络传输,安全性是必须考虑的重要问题。以下是 RPC 安全性的关键方面和实现方法:
1. 身份认证(Authentication)
Token 认证
- 客户端在请求中携带 Token
- 服务端验证 Token 有效性
- Token 可以是 JWT、OAuth2 等
- 实现示例:
java
// gRPC 拦截器实现 Token 认证 public class AuthInterceptor implements ServerInterceptor { @Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall( ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) { String token = headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER)); if (!validateToken(token)) { call.close(Status.UNAUTHENTICATED.withDescription("Invalid token"), headers); return new ServerCall.Listener<ReqT>() {}; } return next.startCall(call, headers); } }
API Key 认证
- 为每个客户端分配唯一的 API Key
- 简单但安全性相对较低
- 适合内部服务调用
双向 TLS(mTLS)
- 客户端和服务端都验证对方证书
- 提供强身份认证
- 适用于高安全要求的场景
2. 数据加密(Encryption)
传输层加密
- TLS/SSL:加密整个通信通道
- HTTPS:基于 HTTP 的 RPC 使用 HTTPS
- gRPC over TLS:gRPC 支持 TLS 加密
- 实现示例:
java
// gRPC TLS 配置 NettyChannelBuilder.forAddress(host, port) .sslContext(GrpcSslContexts.forClient() .trustManager(new File("ca.pem")) .build()) .build();
应用层加密
- 对敏感数据进行额外加密
- 使用 AES、RSA 等加密算法
- 即使传输层被破解,数据仍然安全
3. 授权(Authorization)
基于角色的访问控制(RBAC)
- 为用户分配角色
- 角色关联权限
- 检查用户是否有权限调用特定服务
基于资源的访问控制
- 细粒度控制对资源的访问
- 可以控制到方法级别
权限注解
- 使用注解标记需要权限的方法
- 拦截器统一处理权限检查
4. 防重放攻击
时间戳验证
- 请求中包含时间戳
- 服务端验证时间戳是否在有效范围内
- 防止旧请求被重放
Nonce 机制
- 每次请求使用唯一的随机数
- 服务端记录已使用的 Nonce
- 防止相同请求被重复使用
请求签名
- 对请求参数进行签名
- 签名包含时间戳和 Nonce
- 服务端验证签名有效性
5. 防止 DDoS 攻击
限流
- 限制单个客户端的请求频率
- 使用令牌桶、漏桶等算法
- 实现示例:
java
// Guava RateLimiter RateLimiter rateLimiter = RateLimiter.create(100); // 100 QPS if (rateLimiter.tryAcquire()) { // 处理请求 } else { throw new RateLimitExceededException(); }
黑名单/白名单
- 拦截来自黑名单 IP 的请求
- 只允许白名单 IP 访问
验证码
- 对可疑请求要求验证码
- 防止自动化攻击
6. 数据完整性
消息认证码(MAC)
- 使用 HMAC 等算法验证消息完整性
- 防止数据在传输中被篡改
数字签名
- 使用私钥签名,公钥验证
- 提供不可抵赖性
7. 安全审计
日志记录
- 记录所有 RPC 调用
- 包括调用者、时间、参数等
- 便于事后审计和问题排查
监控告警
- 监控异常调用模式
- 及时发现安全威胁
8. 安全配置最佳实践
最小权限原则
- 只授予必要的权限
- 定期审查权限配置
定期更新证书
- 及时更新过期的证书
- 使用证书自动管理工具
安全配置检查
- 定期进行安全扫描
- 使用安全配置检查工具
敏感信息保护
- 不在日志中记录敏感信息
- 使用配置中心管理密钥
- 定期轮换密钥
9. 框架特定安全配置
gRPC 安全
- 启用 TLS
- 使用拦截器实现认证和授权
- 配置 ALTS(Application Layer Transport Security)
Dubbo 安全
- 配置 Token 认证
- 使用 Dubbo Filter 实现安全检查
- 支持自定义序列化协议加密
Thrift 安全
- 使用 TSSLTransport
- 实现 TProcessor 拦截器
- 自定义协议层加密