Keystone Token revocation issues

Keystone的Token Revocation的实现方式是导致Keystone Token Validation变慢的根源。 由于所有的OpenStack API调用均需要Validate Token,这也将该问题扩大成整个OpenStack云平台的性能瓶颈之一。

在2016年7月22日的Openstack Digest, Vol 37, Issue 22中,来自Redhat的Luke Hinds提到了该问题可被利用来进行拒绝服务攻击(DoS)。 Revocation Event记录的保存时间是Token Expiration 加上Expiration Buffer。在默认配置下,其值为1.5小时。在这个时间段内, 一个合法的普通OpenStack用户可以不停地生成Token,然后revoke Token,从而生成大量的Revocation Event记录,拖慢Token Validation。

在Validate Token时对Revocation Event表的查询语句是:

Select <Column List> from Revocation_Event Order By Revoked_at

在用户不停地调用revoke Token的情况下,这样一个语句的结果是变化的,导致在数据库端和Keystone端的缓存都是会失效的。 当结果集足够大时,这一查询过程和结果数据传输过程都会变得很费时。

那么如何解决这一问题呢?在Luke Hinds的邮件中提到了限制revoken Token调用频率的方法,这是常用的保护API的防御性办法。

上述办法假定正常情况下Keystone的Revocation Event记录是比较少的、不至于有性能问题。然而在某些集成应用场合中, 由于Keystone客户正是以类似方式使用Token,再revoke Token来提高其Token安全性的,客观上导致Revocation Event记录很多,validate Token费时。

那么有什么直面问题的解决办法呢?

进一步分析validate Token时的Revocation Event计算过程,可以发现当前现实方式的问题是将大量数据记录传递到Keystone进行计算。 因此,我们可以想到的第一个优化方案是将计算过程从Keystone移到数据所在地 -- 也就是使用数据库的存储过程来完成这一计算。

如果考虑到Revocation Event数据的时间特征,我们可以进一步优化方案。 假设Revocation Event List = [A, B, C, D, E, F, ...], 经过M秒之后,列表变为 [C, D, E, F, G, H, ..]. 也就是说在列表头部去掉过期的记录,在列表尾部加上新生成的记录。这是一个典型的排序队列。 上一方案中基于数据库的查询不能利用这一数据变化的特点。我们完全可以开发一个单独的服务,在将记录写入到数据库的同时, 在内存中维护这个排序列表,就可以快速响应Validate Token时对Revocation Event列表的计算。

更新 2017-2-22

在最新的版本里面,validate_token在获取event list时传入了token作为条件,从而极大地减少了返回的记录数量, 明显地提高了性能。

参考资料

  1. Openstack Digest, Vol 42, Issue 11. On Dec 11, 2016, the Keystone PTL, Steve Martinelli, said:

    "Token validation can be improved using caching, which we worked on in Liberty, Mitaka and Newton (the latest Mitaka release (9.2.0) includes a critical performance fix, it was not backported to Liberty). Revocation events are still an issue for performance, but we've been addressing that in Ocata. I don't think we'll be able to backport the fixes for poor revocation performance though, unfortunately it goes against the backport policy."

  2. Dolph Mathews, Benchmarking OpenStack Keystone Token Formats, http://dolphm.com/benchmarking-openstack-keystone-token-formats/, "PKI and PKIZ tokens are slower than UUID tokens, and based on the June 2015 update, Fernet tokens are faster to create than UUID tokens (but also way slower to validate). "

  3. Matt Fischer, Keystone Token Performance, Liberty vs. Mitaka, https://www.mattfischer.com/blog/?p=703

  4. Matt Fischer, Token Revocation Performance Improvements in Keystone Ocata, https://www.mattfischer.com/blog/?p=790, 该改善的测试是在静态的Revocation Event列表情况下的,没有考虑到在测试中引入新的Revocation Event的影响。