vlambda博客
学习文章列表

gMIS吉密斯升级:多IP-Roaming漫游改进和Cache缓存优化

“完成大事业的唯一方法,但从基本上一步一步、一点一点地做起,这是行为学所重视的一个事实。”
—-米塞斯 Mises《人的行为 Human Action》,https://ufqi.com/news/ulongpage.2014.html 

 gMIS吉密斯 作为管理后台系统软件,一直默默工作在后端,鲜有抛头露面的时机。其实gMIS也在不断的优化改进,距离上次:☘ gMIS吉密斯升级:点选Pickup2.0和安全及权限系统等 ( https://ufqi.com/blog/gmis-updt-pick2-enhance-in-signout/ ),已经差不多快一年没更新gMIS Blog,趁着最近一次版本的更新,记录如下,以资参考备查。

1. 单用户多IP-Roaming漫游安全鉴权改进

也就是说位移静态单用户可能有多个IP,而位移进行中的用户更有可能是多个IP,再而三的多IP多通道并发通信也日渐成熟——一次上层的HTTP请求,可能其中的Packets分别由不同的IP“同时”传送而来的。这在应用层或感知不到,但也要在未来考虑到这种情况。

回到这个单用户多IP漫游的情况,如果继续使用此前的策略,将用户从系统登录状态弹出然后请用户再登录一次,从而形成新IP下的鉴权,显然是不合适的。有没有更好的办法来实现既能保障安全,也同时降低由于多IP变化引起的频繁登录?
梳理一下面临的新情况:
1)  一个用户单地点可能同时有多个IP,如 IPv4、IPv6
2)  一个用户移动中可能访问多个基站,会经历多个IP,这些基站IP可能同时也有IPv4和IPv6.
综上,一个已登录的用户,在单一个回话期间,其IP变更将是大概率事件。

然而作为网络安全防范的主要利器之一IP在用户鉴权方面短期内看,又是不可或缺的。或许将SID视为Token来处理将是一个新思路。每一次成功鉴权之后,将已授权的SID赋予Token的含义,在后续行为中如果持有一个合法的TOken则视为合法的访问,作为鉴权IP失败后的补救措施。

借助于服务器端的缓存机制,我们设计到一种新方法,基于此可以实现在单用户多IP或者多IP漫游的情况下,使得用户能免于重新登录。该方法的思路是:
1) 维持现有登录机制不变,
2) 当用户登录成功后,在服务器端缓存用户下次鉴权的SID值,
3) 当下次用户进行访问时,如果IP没有发生改变,则使用此前的鉴权获得成功,继续,
4) 此时,如果用户切换(IPv4/IPv6) 或者漫游到新IP时,读取在服务端的缓存SID,如果是合法有效的,则视为已鉴权的用户,继续,
5) 如果使用IP未鉴权成功,也未检测到SID为合法的,则视为非法,拒绝请求并跳转到登录页面。

这个策略可以视为对去年IPv4/IPv6双栈网络模式的扩展和升级,无论后续单用户再切换多少IP,如果其持有一个经合法鉴权的SID,则可以在该SID有效期内(数分钟、数小时或者至多一天)持续使用系统服务。

如此以来,则可以继续愉快地的玩耍了。这一升级改进主要涉及到内容有:
1) class/user.class 中增加 setSidToken / getSidToken 两个方法,
2) 改进 extra/signupin: 登录成功后,调用 $user->setSidToken ,将已授权SID 缓存起来,
3) 改进 user->getUserBySession: 在访问鉴权的时候,增加对现有SID的读取,通过 $user->getSidTOken读取.

等等,这里好像又埋下了隐患,本来一把钥匙(SID)开一个门(IP),现在是一把钥匙能开很多门了,这是万能钥匙🔑吗?如果中间人攻击,获得一个已授权的SID,在别处也可以自由的使用,这显然与最早的SID安全机制设计有冲突的地方。
有鉴于此,我们将这个单一SID允许多IP的功能设置为可选项,仅在对安全性要求不高的场景下使用,或者在相对隔离的。

4) 修改 inc/config: 增加 Single_Sid_Allow_Multiple_IP 的开关,如果是 true 则启用上述功能,如果 false 则不允许。默认是 false.
$conf[‘single_sid_multiple_ip’] = true; # lower security higher convenience if true, vice versa. 13:12 2021-03-23

从本质上说,安全与便利有很多时候需要做取舍,而技术的进步则使得两者更好地平衡。

2. Cache优化改进键值Key的设置

gMIS默认配置的缓存服务是 -Memcached, 尽管Memcached对Key的命名和取值给了很大的空间(250Bytes)和很少的限制(除空格和一些控制字符外),我们在实际使用中,仍然不会真的设定一个key为100字节的取值。
为了方便操作,通常我们认为对原始的raw string,取Md5摘要信息,这样既避免了太长,也避免了包括危险非法字符的可能。目前的写法是这样的:
return strlen($k)>32 ? md5($k) : $k;

这么写是有一定道理的,通常我们为一个缓存的Key命名时,并不会超过32个字节,这样的话,等于是人为的加长了Key值。理性一些,我们不应该对小于32的Key进行加长,所以才有了这样的设计:只对超过32字节的Key做摘要处理。
然而,实际追究起来,这里似乎也有个隐患,就是Key值如果使用 raw string的话,可能会有危险的非法字符,这可怎么好?

很快,我们在GWA2 Java( https://ufqi.com/dev/gwa2/ )的源代码中找到答案。在GWA2 Java的Memcached的缓存实现中,预留了 isSanitizeKeys 的开关,如果将 isSanitizeKeys=true, 则会对Keys进行安全地封装,从而避免了潜在的危险字符。
这一封装是基于输出安全纯字符串的 Base62x ( https://ufqi.com/dev/base62x/ )而实现的。

改进的实现方法如下:
if(strlen($k) > self::Max_Plain_Key_Length){
$k = md5($k);
}
else{
if($this->sanitizeKeys){
$k = Base62x::encode($k);
}
}

这样就满足了当raw string key太长而大于32字节时,加以md5消息摘要处理,使之输出转换为不大于32字节的Key;如果 raw string key 小于32字节时,为安全起见,使用 Base62x 消除危险的非法字符,使之输出的小于32字节的纯字符串。

顺便的,也更新了 GWA2 PHP版本的 Memcached的实现。增加使用 Base62x 加固对小于32字节的raw string key的安全处理。

3. 其他

改进了 comm/header 中对获取 User Id的程序逻辑。

优化 inc/WebApp 核心程序中的 setBy 和 rmBy 方法,向前兼容,增强对Cache的支持。

其他一些细节调整。


-gMIS (general Management Information System,吉密斯) 是一种基于 -GWA2 (General Web Application Architecture,吉娃兔) 的通用管理信息系统应用软件,具有可配置的输入和输出接口、开箱即用等特征。

可以在 gMIS吉米斯 上构建各种管理信息应用系统软件,例如:
内容管理系统(CMS), 客户资源管理(CRM), 企业资源计划管理(ERP),
办公自动化系统(OA)等,
也可以是各种行业应用管理系统软件,例如:
人力资源管理系统(HR),学生管理,档案管理,旅游管理,图书管理,
商品管理及业务运营支撑系统(BOSS)等等。
gMIS吉米斯 能够实现零代码开发、数分钟内快速搭建各种管理信息系统(MIS, Management Information System).

-gMIS is a -GWA2 based Management Information System (MIS) software with characteristics like configurable input and output interfaces, open-box-to-use.
Various management application software systems can be built on it, such as
Content Management System (CMS), Customer Resource Management (CRM), Enterprise Resource Planning Management (ERP),
Office automation systems (OA), as well as different industry application management system softwares, such as
Human Resource Management System (HR), Student Management, Archive Management, Tourism Management, Book Management,
Commodity management and business operations support systems (BOSS), etc.
With zero code development, -gMIS can build a set of management information systems (MIS) software in a few minutes.

Lower Costs, 
Better Productivity.
降低成本,
提高效率.

http://ufqi.com/blog/gmis-ip-roaming-and-cache/ 

-R/12Sh