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=deny6.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_all6.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-servers6.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-services6.3.4 在客户端验证 Sudo 规则
# 客户端刷新 SSSD 缓存(规则修改后需要)
sudo sss_cache -E
# 查看当前用户的 sudo 权限
sudo -l
# 作为特定用户查看 sudo 权限
sudo -l -U zhangsan6.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-leader6.4.3 查看内置权限
# 查看所有权限
ipa permission-find
# 查看所有特权
ipa privilege-find
# 查看所有角色
ipa role-find
# 查看角色的权限明细
ipa role-show "User Administrator" --all6.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 规则但不生效?
- 检查是否禁用了
allow_all默认规则 - 确认规则服务包含
sshd - 确认主机已加入正确的主机组
- 客户端执行
sudo sss_cache -E刷新缓存,然后sudo systemctl restart sssd
Q2:Sudo 规则不生效?
# 客户端强制刷新
sudo sss_cache -E
sudo systemctl restart sssd
# 检查 sssd 日志
sudo journalctl -u sssd -fQ3:如何实现”运维组不需要密码就能 sudo”?
ipa sudorule-add-option ops-sudo --sudooption='!authenticate'Q4:HBAC 规则和 Sudo 规则的区别?
| HBAC | Sudo | |
|---|---|---|
| 控制什么 | 能不能登录服务器 | 登录后能执行什么命令 |
| 作用层面 | SSH 登录前 | 登录后 |
| 不配置的后果 | 用户无法 SSH 登录 | 用户能登录但无法 sudo |