作者 | Manuel Zapf
译者 | Luga Lee
策划 | Luga Lee
2021 年 12 月 10 日,Apache Log4j2 中的一个被称为 “Log4Shell” 的漏洞被发布(CVE-2021-44228),引入了严重的安全风险。作为 Java 应用程序日志库中的一个核心组件,其广泛用于著名的开源项目以及企业级后端应用程序。在本文中,我们将向您展示 Traefik 如何基于插件系统帮助我们的业务缓解此问题。
漏洞简介
Log4j 漏洞使攻击者可以执行任意代码或从被攻击的系统中检索机密信息。可以通过两个不同的步骤来缓解此漏洞:修补系统中的实际漏洞并重新部署它们,或者阻止恶意请求进入反向代理级别。这是可能的,因为在插入可以查询 LDAP 服务器的字符串时出现问题。
在反向代理级别拦截 Log4j 漏洞
得知该漏洞后,我们立即寻找帮助我们的用户和客户降低风险的最佳方法。从下图中可以看出,阻止攻击的最合乎逻辑的位置就在网络入口处,即恶意请求到达易受攻击的系统之前。这正是 Traefik 代理所在的位置。
虽然 HeadersRegexp 匹配器的内部架构允许您阻止简单的请求,例如 curl 127.0.0.1:8080 -H 'User-Agent: jndi:ldap://127.0.0.1/a},但有一种较为容易的方法可以屏蔽用户代理,从而防止对这些标头进行简单的匹配。为了帮助缓解这些问题,我们利用了 Traefik 插件系统。
Traefik 插件
从 Traefik 2.3 版本开始,Traefik 可以加载和使用自定义插件(在我们的 Go 解释器 Yaegi 的帮助下)充当中间件或提供者,以处理和匹配请求头或用户代理中间件的职责。为了缓解 Log4j 问题,我们需要快速采取行动,而不必消耗大量时间来进行软件的实际发布。因此,我们决定在插件中实现所需的功能。
插件的代码地址:https://github.com/traefik/plugin-log4shell
通过利用插件系统,每个 Traefik Proxy 用户或 Traefik Enterprise 客户只需几行配置和重新启动 Traefik 即可有效缓解 CVE。这种做法对双方都有利。我们节省了时间,因为我们不需要经过实际的发布过程,而用户和客户可以更快地访问帮助他们缓解该问题的软件。
要使用插件,与之前的更新配置流程一样,首先,必须在静态配置中声明它,然后重新启动 Traefik fu w 即可。
以下为通过命令行进行配置更新:
--pilot.token=xxx --experimental.plugins.log4shell.modulename=github.com/traefik/plugin-log4shell --experimental.plugins.log4shell.version=v0.1.1
或者基于通用的方法在静态文件中进行配置更新:
Yaml 文件模型
pilot: token: xxx --pilot.token=xxx --experimental.plugins.log4shell.modulename=github.com/traefik/plugin-log4shell --experimental.plugins.log4shell.version=v0.1.1 experimental: plugins: log4shell: modulename: github.com/traefik/plugin-log4shell version: v0.1.0
Toml 文件模型
[pilot] token = "xxx" [experimental.plugins.log4shell] modulename = "github.com/traefik/plugin-log4shell" version = "v0.1.0"
一旦插件安装完成并重新启动 Traefik 后,插件充当普通中间件,此时,我们需要在路由器上进行引用:
http: middlewares: log4shell-foo: plugin: log4shell: errorCode: 200 routers: my-router: rule: Host(`localhost`) middlewares: - log4shell-foo service: my-service services: my-service: loadBalancer: servers: - url: 'http://127.0.0.1'
除此之外,也可以在 K8s Ingress 或 K8s Ingress Route 上进行引用。
K8s Ingress:
--- apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: log4shell-foo spec: plugin: log4shell: errorCode: secretName --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: myingress annotations: traefik.ingress.kubernetes.io/router.middlewares: log4shell-foo@kubernetescrd spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: whoami port: number: 80
K8s Ingress Route:
--- apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: log4shell-foo spec: plugin: log4shell: errorCode: secretName --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoami spec: entryPoints: - web routes: - kind: Rule match: Host(`whoami.example.com`) middlewares: - name: log4shell-foo services: - kind: Service name: whoami-svc port: 80
基于此插件中间件并准备好相关配置更新,即便更棘手的查询,比如 curl 127.0.0.1:8080 -H 'User-Agent: ${${lower:j}ndi:ldap://127.0.0.1/a} 在入口控制器级别也能够有效阻止,因此,后端服务免受传入的恶意请求。
结论
除了 CVE-2021-44228 漏洞之外,还有第二个 CVE 发布 (CVE-2021-45046) 用于 Log4shell 中一个不太严重的漏洞,这将迫使管理员、操作员和开发人员再次更新他们的所有应用程序并执行新的部署集。基于 Traefik 的保护,使得后端服务器免受漏洞的压力就变得尤为渺小,毕竟, Traefik 阻止了外部攻击。这不会使更新实际应用程序过时,但它消除了这样做的直接压力。
这种缓解措施并不是 Traefik 可以帮助您保护后端应用程序的唯一方式。中间件,例如 Rate-Limiting 或 Traefik Enterprise 的增强功能,也有助于保护您的系统免受各种攻击。
# 参考
- https://info.traefik.io/webinar-recording-enterprise-best-practices-to-expose-and-secure-microservices-apis
- https://pilot.traefik.io/plugins/61bb41bb7e8f2a85c1a22577/log4-shell