别让无服务器变成无防备:AWS Lambda与API Gateway安全实战指南

loong
2026-01-05 / 0 评论 / 17 阅读 / 正在检测是否收录...

别让无服务器变成无防备:AWS Lambda与API Gateway安全实战指南

上周,一个朋友半夜给我打电话,声音里透着疲惫和焦虑。他的一个Serverless应用被扫出了漏洞,虽然没造成数据泄露,但安全团队的红灯已经亮起。他问我:“我都用Lambda了,不用管服务器了,怎么安全问题反而更复杂了?”

说实话,这不是我第一次听到这样的困惑。当我们把基础设施交给AWS时,安全的责任并没有消失,它只是转移了。从“保护服务器”变成了“保护代码、配置和权限”。

权限,权限,还是权限:IAM角色的最小化原则

这是Serverless安全最核心,也最容易出错的地方。

我见过太多Lambda函数挂着一个AdministratorAccess策略就上线了,因为“省事”。这等于把城堡的钥匙挂在城门上。

正确的做法是什么?

从零开始构建权限。你的Lambda函数需要读写DynamoDB的某个表?那就只给它这个表的读写权限,精确到ARN。需要调用另一个Lambda?那就只给lambda:InvokeFunction权限,并且指定目标函数的ARN。

AWS提供了很好的工具来帮你:

  • IAM策略模拟器:在部署前测试你的策略是否真的只做了你想做的事。
  • 服务控制策略(SCP):在组织层面设置护栏,禁止任何人(包括管理员)给函数赋予某些高危权限。

记住一个原则:如果某个权限不是函数启动和运行所绝对必需的,就不要给。

API Gateway:你的前门,别敞开着

API Gateway是流量入口,这里配置不当,攻击者就能长驱直入。

1. 认证与授权别偷懒

千万别再用那种“我在Lambda函数里自己检查API Key”的老办法了。API Gateway原生支持多种授权方式:

  • IAM授权:最适合AWS服务间的内部调用,利用IAM策略进行精细控制。
  • Cognito用户池:为终端用户提供完整的注册、登录、令牌管理。
  • Lambda授权方:最灵活,你可以写一段自定义的Lambda函数来处理JWT、自定义令牌或任何奇怪的鉴权逻辑。

关键是,让授权在请求到达你的业务逻辑Lambda之前就发生。无效的请求直接被API Gateway挡掉,既安全又省钱(Lambda不执行)。

2. 别忽视基础防护

  • 启用AWS WAF:给API Gateway挂上Web应用防火墙。设置一些简单的速率限制规则,就能挡住大部分粗暴的爬虫和DDoS试探。
  • 使用使用计划(Usage Plans)和API Keys:对第三方消费者进行配额和限流管理。
  • 配置合理的CORS:不要用*。明确列出允许的来源域名。

依赖与运行时:看不见的威胁

你的代码很干净,但你的依赖呢?

Lambda运行时会加载你部署包里的所有库。一个带有已知漏洞的lodashrequests版本,就可能成为突破口。

把它变成自动化流程:

  1. 在CI/CD流水线中集成依赖检查工具(如npm audit, snyk, dependabot)。
  2. 只部署通过了安全检查的构建包。
  3. 定期扫描已经部署在Lambda上的函数层(Layer)和容器镜像。AWS Inspector现在能很好地做这件事。

秘密信息:别写在代码里,也别放在环境变量里就高枕无忧

把数据库密码塞进环境变量,感觉比写在代码里好点,但本质上还是明文存储。如果攻击者通过漏洞获取了函数执行权限,环境变量一览无余。

请用AWS Secrets Manager或Parameter Store(SSM)。

在函数启动时,用SDK去动态获取秘密值。Secrets Manager还能帮你自动轮转密钥。是的,这会让冷启动时间增加几十到几百毫秒,但为了安全,这个代价几乎总是值得的。记得在IAM角色里只授予获取特定秘密的权限。

可观测性:你不知道的事才会伤害你

Serverless应用是高度分布式和事件驱动的。一个异常可能悄无声息地发生,不触发任何明显的错误。

你必须做好这三件事:

  1. 结构化日志(CloudWatch Logs):确保所有Lambda函数都输出结构化的JSON日志,包含请求ID、错误码等关键上下文。这能让你用CloudWatch Logs Insights快速定位问题。
  2. 分布式追踪(X-Ray):启用X-Ray,你会看到一次API请求如何流经API Gateway、Lambda、DynamoDB等其他服务。这对于诊断性能问题和理解复杂攻击链至关重要。
  3. 设置警报:别只盯着错误率。对函数的持续时间、调用频率、内存使用设置异常警报。一次异常的调用峰值,可能就是攻击者在尝试暴力破解。

最后,一个反直觉的观点:有时“少做”就是“多做”

Serverless架构鼓励微小的、单一职责的函数。这本身就是一个安全优势。一个只做一件事的函数,攻击面更小,代码更容易审计,权限也更易于最小化。

别总想着写一个“强大”的函数来处理所有事情。把它拆开。让安全边界变得清晰。

安全不是一个功能,而是一种属性,它必须被设计到架构的每一个环节里。从你写下第一行代码,到配置第一项IAM策略,这个思维就应该存在。

现在,去检查一下你最新的那个Lambda函数吧,它的IAM角色,是不是又该“瘦身”了?

0