跳转到: 导航, 搜索

OSSN/OSSN-0068


重复的令牌撤销请求可能导致服务降级或中断

总结

目前,单个用户在任何给定时间范围内发起 Keystone 令牌撤销请求的频率没有限制。如果用户重复发起令牌请求,然后立即撤销令牌,可能会导致性能下降,并且可能针对 Keystone 发起 DoS(拒绝服务)攻击。

受影响的服务 / 软件

所有使用 Keystone 的服务。Mitaka, Liberty, Kilo, Nova, Juno, Havana, Icehouse, Grizzly, Folsom, Essex。

讨论

令牌撤销可以自助完成,且对任何用户(包括服务用户)发起的令牌撤销次数没有强制限制。

如果令牌撤销快速连续进行,由于 revocation_event 表中的条目不断增加,响应时间会开始变长。

由于没有速率限制机制,单个用户可能导致 OpenStack 认证服务响应时间变慢,从而导致类似 DoS 攻击的情况。

确实存在对撤销事件的清理机制,基于令牌过期时间加上 expiration_buffer(默认值为 30 分钟)。但是,对于默认令牌 TTL 为 3600 秒的情况,用户在那个时间内可能潜在地填充大约数千个事件。

建议的操作

对于当前的稳定 OpenStack 版本(Mitaka 及更早版本),建议操作员部署外部速率限制代理或 Web 应用程序防火墙,为 Keystone 提供第一层保护。

可以考虑以下解决方案,但关键在于操作员在配置任何速率限制功能时,应仔细规划并考虑 OpenStack 云中用户和服务的各个性能需求。

Repose

速率限制过滤器

Repose 提供了一个速率限制过滤器,可以限制每个 IP 地址以及特定 HTTP 方法(DELETE,与此 OSSN 相关)的请求。

以下配置可用于单个节点。对于更复杂的部署,可以构建集群,利用分布式数据存储。

system-model.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<system-model xmlns="http://docs.openrepose.org/repose/system-model/v2.0">
   <repose-cluster id="repose">
       <nodes>
           <node id="repose_node1" hostname="localhost" http-port="8080"/>
       </nodes>
       <filters>
           <filter name="ip-user"/>
           <filter name="rate-limiting"/>
       </filters>
       <services>
       </services>
       <destinations>
           <endpoint id="keystone" protocol="http" hostname="http://idenity-server.acme.com" root-path="/" port="35357" default="true"/>
       </destinations>
   </repose-cluster>
   <phone-home enabled="false"
               origin-service-id="your-service"
               contact-email="your@service.com"/>
</system-model>
ip-user.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<ip-user xmlns="http://docs.openrepose.org/repose/ip-user/v1.0">
   <user-header name="X-PP-User" quality="0.4"/>
   <group-header name="X-PP-Groups" quality="0.4"/>
   <group name="ipv4-group">
       <cidr-ip>192.168.0.0/24</cidr-ip>
   </group>
   <group name="match-all">
       <cidr-ip>0.0.0.0/0</cidr-ip>
       <cidr-ip>0::0/0</cidr-ip>
   </group>
</ip-user>


  • 注意:使用 ip-user 过滤器意味着向 Repose 发送请求的每个 IP 地址都将拥有自己的速率限制桶。因此,任何超出限制的 IP 地址都将被阻止 - 但仅阻止该 IP 地址。如果您将 NAT 连接发送到 Repose,则应考虑它们也将被视为单个 IP 地址,并相应地分组。
rate-limiting.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<rate-limiting xmlns="http://docs.openrepose.org/repose/rate-limiting/v1.0">
   <request-endpoint uri-regex="/limits" include-absolute-limits="false"/>
   <global-limit-group>
       <limit id="global" uri="*" uri-regex=".*" value="1000" unit="MINUTE"/>
   </global-limit-group>
   <limit-group id="limited" groups="limited" default="true">
       <limit id="all" uri="/auth/token" uri-regex="/.*" http-methods="DELETE" unit="MINUTE" value="10"/>
   </limit-group>
   <limit-group id="unlimited" groups="unlimited" default="false"/>
</rate-limiting>
</code>

需要注意的关键点:速率限制仅限于 DELETE 请求(这是用于撤销令牌的 http 方法),以及 URI /auth/token。任何超过每分钟 10 个撤销请求的 IP 地址都将被阻止 1 分钟。

更多详细信息可以在 openrepose wiki 上找到

https://repose.atlassian.net/wiki/display/REPOSE/Rate+Limiting+filter


其他可能的解决方案

NGINX

NGINX 提供了 limit_req_module,可用于提供全局速率限制。使用 map,可以将其限制为仅 DELETE 方法。

nginx.conf
http {
     map $request_method $keystone {
     default         "";
     DELETE            $binary_remote_addr;
     }
     limit_req_zone $keystone zone=keystone:10m rate=10r/m;
     server {
            ...
            location /auth/token {
            limit_req zone=keystone;
            ...
          }
}


更多详细信息可以在 nginx 网站上找到

https://nginx.ac.cn/en/docs/http/ngx_http_limit_req_module.html

HAProxy

HAProxy 可以使用 stick-tables 和通用计数器 (gpc) 提供固有的速率限制

/etc/init.d/haproxy.cfg
# Monitors the number of request sent by an IP over a period of 10 seconds
stick-table type ip size 1m expire 10s store gpc0,http_req_rate(10s)
tcp-request connection track-sc1 src
tcp-request connection reject if { src_get_gpc0 gt 0 }

更多详细信息可以在 haproxy 网站上找到

http://blog.haproxy.com/2012/02/27/use-a-load-balancer-as-a-first-row-of-defense-against-ddos

Apache

这里可以探索许多解决方案。

mod_ratelimit

https://httpd.apache.org/docs/2.4/mod/mod_ratelimit.html

mod_qos

http://opensource.adnovum.ch/mod_qos/dos.html

mod_evasive

https://www.digitalocean.com/community/tutorials/how-to-protect-against-dos-and-ddos-with-mod_evasive-for-apache-on-centos-7

mod_security

https://www.modsecurity.org/

联系方式 / 参考文献