请及时关注“高效运维(微信ID:greatops)”公众号,并置顶公众号,以免错过各种干货满满的原创文章。
许颖维
曾经就职于日PV超亿次的WAP搜索公司,后加入多次占领Facebook日活跃Top 10的游戏公司(产品有开心水族箱、开心消消乐),负责搭建自动化运维平台。
现任国内领先的商用车联网公司担任系统支持部负责人,同时负责实时在线并发车机百万级别的车联网平台运维工作。
在企业创办初期,少于50台服务器的情况下基本不会遇到帐号管理的问题。
但是随着时间的推移,服务器数量增加及经常变更服务器密码,就会频繁导致有些服务器忘记密码,登录不上去的情况。
这个在大多数公司都是普遍存在的,给SA增加了不少烦恼。甚至有些企业内部员工一直在使用root帐号,开发人员及运维人员混用同一帐号进行管理。这会导致误操作的后果不堪设想,因此急需一套帐号密码管理制度和管理工具。
最初可能仅仅是为了能满足最简单的功能,但是随着时间的推移,问题与需求越来越多,系统不断的演变,最终将会形成一个什么样的系统呢?
下面跟大家分享下,我经历的统一身份认证系统(基于OpenLDAP)的整个发展及演变过程。
需求的产生往往都来自于故障
公司发生了一次故障,一台边缘系统服务不稳定,造成主系统的负载非常高,这个时候业务运维人员需要登录上服务器进行解决问题,可是发生了最不愿意看到的一幕:
“密!码!不!对!我!登!录!不!上!去!”
“我试试看,是不是之前改密码的时候漏掉了这台服务器……完了,我的也登录不上去….”
本来一个简简单单的故障,被延时了将近一个小时才登上服务器进行解决,结果被骂得狗血淋头,站都站不稳。
这个时候运维部门决定要搭建一套统一身份认证系统,避免类似问题再次发生。经过公司内多个部门的讨论,得出最初的需求:
a)为了员工能高效工作,需要只使用一个帐号密码就能登录所有服务器
场景A
A同事入职,申请登录服务器,这个时候需要管理员为他分配登录服务器的账号密码,并且以A的名字为命名账号,密码为初始密码。
b)同时更改一次帐号密码,所有服务器快速生效
场景B
A同事拿到分配的账号密码之后,项目比较着急,希望能马上登录服务器查看相应的应用情况。
出于安全考虑,需要修改账号密码,但是不希望有其他人知道,甚至是管理员。
c)所有人都能sudo到root用户,进行系统管理和业务调整(创业初期讲究短平快,使用root是相当常见的,不过这个不合理的需求在后面会解决)
根据讨论得出的需求及运维部门的考虑,我们考虑过两种方案:
第一、使用配置管理工具,将系统的Passwd、shadows等文件进行统一管理,达到账号密码的统一;
第二、使用工具OpenLDAP/Kerberos来实现账号密码信息的统一管理。
考虑到第一种方案风险较大,而且用户更改密码生效周期过长等因素,所以放弃了。
而至于在OpenLDAP与Kerberos之间的选择则完全是巧合,因为测试OpenLDAP过程非常顺利,而且容易上手( 请原谅我选择了容易上手的工具,大家请勿拍砖 ^_^)
最终确定实施方案:以 OpenLDAP 为核心工具,使用 sudo + pam 来辅助。下面阐述一下方案的概况:
服务器登录验证模块:pam模块增加验证数据源的扩展,不仅在本地 passwd & shadow 文件中进行验证,还增加了到OpenLDAP源的验证过程。
sudo su – root
前期如果考虑到数据库的权限比较特殊,安全级别比较高,可以让OpenLDAP不承载所有服务器类型的认证。
以WEB+CACHE+DB的业务类型为例,我们将WEBCACHE业务的管理纳入到OpenLDAP中,而DB业务维持本地的账号密码+sudo权限管理。
a)需要实现每个人都有相对应的默认权限
场景C
A同事拿到分配的账号密码之后,向SA说明自己的需求,不希望拿到太大的权限,避免误操作承担过多的风险,只需要读的权限,不需要服务器和应用的操作权限。
b)需要在特定环境中获得一些特殊权限
场景D
A同事拿到只读权限登录上服务器之后,希望能拿到测试环境中自己负责模块的应用操作权限,但是不希望拿到BETA和生产环境的操作权限。同时以上的需求仍然需要满足。
c)所有拥有root的权限,非常的危险,必须对权限进行精细化管理
场景E
生产环境发生了一个故障,还是A同事在配合运维排查故障过程中,发现有这个服务配置的内存数量太小,导致服务运行效率非常低,这个时候A同事立马对配置进行更改,效果非常明显,服务恢复了!
但是这并没有结束,接下来是服务器ping得通了,但是服务宕机,连ssh登录都被拒绝了。原因是配置的内存超过了服务器的实际内存大小,服务器严重使用了内存及SWAP空间,最终SWAP空间被使用快速消耗完,并最终导致了服务器短时间内的宕机假象。
场景F
B同事,在根目录下,以为在自己的目录下,使用root的用户执行了一个shell命令: rm -rf ./*
思考:
在公司内部会有多个部门,而每个部门对权限的需求又有很多的不一致:
经过讨论得出:需要对所有的员工根据权限的不同进行分组,并对组进行授权,不同的组拥有不同的权限。
企业中的角色账号分类,具体如下:
1. 管理员角色:root(SA角色使用)
2. 业务角色:oracle(DBA角色使用)、service(OPS角色使用)
3. 观察角色:read_only(研发角色使用)
4. 个人角色:LDAP账号(个人账号)
在OpenLdap里面存在三种对象:
1. 用户(个人账户:people)
2. 用户组(部门组:OU)
3. sudoers组及权限
对象之间的关联关系如下:
就这样用户账号就与sudoers组产生了关联,而在sudoers组里包含了sudo权限。所以用户的权限也就确定了:
sudo su - root
sudo su - service;
none
sudo su - read_only
我们实际情况是如何使用的呢?
个人用户通过LDAP个人账号登录跳板机,然后再登录至目标服务器,最终在目标服务器上根据OpenLDAP内定义的权限,进行用户角色的切换(例如 sudo su – root ),这样就可以得到相应的许可权限。
是否支持多IDC分布式部署?
场景G
随着业务的发展,公司需要进行异地灾备,从一个IDC扩展成为多个IDC。
运维部门必须考虑到有多个IDC该如何处理,必须满足多IDC的分布式架构,才能满足数据同步及快速生效的需求,同时减轻管理上的成本;
OpenLDAP支持一主多从的分布式架构,如果你有多个IDC机房,你可以选择一个IDC作为核心IDC,在核心的IDC上部署Master+Slave(可以部署在同一个服务上),其他非核心的IDC部署Slave。
Master承担的功能是密码变更请求的响应及Replace的log的push功能,Slave承担的是每个IDC内部服务器账号认证的请求响应;
为了通讯的安全,可以在核心与非核心IDC之间建立IpsecVPN隧道,保证数据安全性,同时用户在修改密码的时候,需要将请求重定向到Master上。
所以务必保证所有的IDC是可以访问到Master的OpenLDAP服务,否则会造成无法更改密码,或者只能在核心IDC上服务器进行修改密码等情况。
实现方法
- Master上通过在主配置文件上增加 replica 配置项,就可以轻松实现同步数据的功能
- Slave在配置文件上增加配置项 updatedn 和 updateref 就可以将密码更改重定向到Master上
由于涉及到生产环境,所以使用及管理过程需要是安全可靠的
场景H
安全部门得知要搭建统一身份认证系统,就立马提出要求:过程需要足够的安全,包括通讯过程安全并要防止暴力破解密码。
1. 在OpenLDAP中非常友好的支持使用openssl进行交互数据加密
这里涉及到制作CA证书的过程,又是一个很宽的领域,大家自行学习吧~
强烈建议在制作证书过程使用泛域名,这样就能满足前面的需求,满足多IDC机房的时候使用同一个证书进行部署。
比如:证书匹配 *.domain.com每个IDC使用域名
- idc1.domain.com
- idc2.domain.com
- idc3.domain.com
部署过程只需要一个证书即可满足所有IDC的需求,方便快捷。
OpenLDAP服务器端和客户端增加以下配置,来支持openssl的交互加密:
服务器端:
客户端:
2. OpenLDAP并不是原生支持防暴力破解密码。需要在操作系统的pam模块中增加该功能
在/etc/pam.d/sshd中第二行增加以下内容:
auth required pam_tally.so alt="中小企业如何优雅地统一管理多机房服务器?" />就这样,服务器端的日志不再快速增长,同时服务的性能也恢复了(此处应有掌声)
7.1 需求推动演变:服务器对账号的限制
需要实现项目组的服务器禁止其他项目组的人员登录,即对登录设备的人员权限进行限制
场景J:
目前大家登录服务器已经非常方便,但是存在一个问题:项目组A的同事只要知道项目组B的服务器IP地址,就可以方便快捷的登录上服务器,并随便进行下载资源。
经过各部门的讨论,结论是:
需要控制,让每个项目组的人员只能登录相应项目组的服务器,如果有类似需求,必须得到项目组的确认
7.2 解决方案:
OpenLDAP同样可以支持对主机的限制,通过以下4步就能帮你实现:
- 在OpenLDAP系统内增加 host 的属性
/etc/ldap/schema/ldapns.schema
- 在OpenLDAP的用户信息中增加
host:HostName
(允许用户登录的主机名) - 在客户端的
/etc/ldap.conf
上开启pam_check_host_attr
属性 - 在客户端的
/etc/ldap.conf
上增加pam_filter
和nss_base_<map>
的定义
当然这块需要我们做一定的开发工作,把对用户的host属性编辑功能页面化,并且有一定的审批流程,能更适合企业的使用。
总结:最终的模块与功能划分
1. 账号管理方面
- 账号信息管理:包括用户ID、用户账号、用户密码、OU账号(OpenLDAP以OU命名,区分角色组或者部门)、OU_ID等;
- 权限信息管理:根据用户权限需求不同,定义每个归属的OU对应sudoer权限内容,并作为默认权限。而各自的特殊权限只能在相应的服务器上的sudoers里面进行定义;
2. 方案架构方面
- 认证到服务器端进行验证;
- 主从同步实现:一主多从的架构,实现多IDC之间的数据同步;
- 服务业务解耦:对业务归属账号进行忽略定义,避免对业务的影响,及加大OpenLDAP服务的的压力;
3. 安全管理方面
- 交互通讯加密:使用openssl对整个身份认证过程进行加密,保障内部通讯的安全;
- 登录主机限制:实现对用户拥有登录的设备进行限制,便于管理需要;
- 防止暴力破解:定义密码失败次数限制,及限制动作的定义;
- 提权功能:用户必须通过个人账号登录服务器,并使用sudo才能进行提权,方便进行监控与管理;
一点感悟
每个系统从建立到最终的定型都是需要一步一步摸索过来,没有一个方案是最佳的,只有最适合当前现状的方案。
后记
如果大家觉得内容还不错,后续我还会接着分享更多的内容,包括:
- OpenLDAP与SaltStack整合进行高效管理
- OpenLDAP的WEB封装
- OpenLDAP的API实现
本文分享了一个初略的思路,每个公司最终都会有适合自己的解决方案,希望与广大的运维同仁一起学习进步。有错误的地方非常欢迎指正!
[2019-08-22 16:35:03]