本系列内容是我们在不同项目的维护过程中总结的关于 DevOps/SRE 方面的最佳实践,我们将致力于在项目上尽最大的努力来推行这些最佳实践。我们希望这些最佳实践能对项目的稳定运营提供帮助,也希望刚接触 DevOps/SRE 的新人能通过学习这些最佳实践来提升自己在这方面的水平。
用户和权限管理对于维护一个安全可靠的基础设施和应用资源至关重要。在当今快节奏和协作的开发环境中,确保合适的人员拥有系统、资源和数据的适当访问权限非常重要。通过实施用户与权限管理实践,组织可以降低未经授权访问的风险,减少人为错误,强制执行安全控制,符合法规。
在本文中,我们将探讨一组最佳实践,包括给每个用户建立独立的账号,给每个服务建立专用的账号,减少使用特权账号,使用角色而非用户账号,定期进行轮换长期凭证的密码或访问密钥,最小化权限原则,定期查看并移除未使用的用户、角色、权限等凭证,分离开发、测试和生产环境权限,使用强密码策略,使用多重验证,开启审计日志。以在 Devops/SRE 流程中建立坚实的用户和权限管理基础。通过遵循这些实践,您可以提高系统的安全性、效率和明确责任,促进协作,并保持流程的简化。
给每个用户建立独立的账号
在任何的系统中,我们都强烈建议给每个用户建立独立的账号,而非使用共享账号。相比共享账号,独立账号可以更明确地划分用户的归属和权限,便于最小化权限管理,并减少账号泄露的风险。此外,独立账号还方便后续的风险评估和操作审计等工作。
优点:
- 合法性检验:独立账号可以检验用户身份的合法性以及对用户进行鉴权
- 提高系统安全性:限制每个用户的权限可以维护系统的安全
- 提供个性化设置:为每个用户提供独特的体验,用户可根据其偏好进行自主设置
- 方便审计:独立账号可以方便追踪每个用户的操作记录,有利于故障排查
- 减小损失范围:泄露独立账号后影响的范围更小
缺点:
- 增加管理成本:为每个用户分配独立账号增加了管理复杂性
实施要点:
- 创建账号时,需要有验证用户身份信息的资料,也可以考虑使用多因素身份验证
- 提供用户的账号恢复机制,用于应对用户忘记密码等场景
- 权限应由专门的团队进行管理和分配
- 对于与项目相关的工具链(例如云平台,代码仓库,CI/CD 平台,项目管理工具等),要对用户账号进行统一管理,确保每个用户有独立的权限。大型公司可以使用第三方工具例如 Azure AD 来充当集中式的身份提供者和访问管理平台,将所有项目关联账号统一管理以便管理员方便的定义和执行一致的访问策略,管理用户配置和撤销,确保每个用户在集成平台上进行安全身份验证和授权。
- 保证用户离开团队时权限的销毁
给每个服务建立专用的账号
一些自动化工具会需要和相关的系统/平台进行交互操作,大部分的系统/平台都会对类似的操作鉴权,因此这些工具也需要对应账号来完成相应的验证。我们建议给类似的需求建立服务专用的账号,为方便管理,可以给账号名称上加上一些表意的前后缀,比如 svc 或者machine_user 等来区分账号的属性。
如果需要使用的第三方服务并不需要每个团队成员都注册账号,我们建议使用一个管理专用而非个人所属邮箱等信息来注册,以避免团队成员变动带来的账号无法保留等影响。
优点:
- 保证系统的安全性:若所有平台共用一个账号,一旦被盗用所有的服务都会受到攻击
- 便于审计:方便跟踪操作记录,有利于排查问题
- 精细化权限管理:提高对于不同服务权限管理的颗粒度
缺点:
- 增加管理成本:每个系统/平台需要单独创建账号
- 不适用于所有系统:不太适合小型系统
实施要点:
- 不使用用户 token 拉取代码
- 不与其他服务共用同一账号/用户
- 建立账号时要遵循最小权限原则,保证账号只具有该服务所需要的权限
- 定期审计账号的访问记录
实施示例:
(1)以 Github 为例,在代码管理平台上为 CI/CD 平台的 agent 创建单独的账户
- 对于 agent 要拉取代码仓库的场景,我们建议:创建账户名为 svc_machine 的单独账号,并为该账户授予所需存储库的读权限来拉取代码
- 如果在 agent 上有写仓库的需求,例如 push 代码或者打标签,我们建议:有需求的仓库给对应的 agent 创建独立的 deploy key,并给该 key 赋予写权限,同时对 ssh key 进行加密保存
(2)以 Nexus 为例,在制品库平台上为 CI/CD 平台的 agent 创建单独的账户。例如,创建
减少使用特权(root)账号
在任何系统的日常管理工作中,在非必要的情况下,我们强烈建议不要使用特权(root)账号来进行操作。特权账号具有系统所有权限,疏忽和不慎的操作有可能带来极大的损失。如果是在多人管理的情况下,也会增加账号泄漏的风险。同时,我们强烈建议对于特权账号施行一切必要的安全管理,比如强密码,开启多重验证,及时的操作审计等。
优点:
- 提升安全性:一旦特权账号泄露,会导致系统数据被破坏或者被盗取
- 降低系统风险:若使用特权账户不慎操作系统设置,可能会造成严重后果
缺点:
- 降低工作效率:某些工作若需要特殊权限,申请特权账号会影响员工的工作效率
- 服务可能会产生异常:一些特殊服务需要特权账号,普通用户账号可能会导致系统或应用程序出现故障或不可用
实施要点:
(1)保护和减少使用云服务账号根用户(以 AWS 为例):
- 在创建 AWS 账户时,会有一个根用户名和密码,以登录 AWS Management Console。不建议为该根用户生成访问密钥,也不要将根用户用于日常任务。
- 仅使用根用户执行那些只能由 root 用户执行的任务,创建其他专门的用户来执行其他任务
(2)限制应用程序的权限
- 容器中的服务尽量使用普通账号:在编写 Dockerfile 时,使用 USER 关键字限定使用运行的专用账户,避免使用 root 用户。
- 避免使用特权模式:在容器启动时,不要使用特权模式(如--privileged选项),以限制容器的权限。
- 如果使用 Kubernetes,则可以 在 securityContext 中增加 allowPrivilegeEscalation: false 避免容器越权
(3)日常操作数据库时,应使用普通权限的账号而非管理员账号
(4)加强对特权账号的审计和监管
使用角色而非用户账号
用户应该被分配到特定的角色,这些角色决定了他们在系统中的访问级别。不同的角色通常被赋予一系列不同的权限。一些平台,比如AWS,支持角色使用临时认证进行获取操作权限,所以我们建议在你的业务或者操作支持的情况下,使用角色 (Role) 而非用户账号来完成对应的操作。
优点:
- 增强安全性:使用角色进行临时认证可以减少永久凭证的使用,从而降低潜在的安全风险。临时凭证在一段时间后会自动失效,减少了凭证泄露或被滥用的风险
- 简化管理:角色的临时认证可以避免在每个用户账号上设置和管理长期凭证的复杂性。相反,我们只需为角色配置适当的权限,并让用户通过临时凭证来获取访问权限。
- 提高灵活性:角色的临时认证允许根据需要授予用户临时的特定权限。这使得我们可以按需分配访问权限,并在不同的操作场景中灵活控制用户的权限级别。
缺点:
- 增加复杂性:角色的临时认证通常涉及更多的设置和配置步骤,相比直接使用用户账号进行认证可能更为复杂。特别是对于初次接触和不熟悉角色概念的人员来说,这可能需要额外的学习和配置成本。
- 可用性和延迟:由于临时凭证的过期时间,用户可能需要定期重新获取凭证以维持访问权限。这可能导致一些中断或延迟,特别是在凭证过期前用户未及时获取新凭证的情况下。
- 授权复杂性:角色的临时认证可能需要更精细的权限设置和授权过程。您需要仔细定义和配置角色的权限范围,以确保用户具有足够的权限执行任务,同时避免过度授权导致安全风险。
- 平台限制:并非所有平台都支持角色的临时认证或具有相同的实现方式。在考虑使用角色进行临时认证时,需要确保目标平台支持并提供适当的功能和集成选项。
实施示例:
(1)例如 AWS:AWS Identity and Access Management (IAM) 提供了角色的临时认证功能。这使得我们可以方便地创建角色,并使用临时凭证来获取对 AWS 资源的操作权限,而无需使用长期凭证(如用户名和密码)。以下是一个具体的例子:假设我们在 AWS 上有一个 EC2 实例,并且想要让该实例能够访问 S3 存储桶。以下是如何使用角色进行临时认证的具体步骤:
通过使用角色的临时认证,可以避免在 EC2 实例上设置和管理长期凭证。相反,EC2 实例可以通过角色来获取所需的临时凭证,并且这些凭证具有定义的 S3 访问权限。这提高了安全性,并简化了凭证管理过程。
请注意,上述示例仅适用于AWS,并且是一个具体的用例。其他平台和服务可能具有类似的功能和实现方式,但具体细节可能会有所不同。而且上述的步骤在实际的使用中是需要 as code 的,拒绝任何人为的步骤。
- 创建角色:使用 IAM 服务创建一个名为"EC2-S3-Access-Role"的角色。在角色策略配置中,为该角色授予适当的S3访问权限。
- 配置实例:将"EC2-S3-Access-Role"角色分配给 EC2 实例。可以在 EC2 实例的启动配置或实例配置中指定所需的角色。
- 获取临时凭证:在 EC2 实例中,使用实例配置角色(Instance Profile)来获取临时凭证。这些凭证将包含"EC2-S3-Access-Role"角色所授予的 S3 访问权限。
- 访问 S3 存储桶:使用获取的临时凭证,EC2 实例现在可以通过 AWS SDK 或 AWS 命令行工具访问指定的 S3 存储桶,而无需使用用户名和密码。
(2)例如 Github:在 Github 中的组织中,我们可以创建团队,为团队分配权限和访问控制。通过创建团队,可以将一组人员组织在一起,并为他们分配某个代码仓库的特定的权限角色,例如 Admin/Write/Read 等 role,分别对应读取或写入等操作代码仓库的权限。这样,我们可以更容易地管理团队成员的访问权限,而不是单独为每个成员设置权限。
对于长期凭证,定期轮换密码或访问密钥
长期凭证(如密码、访问密钥、证书等)是指用于身份验证和授权的凭证,它们被分配给个人或应用程序,以便它们可以访问系统或服务。长期凭证容易被盗用或泄露,如果不及时轮换,可能会导致安全漏洞。定期轮换长期凭证是一种重要的安全管理措施,可以帮助组织降低风险,符合安全合规要求,防止不可撤销的访问权限,并提高安全意识。
优点:
- 控制泄露影响:通过限制可用周期减少凭证泄漏产生的影响。
- 降低泄露范围:可以确定使用方的使用状态,清理未使用的凭证,降低泄漏的范围。
- 符合标准:帮助系统通过 PCI-DSS 等强制标准。
缺点:
- 需要进行额外的操作:进行轮换时可能需要停止服务,对用户会有一定影响。
- 沟通成本高:可能需要与多方进行沟通,共同商定轮换时间,如有一方未能按照约定进行轮换,仍然会对部分用户造成影响。
- 产生意外影响:进行轮换时可能会遇到意料之外的情况,如配置错误导致服务不可用。
- 增加管理成本:如需要密码管理器或是设备进行存储,需要配置额外的监控系统对轮换时间进行监控。
实施示例:
(1)对需要轮换的凭证设置监控或通知,务必确保监控或通知系统的可用性。
- 对 HTTPS TLS 证书可以通过外部监控系统对其过期时间进行监控,对于其他类型的凭证可以设置一个计划任务,及时提醒更换。
- 定期测试告警系统的通知是否送达。
(2)对更换周期要仔细斟酌,没有适合所有系统的最优解。
(3)使用密钥扫描工具对代码库进行扫描,避免代码中出现硬编码的密钥,例如:
- GitHub 可以在 Settings - Security - Code security and analysis 启用 Secret scanning
- 使用 TruffleHog、git-secrets、GitGuardian 等工具将密钥扫描集成在 CI/CD 中,可参考OWASP 的这一篇。
(4)定期检查证书是否需要使用较新的 cipher,增强系统安全性。
(5)记录和完善文档
- 及时完善各类凭证生成及验证方法的文档,确保新生成的凭证可以在系统中使用
- 对集成方进行记录,确保在更换时可以找到相应 Point Of Contact
最小化权限原则
最小化权限原则是指系统的每个程序或者用户都应该使用完成工作所需的最小权限工作。最小权限原则限制操作所需的权限,降低账号或者系统在被恶意利用时造成的损失。因此在给账号或者角色赋权时,尽可能只赋予操作所需的权限,应为用户提供履行其工作职责所需的最低访问级别,而非随意扩大权限范围,这有助于降低意外或故意滥用特权的风险。即使我们需要给一些临时的操作赋权,也不要赋予不必要的额外权限,并在操作完成之后清理临时权限。如有可能,我们也建议新建临时账号来完成此类操作,而非扩大原有账号的权限。
优点:
- 减少安全漏洞的风险:在不存在提权漏洞情况下,攻击者只能执行对该用户所授权的操作。
- 限制数据泄露的风险:同上,攻击者只能访问该用户被允许的文件。
- 简化权限管理:降低对权限管理的工作量,可以快速确定使用范围。
- 便于审计:随时吊销清理不必要的权限,降低系统的攻击面。
缺点:
- 增加管理的复杂性:即使是使用权限组的情况下,仍有可能会增加管理的复杂性,尤其是存在较多权限组时。
- 影响工作效率:在限制访问的情况下,做一件复杂的事时可能需要反复切换账号。
- 增加系统开发的成本:如果是正在开发中的系统,可能会增加系统开发的成本。
实施要点:
- 要权衡安全和效率的关系,对基础权限应主动给予,其他权限应评估后授予。
- 不给予太过宽泛的权限,即使是用于测试,以此避免滥用的可能性。例如:在使用 CI 部署 AWS EC2 实例时,不应该为了方便而给予 ec2:* 这样的权限,而是应该仔细查看权限列表,只授予需要的最小权限列表。
- 应定期审查和更新权限,及时收回不必要的权限,降低攻击和滥用风险。
- 对于 Linux 中的程序,必要时可使用 AppArmor 或是 SELinux 增强其权限管理。
定期查看并移除未使用的用户、角色、权限等凭证
我们建议定期去查看系统中是否有未被使用的凭证信息,如果发现要及时进行清理或禁用,以防止不必要的访问权限和潜在的安全风险,提高安全水平。
优点:
- 降低凭证泄漏的影响:避免通过找回早期生成的凭证对系统进行操作。
- 降低管理成本:对长期未使用的凭证进行清理可以简化系统的管理和审计过程。
减少混淆:可以直接专注于真正在使用中的用户、角色和权限。
缺点:
- 有误删风险:维护的过程中有误删的可能,有一定造成业务系统中断的风险。
- 增加工作量:需要定期检查,有对用户造成不便的可能,但对于多数系统来说仍然是推荐的做法。
实施要点:
- 及时对未使用的凭证进行清理,以避免过度堆积造成审计负担。
- 在未确定是否仍在使用的情况下不要激进武断地删除凭证。
- 可以使用自动化工具对凭证进行扫描,对近期未使用的凭证/用户进行清理。例如:对于 AWS 可配置 AWS Config iam-user-unused-credentials-check 来辅助检查。
分离开发、测试和生产环境权限
我们日常大部分的工作场景都有多个环境,我们建议对于开发、测试和生产环境应该分别有不同的权限管理策略,以确保每个环境都具有正确的访问权限,并且不会影响其他环境的安全性。
优点:
- 增强生产环境的安全性:对生产环境权限的严格控制,可以最大限度地确保生产环境的安全,从权限上防止误操作导致脏数据、恶意删库等行为。
- 提升非生产环境的权限:不同的权限管理策略,可以最大化地给予开发人员和测试人员在开发、测试环境的权限。并且使得他们在不受到权限限制影响的同时,也不用担心会影响到生产环境的安全。
缺点:
- 紧急情况时流程复杂:当遇到特殊的线上问题且无法在其他环境复现时,如果此时没有足够的生产权限,则需要申请生产环境权限,流程审批复杂时会浪费时间。
实施要点:
- 各个环境的权限应该由专门团队来统一管理和分发
- 对申请人的权限进行分发时需要经过该项目团队负责人的同意
- 权限的创建要遵循权限最小化原则,比如读写权限分离。
实施示例:
以 AWS 为例,对于部署在 AWS 上的服务,我们建议:
(1)将开发,测试和生产环境账号分开,部署在不同的 AWS Account 里,实现整个环境的隔离
(2)分别为用户在不同环境创建不同权限的 IAM role,例如:
- Example_dev_admin
- Example_dev_readonly
- Example_prod_admin
- Example_prod_readonly
使用强密码策略
我们强烈建议使用强密码策略,一个安全的密码应该不少于12个字符,至少有三种不同的字符,如数字,特殊字符,大小写字母。应避免在密码中包含个人信息,如出生日期或名字,宠物或乐队。还要避免歌词,伴侣和常用词组等。并且我们建议不要使用重复密码,尽可能在不同的系统中使用不同的密码,并定期更换密码。
优点:
- 提高安全性:使用强密码策略可以大大提高账户的安全性。强密码通常更难以猜测、破解或猜测,因此更难被恶意用户破解并获取对账户的未授权访问。
- 防止撞库:在不同的系统中使用不同的密码,防止其他系统密码意外泄漏后被撞库。
- 减少数据损失:如果密码发生泄漏,定期更换密码可以减少数据损失。
- 减少密码泄露风险:使用强密码策略可以减少密码泄露的风险。强密码难以通过常见的攻击手段(如字典攻击、暴力破解、社交工程等)破解,从而降低账户被黑客入侵的可能性。
缺点:
- 用户体验低:使用强密码策略可能会给用户带来不便。长、复杂的密码可能难以记忆,并可能需要经常更改密码。这可能导致用户重复使用密码、写下密码或寻求其他不安全的方法。
- 易忘记密码:由于密码的复杂性,用户可能更容易忘记密码。这可能导致密码重置的频率增加,给用户和支持团队带来额外的负担。
- 密码管理挑战:对于具有多个账户和复杂密码要求的用户来说,管理和记忆所有密码可能成为挑战。这可能导致用户使用密码管理器或其他自动化工具,或者采用不安全的解决方案。
实施示例:
例如 AWS:可以在 AWS IAM 中设置如下的用户密码策略,任何用户的密码必须遵守设置的策略:
- 设置密码最小长度,AWS 支持密码长度设置在 6-128 范围内。
- 设置密码强度,例如至少需要一个大写字母、至少需要一个小写字母、至少需要一个数字或者至少需要一个字符。
- 设置密码过期时间,例如设置为 90 天。
- 设置密码过期需要管理员重置。
- 防止密码重复使用,例如不能将密码设置为之前设置过的密码。
使用多重验证(MFA)
多重验证(MFA)是一个额外的安全措施,要求用户在被授予系统访问权限之前提供多种形式的身份验证。这可能包括发送到手机或其他设备的密码或代码。如果对应的系统支持多重验证,我们建议开启使用多重验证功能。并且不要把密码管理工具和MFA工具安装在同一设备上。
优点:
- 提供多层保障:可以提高账户的安全保障,如果密码不小心泄漏,多重验证可以提供第二层保护。
- 账户被盗可能性最小化:由于 MFA 可能是面部识别、指纹或者一次性密码,所以被盗取的可能性非常小。
- 防止账户劫持:多重验证可以有效防止恶意用户劫持他人的账户。除了知道密码外,攻击者还需要访问用户所拥有的其他验证因素,才能成功冒充用户。
- 合规性要求:在某些行业和法规中,使用多重验证可能是强制性的要求。例如,支付卡行业(PCI DSS)对进行支付交易的账户要求启用多重验证。
缺点:
- 用户体验烦琐:使用多重验证可能会增加用户登录过程的复杂性和时间。用户需要提供额外的验证因素,并可能需要额外的设备或应用程序来完成验证。
- 依赖额外设备:某些多重验证方法可能需要额外的硬件设备(如硬件令牌)或应用程序(如身份验证器应用程序)。用户需要确保这些设备或应用程序可靠,并妥善保管。
- 丢失或损坏的设备:如果用户的多重验证设备丢失或损坏,他们可能会面临账户被锁定的风险。在这种情况下,恢复访问账户可能需要额外的步骤和时间。
实施要点:
- 选择适当的验证因素:确定适合我们当前环境和用户的验证因素类型。常见的验证因素包括密码、手机验证码、硬件令牌、身份验证器应用程序(如Google Authenticator)和生物识别(如指纹或面部识别)。根据实际需求和安全要求,选择一个或多个验证因素。推荐使用硬件密钥增强安全性和易用性,尽量不使用短信验证方式。
- 启用强制性多重验证:对于敏感账户和重要权限的用户,应强制启用多重验证。确保所有用户了解并遵守多重验证政策,以保护账户的安全。
- 必要情况下可以强制添加两种及以上的多重验证
开启审计日志
如果你的系统支持记录审计日志,我们建议开启审计日志并保存至少半年的记录。审计日志本身是法律刚性需求,是安全合规性检查的必备材料之一。
优点:
- 安全监控:审计日志提供了对环境活动和操作的完整可见性,能够监控和检测潜在的安全威胁、漏洞或异常行为。
- 审计和合规性:审计日志可以用于满足合规性要求,并支持安全审计和调查。它们记录了谁在何时进行了什么操作,为审核和合规性证明提供了关键的依据。
- 故障排除和故障恢复:审计日志可以帮助我们进行故障排除,追踪问题的根源,并支持故障恢复过程。
- 调查和取证:审计日志可以用于调查安全事件、追踪攻击来源以及为法律或法规要求收集证据。
- 分析和洞察:审计日志提供了对环境活动的可追溯记录,可以用于分析和获取有关资源使用、访问模式和行为趋势的洞察。
缺点:
- 存储成本增加:启用审计日志可能会增加存储成本,尤其是在有大量活动和长期保留需求的情况下。存储和保留审计日志可能需要额外的资源和成本。
- 处理复杂性:审计日志可能会产生大量的事件和日志数据,需要适当的工具和技术来处理和分析这些数据。处理大量的日志数据可能需要投入时间和资源。
- 隐私和合规性考虑:审计日志可能包含敏感信息,因此必须遵守适用的隐私和合规性要求,例如数据保护和数据保留政策。
实施要点:
- 选择合适的审计日志工具:例如:在 AWS 上,可以使用 AWS CloudTrail 来记录和监控环境的活动。确保正确配置和启用 CloudTrail,并根据需求设置适当的日志保留期限和存储位置。
- 定义审计日志策略:制定和文档化审计日志策略,明确记录哪些活动和事件应该被审计。根据实际需求和合规性要求,确定需要记录的资源类型、操作类型和级别。
- 审核访问权限:审查和验证用户和角色的访问权限,确保只有授权的实体能够访问和修改审计日志。采用最小特权原则,仅授予必要的权限以防止潜在的滥用。
- 配置日志存储和保留期:确定审计日志的存储位置和保留期。根据合规性要求和业务需求,选择适当的存储服务和设置合理的保留期限。
- 配置自动化审计策略,实时监控和警报:建立实时监控和警报机制,以便对重要的活动和事件及时做出响应。例如使用 AWS CloudWatch、AWS EventBridge 或其他警报服务来监控审计日志,检测异常或可疑的活动。
- 日志分析和可视化:使用适当的日志分析工具和技术,对审计日志进行分析、搜索和可视化。这有助于快速发现潜在的安全威胁、异常行为或合规性问题。
- 定期审查和检查:定期审查审计日志,检查活动和事件的记录,并及时调查任何异常或可疑的情况。根据需要,更新和改进审计日志策略和设置。
- 合规性要求:根据适用的合规性要求(如 GDPR、HIPAA、PCI DSS 等),确保审计日志的实施符合相关标准和规定。
- 培训和意识:提供培训和意识活动,确保相关人员了解审计日志的重要性、使用方法和最佳实践。培养团队对审计日志的积极态度和有效利用。审计应该由不同的人员执行,以确保权限分配的公正性和准确性。
- 持续改进:根据实际情况和反馈,持续改进审计日志实施。定期评估并更新审计日志策略、工具和流程,以适应变化的需求和威胁。