06 — 权限管理与访问控制(HBAC + Sudo)

6.1 核心概念:三层权限体系

FreeIPA 使用三层权限模型来精确控制谁能访问什么:

第一层:HBAC(Host-Based Access Control)      ← 控制"能不能登录"
第二层:Sudo Rules                              ← 控制"能用 sudo 做什么"
第三层:Role-Based Access Control (RBAC)        ← 控制"能管理 FreeIPA 的哪些部分"

6.2 第一层:HBAC(基于主机的访问控制)

6.2.1 什么是 HBAC?

HBAC(Host-Based Access Control)控制哪些用户可以登录哪些主机,提供哪些服务。

默认规则 allow_all:任何人都能登录任何主机 ← 不安全,需要定制
自定义规则:开发组只能登录开发服务器,运维组只能登录运维服务器

6.2.2 创建 HBAC 规则

场景:开发组只能访问开发服务器

# 1. 创建用户组
ipa group-add developers
 
# 2. 创建主机组
ipa hostgroup-add dev-servers --desc="开发服务器组"
 
# 3. 将主机加入主机组
ipa hostgroup-add-member dev-servers --hosts=dev.thinkmeta.site
 
# 4. 创建 HBAC 规则
ipa hbacrule-add dev-access --desc="开发人员访问开发服务器"
 
# 5. 关联用户组
ipa hbacrule-add-user dev-access --groups=developers
 
# 6. 关联主机组
ipa hbacrule-add-host dev-access --hostgroups=dev-servers
 
# 7. 关联服务(允许所有服务)
ipa hbacrule-add-service dev-access --hbacsvcs=sshd

场景:禁止 root 通过 SSH 登录(安全最佳实践)

# 创建拒绝 root SSH 的规则
ipa hbacrule-add deny-root-ssh --desc="禁止 root SSH 登录"
 
# 将 root 用户加入规则
ipa hbacrule-add-user deny-root-ssh --users=root
 
# 关联所有主机
ipa hbacrule-add-host deny-root-ssh --hostcat=all
 
# 关联 sshd 服务
ipa hbacrule-add-service deny-root-ssh --hbacsvcs=sshd
 
# 设置为拒绝规则
ipa hbacrule-mod deny-root-ssh --type=deny

6.2.3 HBAC 规则组成要素

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   谁(Who)    │    │ 去哪里(Where)│    │  做什么(How) │
│ 用户/用户组  │    │ 主机/主机组  │    │  服务/服务组 │
└─────────────┘    └─────────────┘    └─────────────┘
        │                 │                  │
        └─────────┬───────┴──────────────────┘
                  │
          ┌───────▼───────┐
          │  HBAC Rule    │
          │  允许 / 拒绝  │
          └───────────────┘

6.2.4 管理 HBAC 规则

# 查看所有 HBAC 规则
ipa hbacrule-find
 
# 查看规则详情
ipa hbacrule-show dev-access
 
# 查看某个用户被哪些规则影响
ipa hbactest --user=zhangsan --host=dev.thinkmeta.site --service=sshd
 
# 修改规则
ipa hbacrule-mod dev-access --desc="更新描述"
 
# 删除规则
ipa hbacrule-del dev-access
 
# 查看默认规则
ipa hbacrule-find allow_all

6.2.5 最佳实践:关闭默认 allow_all

# 查看默认规则
ipa hbacrule-show allow_all
 
# 禁用默认规则(强烈建议!)
ipa hbacrule-disable allow_all
 
# 然后创建具体的访问规则替代

6.3 第二层:Sudo 规则管理

6.3.1 为什么集中管理 Sudo?

传统方式:                         FreeIPA 方式:
/etc/sudoers 每台机器都要改          一处定义,全集群生效
sudo visudo 容易出错                 Web UI 或 CLI 管理
审计困难                           集中审计日志
离职后遗留 sudo 权限                禁用用户即可

6.3.2 创建 Sudo 规则

场景一:开发组可以免密码重启开发服务器上的服务

# 1. 创建 Sudo 规则
ipa sudorule-add dev-sudo-services --desc="开发组可重启服务"
 
# 2. 允许执行的命令
ipa sudorule-add-allow-command dev-sudo-services \
  --sudocmds="/usr/bin/systemctl restart *" \
  --sudocmds="/usr/bin/systemctl stop *" \
  --sudocmds="/usr/bin/systemctl start *" \
  --sudocmds="/usr/bin/systemctl status *"
 
# 3. 关联用户组
ipa sudorule-add-user dev-sudo-services --groups=developers
 
# 4. 关联主机组
ipa sudorule-add-host dev-sudo-services --hostgroups=dev-servers
 
# 5. 设置免密码(NOPASSWD)
ipa sudorule-add-option dev-sudo-services --sudooption='!authenticate'

场景二:运维组拥有完全 sudo 权限

# 创建运维 sudo 规则
ipa sudorule-add ops-full-sudo --desc="运维组完全 sudo 权限"
 
# 允许所有命令
ipa sudorule-add-allow-command ops-full-sudo --sudocmds=ALL
 
# 关联用户组(添加命令组)
ipa sudorule-add-user ops-full-sudo --groups=operations
 
# 关联所有主机
ipa sudorule-add-host ops-full-sudo --hostcat=all
 
# 需要密码验证(不给 NOPASSWD)
# 不添加 !authenticate 选项即默认需要密码

场景三:DBA 只能用特定命令访问数据库服务器

# 创建命令组
ipa sudocmdgroup-add db-admin-cmds --desc="数据库管理命令"
 
# 添加具体命令
ipa sudocmd-add "/usr/bin/systemctl restart mysql"
ipa sudocmd-add "/usr/bin/systemctl restart postgresql"
 
# 将命令加入命令组
ipa sudocmdgroup-add-member db-admin-cmds \
  --sudocmds="/usr/bin/systemctl restart mysql" \
  --sudocmds="/usr/bin/systemctl restart postgresql"
 
# 创建 Sudo 规则
ipa sudorule-add dba-admin-sudo --desc="DBA 管理数据库"
 
# 关联命令组
ipa sudorule-add-allow-command dba-admin-sudo --sudocmdgroups=db-admin-cmds
 
# 关联用户组和主机组
ipa sudorule-add-user dba-admin-sudo --groups=dba
ipa sudorule-add-host dba-admin-sudo --hostgroups=db-servers

6.3.3 管理 Sudo 规则

# 查看所有 Sudo 规则
ipa sudorule-find
 
# 查看规则详情
ipa sudorule-show dev-sudo-services
 
# 查看 Sudo 命令
ipa sudocmd-find
 
# 禁用规则
ipa sudorule-disable dev-sudo-services
 
# 启用规则
ipa sudorule-enable dev-sudo-services
 
# 删除规则
ipa sudorule-del dev-sudo-services

6.3.4 在客户端验证 Sudo 规则

# 客户端刷新 SSSD 缓存(规则修改后需要)
sudo sss_cache -E
 
# 查看当前用户的 sudo 权限
sudo -l
 
# 作为特定用户查看 sudo 权限
sudo -l -U zhangsan

6.4 第三层:RBAC(基于角色的权限委派)

6.4.1 什么是 RBAC?

控制 FreeIPA 管理权限的委派。比如赋权某个人可以管理用户但不能管理主机。

角色(Role) → 权限(Permission) → 特权(Privilege)

6.4.2 创建角色委派

场景:让运维组长可以管理用户,但不能修改配置

# 1. 创建特权(Privilege — 一组权限的集合)
ipa privilege-add "用户管理" --desc="创建/修改/删除用户和组"
 
# 2. 为特权分配权限
ipa privilege-add-permission "用户管理" \
  --permissions="System: Add Users" \
  --permissions="System: Modify Users" \
  --permissions="System: Remove Users" \
  --permissions="System: Add Groups" \
  --permissions="System: Modify Groups" \
  --permissions="System: Remove Groups"
 
# 3. 创建角色
ipa role-add user-admin --desc="用户管理员"
 
# 4. 将特权赋予角色
ipa role-add-privilege user-admin --privileges="用户管理"
 
# 5. 将角色赋予用户/用户组
ipa role-add-member user-admin --users=ops-leader

6.4.3 查看内置权限

# 查看所有权限
ipa permission-find
 
# 查看所有特权
ipa privilege-find
 
# 查看所有角色
ipa role-find
 
# 查看角色的权限明细
ipa role-show "User Administrator" --all

6.5 实战:建立完整的权限体系

以下是一个中型团队的实际配置方案:

#!/bin/bash
# init-access-control.sh — 初始化权限体系
 
DOMAIN="thinkmeta.site"
 
echo "=== 初始化 FreeIPA 权限体系 ==="
 
# ─── 1. 创建组织架构组 ───
echo "--- 创建组织架构组 ---"
ipa group-add all-employees --desc="全体员工"
ipa group-add engineering --desc="工程部"
ipa group-add operations --desc="运维部" 
ipa group-add dba --desc="DBA 团队"
 
ipa group-add-member all-employees --groups=engineering,operations,dba
 
# ─── 2. 创建主机分组 ───
echo "--- 创建主机分组 ---"
ipa hostgroup-add all-servers --desc="所有服务器"
ipa hostgroup-add dev-servers --desc="开发服务器"
ipa hostgroup-add prod-servers --desc="生产服务器"
 
# ─── 3. 创建 HBAC 规则(替换默认 allow_all)───
echo "--- 创建 HBAC 规则 ---"
 
# 禁用默认规则
ipa hbacrule-disable allow_all 2>/dev/null
 
# 运维组可访问所有服务器
ipa hbacrule-add ops-access --desc="运维组访问所有服务器"
ipa hbacrule-add-user ops-access --groups=operations
ipa hbacrule-add-host ops-access --hostcat=all
ipa hbacrule-add-service ops-access --hbacsvcs=sshd
 
# 开发组只能访问开发服务器
ipa hbacrule-add dev-access --desc="开发组访问开发服务器"
ipa hbacrule-add-user dev-access --groups=engineering
ipa hbacrule-add-host dev-access --hostgroups=dev-servers
ipa hbacrule-add-service dev-access --hbacsvcs=sshd
 
# DBA 只能访问生产服务器
ipa hbacrule-add dba-access --desc="DBA 访问生产服务器"
ipa hbacrule-add-user dba-access --groups=dba
ipa hbacrule-add-host dba-access --hostgroups=prod-servers
ipa hbacrule-add-service dba-access --hbacsvcs=sshd
 
# ─── 4. 创建 Sudo 规则 ───
echo "--- 创建 Sudo 规则 ---"
 
# 运维组 — 完全 sudo 权限(需密码)
ipa sudorule-add ops-sudo
ipa sudorule-add-allow-command ops-sudo --sudocmds=ALL
ipa sudorule-add-user ops-sudo --groups=operations
ipa sudorule-add-host ops-sudo --hostcat=all
 
# 开发组 — 有限 sudo(免密码重启服务)
ipa sudorule-add dev-sudo
ipa sudorule-add-allow-command dev-sudo \
  --sudocmds="/usr/bin/systemctl restart *" \
  --sudocmds="/usr/bin/systemctl stop *" \
  --sudocmds="/usr/bin/systemctl start *" \
  --sudocmds="/usr/bin/systemctl status *"
ipa sudorule-add-user dev-sudo --groups=engineering
ipa sudorule-add-host dev-sudo --hostgroups=dev-servers
ipa sudorule-add-option dev-sudo --sudooption='!authenticate'
 
echo "=== 权限体系初始化完成 ==="

6.6 权限验证与审计

查看谁可以登录哪台机器

# 测试特定用户能否登录特定主机
ipa hbactest --user=zhangsan --host=dev.thinkmeta.site --service=sshd
# 输出:
# Access granted: True      ← 允许
# Matched rules: dev-access
 
# 测试被拒绝的情况
ipa hbactest --user=zhangsan --host=prod.thinkmeta.site --service=sshd
# Access granted: False     ← 拒绝

查看用户拥有哪些 sudo 权限

# 在任意客户端执行
sudo -l -U zhangsan

查看 FreeIPA 审计日志

# 查看认证日志
ipa automember-find
 
# 查看 HBAC 拒绝事件(需要安装 audit 插件)
# 在客户端
sudo journalctl -u sssd | grep -i "access denied"

6.7 常见问题

Q1:创建了 HBAC 规则但不生效?

  1. 检查是否禁用了 allow_all 默认规则
  2. 确认规则服务包含 sshd
  3. 确认主机已加入正确的主机组
  4. 客户端执行 sudo sss_cache -E 刷新缓存,然后 sudo systemctl restart sssd

Q2:Sudo 规则不生效?

# 客户端强制刷新
sudo sss_cache -E
sudo systemctl restart sssd
 
# 检查 sssd 日志
sudo journalctl -u sssd -f

Q3:如何实现”运维组不需要密码就能 sudo”?

ipa sudorule-add-option ops-sudo --sudooption='!authenticate'

Q4:HBAC 规则和 Sudo 规则的区别?

HBACSudo
控制什么能不能登录服务器登录后能执行什么命令
作用层面SSH 登录前登录后
不配置的后果用户无法 SSH 登录用户能登录但无法 sudo