所有文章 > API安全 > 增强API安全性:使用OPA和Kong Gateway进行细粒度访问控制
增强API安全性:使用OPA和Kong Gateway进行细粒度访问控制

增强API安全性:使用OPA和Kong Gateway进行细粒度访问控制

Kong Gateway 是一个开源 API 网关,可确保只有正确的请求才能进入,同时管理安全性、速率限制、日志记录等。OPA (开放策略代理) 是一个开源策略引擎,可控制您的安全和访问决策。您可以将其视为将策略实施与您的应用分离的大脑,这样您的服务就无需担心执行规则。相反,OPA 使用其 Rego 语言进行思考,评估跨 API、微服务甚至 Kubernetes 的 策略。它灵活、安全,使更新策略变得轻而易举。OPA 通过评估三个关键事项来工作:输入(请求等实时数据)、数据(用户角色等外部信息)和策略(Rego 中决定“允许”还是“拒绝”的逻辑)。这些组件共同使 OPA 能够让您的 安全 游戏保持强大,同时保持简单和一致。

我们想要实现什么目标或解决什么问题?

通常,OPA 中的数据就像一个稳定的老朋友——静态或缓慢变化。它与不断变化的输入数据一起使用,以做出明智的决策。但是,想象一下一个拥有庞大的微服务网络、大量用户和像 PostgreSQL 这样的庞大数据库的系统。该系统每秒处理大量交易,需要毫不费力地保持其速度和吞吐量。

在这样的系统中,细粒度的访问控制非常棘手,但借助 OPA,您可以减轻微服务的负担,并在网关级别进行处理。通过与 Kong API Gateway 和 OPA 合作,您可以获得一流的吞吐量和精确的访问控制。

如何在不降低速度的情况下保持准确的用户数据?不断访问 PostgreSQL 数据库以获取数百万条记录既昂贵又缓慢。同时实现准确性和速度通常需要在两者之间做出妥协。让我们通过开发一个自定义插件(在网关级别)来达到实际的平衡,该插件经常加载和本地缓存数据,供 OPA 用于评估其策略。

演示

为了演示,我在 PostgreSQL 中设置了示例数据,其中包含用户信息,例如姓名、电子邮件和角色。当用户尝试通过特定 URL 访问服务时,OPA 会评估是否允许该请求。Rego 策略检查请求 URL(资源)、方法和用户的角色,然后根据规则返回 true 或 false。如果为 true,则允许请求通过;如果为 false,则拒绝访问。到目前为止,这是一个简单的设置。让我们深入了解自定义插件。为了更清楚地了解其实现,请参阅下图。

当请求通过 Kong Proxy 发出时,Kong 自定义插件将被触发。该插件将获取所需的数据并将其与输入/查询一起传递给 OPA。此数据获取分为两个部分:一部分是查找 Redis 以找到所需的值,如果找到,则将其传递给 OPA;否则,它将进一步查询 Postgres 并获取数据并将其缓存在 Redis 中,然后再传递给 OPA。我们可以在运行下一节中的命令并观察日志时重新回顾这一点。OPA 做出决定(基于策略、输入和数据),如果允许,Kong 将继续将该请求发送到 API。使用这种方法,对 Postgres 的查询数量显着减少,但可用于 OPA 的数据相当准确,同时保持低延迟。

要开始构建自定义插件,我们需要一个 handler.lua 实现插件核心逻辑的地方,以及一个 schema.lua 定义插件配置架构的地方(顾名思义)。如果您正在开始学习如何为 Kong 编写自定义插件,请参阅 此链接 了解更多信息。文档还解释了如何打包和安装插件。让我们继续了解这个插件的逻辑。

演示的第一步是 在您的本地设置或任何云设置上安装 OPA、Kong、Postgres 和 Redis 。请克隆到此 存储库 。

查看 docker-compose yaml,其中定义了用于部署上述所有四个服务的配置。观察 Kong Env 变量以了解自定义插件的加载方式。

运行以下命令来部署服务:

docker-compose build
docker-compose up

一旦我们验证容器已启动并正在运行,Kong 管理器和 OPA 即可在相应的端点 https://localhost:8002 和 https://localhost:8181 上使用,如下所示:

创建测试服务、路由并使用以下命令将我们的自定义 kong 插件添加到此路由:

curl -X POST http://localhost:8001/config -F config=@config.yaml

使用以下命令将 authopa.rego 文件中定义的 OPA 策略发布并更新到 OPA 服务:

curl -X PUT http://localhost:8181/v1/policies/mypolicyId -H "Content-Type: application/json" --data-binary @authopa.rego

仅当用户使用方法访问 /demo 路径并具有 .可以根据需要添加其他规则,以根据不同的标准定制访问控制。GET"Moderator"

opa_policy = [
{
"path": "/demo",
"method": "GET",
"allowed_roles": ["Moderator"]
}
]

现在设置已准备就绪,但在测试之前,我们需要在 Postgres 中添加一些测试数据。我为一些员工添加了一些示例数据(姓名、电子邮件和角色),如下所示(请参阅 PostgresReadme)。

以下是失败和成功请求的示例:

现在,为了测试这个自定义插件的核心功能,让我们发出两个连续的请求并检查日志以了解数据检索是如何发生的。

以下是日志:

2024/09/13 14:05:05 [error] 2535#0: *10309 [kong] redis.lua:19 [authopa] No data found in Redis for key: alice@example.com, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"

2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:25 [authopa] Fetching roles from PostgreSQL for email: alice@example.com, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"

2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] postgres.lua:43 [authopa] Fetched roles: Moderator, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"

2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] handler.lua:29 [authopa] Caching user roles in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"

2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] redis.lua:46 [authopa] Data successfully cached in Redis, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"

2024/09/13 14:05:05 [info] 2535#0: *10309 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "ebbb8b5b57ff4601ff194907e35a3002"

2024/09/13 14:05:05 [info] 2535#0: *10309 client 192.168.96.1 closed keepalive connection

------------------------------------------------------------------------------------------------------------------------

2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] redis.lua:23 [authopa] Redis result: {"roles":["Moderator"],"email":"alice@example.com"}, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"

2024/09/13 14:05:07 [info] 2535#0: *10320 [kong] opa.lua:37 [authopa] Is Allowed by OPA: true, client: 192.168.96.1, server: kong, request: "GET /demo HTTP/1.1", host: "localhost:8000", request_id: "75bf7a4dbe686d0f95e14621b89aba12"

日志显示,对于第一个请求,当 Redis 中没有数据时,数据将从 Postgres 获取并缓存在 Redis 中,然后再发送给 OPA 进行评估。在后续请求中,由于 Redis 中有数据,因此响应速度会快得多。

结论

总之,通过将 Kong Gateway 与 OPA 相结合并使用 Redis 缓存实现自定义插件,我们有效地平衡了高吞吐量环境中访问控制的准确性和速度。该插件通过在初始查询后将用户角色缓存在 Redis 中来最大限度地减少昂贵的 Postgres 查询的数量。在后续请求中,数据将从 Redis 中检索,从而显着减少延迟,同时为 OPA 策略评估保持准确和最新的用户信息。这种方法可确保在网关级别有效处理 细粒度的访问控制, 而不会牺牲性能或安全性,使其成为扩展微服务同时实施精确访问策略的理想解决方案。

原文链接: https://dzone.com/articles/enhanced-api-security-fine-grained-access-control

#你可能也喜欢这些API文章!