全网统一账户实践

分享下目前我们全网的账号管理体系。

整体的账户管理思路是分而治之。主要分为下面三类账户:
1. 办公网账户,也就是大家熟悉的域账户。对于办公网账户,全网用户一人一账户,在 OpenLDAP 的基础上做了一些开发,这是进入公司内部的大门,所有新入职的员工都会分配一个该账号,不管是在办公室连接 Wi-Fi 还是在家连接 anyconnect VPN,访问 confluence/jira 等基础办公设置,都需要通过此账户进行登录认证。
2. 生产网账户,主要用来访问线上、线下机器资源。工程师访问线上生产、测试机器,登录线下自助机树莓派(raspberry) 均需要通过此账户认证,整个 user/group 的分配、HBAC/sudo 的控制、密码/公钥的管理均在 freeIPA/IDM 上实现,freeIPA 是 RedHat 支持的一整套集成安全信息管理解决方案系统,又称 IDM。
3. 数据库账户,这块比较小众,简单带过。
下面会针对上面两大块分别介绍。

办公网账户

该账号与所有人息息相关,从入职第一天起到你的 lastday,都需要登录该账户才可以访问办公资源,包括常见的 Wi-Fi/Gitlab/Jira/Confluence/Jenkins/Cisco Anyconnect VPN/Zabbix/Grafana/跳板机(intermediate host) 以及自己开发的各种内部系统。

这里面需要先简单描述下目前我们的多网分离的架构,多网是指办公网(包含国际线路)、生产网、测试网、专线网(到医院 HIS/LIS 等信息系统)、OOB(带外管理网),这五张大网是处于「部分」分离的状态的,比如,办公网到生产网/测试网/专线网/OOB 是完全分离的状态,除非通过跳板机(后面全部以 ih 代指)登录之后再访问;生产网跟测试网也是几乎分离的,除了极个别的公共服务。以办公网登录生产、测试网为例,在进入用户验证这步之前,会先通过 IP <-> MAC <-> 用户身份的一一映射绑定,先通过最基本 IP:PORT 的 ACL 方式来控制住大部分的请求。所以在你能通过网页打开 git,通过 ssh 协议 pull/push git 仓库的时候,说明已经通过 TCP/IP 层面的验证机制以及用户级别的验证机制,具体如何实现的会在后面的博客中说明。

默认情况下,OpenLDAP 支持的 schema 非常有限;另外不同应用接入方式都不大一样,需要逐一尝试。

比如 LDAP 跟 Anyconnect 的对接,官方提供的 schema 仅仅基本可用,离生产还有一段距离,默认只支持添加一组 IP/Netmask,以及一条 IP 层面的 ACL,为此需要自行扩展维护一套 cisco.ldif 文件,这个是我们自行维护的一个 schema 文件,根据我们业务的情况,新增了一组 IP/netmask 以及若干的 ACL。下面是一个普通用户的数据文件示例:

从 slapcat 导出的字段数据可以看到,为了实现 Wi-Fi 账号跟 OpenLDAP 的共享,加入了 samba 相关的 schema,具体的可以看这个文件

再比如,对于 anyconnect/ih 的认证,需要增加两步验证机制,这里引入 OTP(privacyIDEA) 以及 Radius 作为跟 OpenLDAP 的桥梁例,具体的交互图可以看这里:

最终实现了用户的 CRUD 在 OpenLDAP 层面控制。用户的两步验证,下图可以看到,privacyIDEA 支持十余种的 token,包括 hOTP/mOTP/sms/email/Yubikey 等等:

privacyIDEA 不仅仅支持我们使用的 ldapresolver,sql/passwd/scim 的 resolver 都有很好的支持。目前我们使用 Google Authenticator 是基于事件的 HOTP(RFC4226):

用来管理 OpenLDAP 的工具有不少,包括我们使用的经典的 phpldapadmin,除此之外,fusiondirectoryweb2ldap 都是不错的选择。同时为了支持用户的自助修改、重置密码,定期修改用户密码,我们引入了 LTB,一个非常神奇的 LDAP 工具箱集合,目前仅支持通过邮件找回密码的链接来重置密码:

除了自助机服务,LTB 还支持 LDAP 性能、用户使用数据的监控等若干非常实用的脚本。
这么重要的基础服务稳定性肯定是需要保障的,通过 syncprov 模块实现双 master 的写的高可用,通过多个 slave 同步 master,前端挂 Haproxy 实现读的高可用:

对用户来说,他们看到的是下面这个样子:

PACKT 出版的 Mastering OpenLDAP 是本通俗易懂的书,浏览一遍之后应该能轻松应对上面的内容。 

生产网账户

这里的生产网泛指包含线上生产测试服务器线下自助机树莓派等在内的所有 *nix 系统。所有需要登录如上机器的用户都需要获得该账户的权限之后,才能访问基于 HBAC 机制的主机以及颗粒度更细致的用户执行权限。

整个系统基于 freeIPA/IDM 实现,默认情况下,每台机器有一个专门用来运行进程(我们所有的 JVM 进程都跑在 vm 上,不会出现混跑的状态)的 worker 用户,所有的相关的 bin/, log/, lib/ 等目录文件都通过 Jenkins 统一打包到 ~/worker/ 下面,实现跟系统文件的隔离。/home/worker/ 的权限如下:

worker/ 下面所有的目录文件权限都如上所示。这样,只要用户在 bm_be_sre 这个组下面,就能实现 worker/ 下面也即 JVM 相关服务的读取权限:

下图可以看到,appCenter 这个服务是跑在 worker 下面的:

类似的,如果想实现 worker/ 下面的写操作,比如执行 bin/ 下面的脚本,将用户加到 30002(sre) 这个组即可,这里完全可以各自的需求自定义。所有的 sudo/su 相关权限设置全部在 IPA 的 Policy 操作即可,比如下面这个赋予的是 sre 这个组的用户可以执行 /bin/su – worker、/bin/su worker 这两个单独的比较危险的命令以及 sre_allow 命令行组里面基础命令(/bin/chmod, /bin/chown, /bin/cp 等等):

目前单台 8G/4core 的 IPA 支撑着 1000+ 的线上生产测试的物理虚拟机以及线下 100+ 的树莓派,应付起来绰绰有余,CPU 平均 1% 利用率、disk IO 平均 10%。

对我们的用户来说,在经过办公网/VPN 的 IP ACL 过滤之后,通过办公网账号结合 OTP 登录线上的任意一台跳板机(ih),然后通过 ih 再登录线上的机器,跟办公网账户类似的是,需要定期修改密码。对有权限看到的用户来说,他们看到的是下面这样

以上的两块账户体系算是把当年在阿里的基础核心账户体系复制了一遍,对最终用户来说,体验相对来说会更好些,当然我们没法也暂时没必要实现类似阿里郎那种监控每台入网设备所有操作的系统。

需要注意的是,在 IPA 上新增的用户,或者新增 sudo 权限,由于 sssd 的缓存,不会立即生效,可以通过 sss_cache 或者删除缓存文件可以让规则立即生效,这部分可以以类似 hook 的方式触发,每次修改用户权限的时候自动触发该操作。

freeIPA 结尾的 A 表示 audit,实际情况是目前还不支持 audit 功能,所以这块功能我们通过 snoopy 结合 rsyslog 方式进行收集审计

对于办公网账户,目前通过 python-ldap 实现了多个层次的自助以及服务的打通,freeIPA 还未进行这块的开发工作,最终的效果类比阿里内外,一个 portal 实现不同用户的自助服务。

数据库账户

第三块,或者说非常小众的一块账户是 DB 的账户,这里面主要涉及 MySQL 以及 NoSQL(Redis/ElasticSearch) 的账户划分管理审计。

MySQL 的账户管理我们通过 saltstack 的 mysql_user 进行管理,我们用的saltstack 是 2015.8.7,对 MySQL 5.7 的支持有不少 bug,2016 开头的版本对此都修复了,嫌麻烦的不妨直接把 salt 给升级了或者做 diff 给 2015.8.7 打 patch,主要原因是 5.7 之前存储用户表的密码字段是 password 而 5.7 之后变成了 authentication_string。

目前所有的 MySQL 账户用户通过 git 管理而密码通过 salt pillar 管理,审计则使用了 Percona 的 Audit Log Plugin 通过 rsyslog 打到中心服务器收集分析。

对于 Redis/ES 来说,由于上面存储的数据为非敏感数据,所有的都通过 IP 层面的 ACL 进行控制访问。