深色模式
访问控制合规:权限分离与最小化授权
摘要:访问控制的核心是"职责分离 + 按需授权 + 定期复核",避免出现一个人能独立完成"操作 + 审批 + 抹日志"的完整链条。本文给出 Linux 与数据库侧的分离方案与复核脚本。
适用环境
bash
cat /etc/os-release
getent group | grep -E 'wheel|sudo|adm'
ls /etc/sudoers.d/
command -v mysql && mysql --version1
2
3
4
2
3
4
操作步骤
1. 设计三类角色,账号物理分离
| 角色 | 职责 | 典型权限 | 禁止 |
|---|---|---|---|
| 系统管理员 sysadmin | 配置、部署 | 服务管理、应用目录写 | 不得修改审计配置 |
| 安全管理员 secadmin | 安全策略 | 账号/口令策略、防火墙 | 不得改业务配置 |
| 审计管理员 auditor | 审计 | 只读日志与审计记录 | 不得做任何写操作 |
bash
groupadd sysadmin secadmin auditor
useradd -m -G sysadmin sys_li
useradd -m -G secadmin sec_wang
useradd -m -G auditor aud_zhao
id sys_li; id sec_wang; id aud_zhao1
2
3
4
5
2
3
4
5
2. sudoers:按角色给最小命令集
bash
cat >/etc/sudoers.d/10-sysadmin <<'EOF'
%sysadmin ALL=(root) /bin/systemctl restart *, /bin/systemctl status *, \
/usr/bin/journalctl *
%sysadmin ALL=(svc_app) NOPASSWD: /opt/myapp/bin/deploy.sh
EOF
cat >/etc/sudoers.d/20-secadmin <<'EOF'
%secadmin ALL=(root) /usr/sbin/nft, /usr/sbin/iptables, \
/usr/sbin/useradd, /usr/sbin/usermod, /bin/chage
EOF
cat >/etc/sudoers.d/30-auditor <<'EOF'
%auditor ALL=(root) NOPASSWD: /usr/bin/journalctl, /usr/bin/ausearch, \
/usr/bin/last, /usr/bin/lastlog, /bin/cat /var/log/*
EOF
chmod 0440 /etc/sudoers.d/1* /etc/sudoers.d/2* /etc/sudoers.d/3*
visudo -c1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
允许 auditor 执行 cat /var/log/* 仍可能读到敏感内容
更严格的做法是只给 journalctl/ausearch,日志内容本身由集中日志平台的只读角色控制。
3. 保护审计配置不被操作者改动
bash
chown root:root /etc/audit/rules.d/ /etc/rsyslog.conf
chmod 750 /etc/audit/rules.d/
# auditd 规则里监控审计配置自身
cat >/etc/audit/rules.d/98-audit-protect.rules <<'EOF'
-w /etc/audit/ -p wa -k audit_config
-w /etc/rsyslog.conf -p wa -k syslog_config
-w /var/log/audit/ -p wa -k audit_log
EOF
augenrules --load1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
4. 数据库侧权限分离
sql
-- 应用账号只给 DML,不给 DDL
CREATE USER 'app_rw'@'10.0.%' IDENTIFIED BY 'StrongPass!2026';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app_rw'@'10.0.%';
-- 只读账号给报表/排障
CREATE USER 'app_ro'@'10.0.%' IDENTIFIED BY 'StrongPass!2026';
GRANT SELECT ON appdb.* TO 'app_ro'@'10.0.%';
-- DBA 账号限制来源
CREATE USER 'dba_admin'@'10.0.0.5' IDENTIFIED BY 'StrongPass!2026';
GRANT ALL PRIVILEGES ON *.* TO 'dba_admin'@'10.0.0.5' WITH GRANT OPTION;
SHOW GRANTS FOR 'app_rw'@'10.0.%';1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
原则:应用账号无 DROP/GRANT;管理账号限定来源 IP;禁止应用使用 root/sa。
5. 服务进程降权
ini
# /etc/systemd/system/myapp.service
[Service]
User=svc_app
Group=svc_app
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/myapp
CapabilityBoundingSet=1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
bash
systemctl daemon-reload && systemctl restart myapp
systemctl show myapp -p User -p NoNewPrivileges1
2
2
6. 周期性权限复核(每季度)
bash
cat >/usr/local/bin/perm-review.sh <<'EOF'
#!/bin/bash
echo "== UID 0 =="; awk -F: '$3==0 {print $1}' /etc/passwd
echo "== sudo 授权 =="; for f in /etc/sudoers.d/*; do echo "--- $f"; grep -v '^#' "$f"; done
echo "== 90 天未登录 =="; lastlog -b 90 | grep -v "Never logged in" | tail -n +2
echo "== 空口令 =="; awk -F: '$2=="" {print $1}' /etc/shadow
echo "== 全局可写 =="; find /etc /opt -xdev -type f -perm -0002 -ls 2>/dev/null | head
EOF
chmod +x /usr/local/bin/perm-review.sh1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
验证
bash
sudo -l -U sys_li; sudo -l -U sec_wang; sudo -l -U aud_zhao
visudo -c
# 越权尝试应被拒绝
sudo -u aud_zhao sudo systemctl restart nginx # 应 deny
systemctl show myapp -p User -p NoNewPrivileges
ausearch -k audit_config --start today1
2
3
4
5
6
2
3
4
5
6
判定标准:三角色权限互斥;审计配置变更有告警;服务非 root 运行;复核脚本输出可归档。
常见坑
三权分立做成了同一个人三个账号
形式分离没意义。必须落到不同的人,且审批与操作分离。
sudoers 里用通配符 * 放得太开
/bin/systemctl restart * 已算宽松,若写成 ALL=(ALL) ALL 就等于 root。逐命令白名单化。
审计管理员被授予了写权限
审计员能改日志就失去了审计意义。只读是硬要求。
应用直连数据库用超级用户
一旦应用被 RCE,整个实例沦陷。按库、按操作类型拆分账号。
复核只做一次
人员变动、临时授权是常态。权限复核必须季度化并留记录。