首页 / 帮助文档 / centos服务器安全系统服务权限最小化

centos服务器安全系统服务权限最小化

CentOS服务器默认安装后,很多系统服务是以root身份运行的,而且权限配置偏向“能用就行”。这种做法在公网环境里等于把攻击面直接摊开。权限最小化的核心不是把服务删光,而是让每个服务只拥有完成自身任务所必需的最小权限,一旦服务被攻破,攻击者也无法借助服务进程拿到高权限执行后续操作。下面直接讲具体怎么落地。

先审计当前服务与进程权限

动手之前先搞清楚系统里跑了哪些服务、以什么用户运行、监听了哪些端口。执行以下命令:

systemctl list-units --type=service --state=running
ps -eo user,pid,cmd | grep -E 'nginx|mysql|redis|php|java|node|tomcat'

再用ss查看端口对应的进程:

ss -tulnp

很多管理员看到输出后才会发现,Redis正用root跑在0.0.0.0:6379上,MySQL的启动用户是mysql但数据目录权限是755。这些都是典型的权限过大问题。审计结果要记录成表,包括服务名、运行用户、监听地址、配置文件路径、日志路径、数据目录路径,后续逐项收紧。

为每个服务创建独立系统用户

CentOS上用yum或dnf安装的服务通常会自动创建专用用户,比如nginx、mysql、redis。但如果是源码编译或二进制部署的服务,很多人图省事直接用root启动。正确做法是给每个服务建一个无登录权限的系统账号:

useradd -r -s /sbin/nologin -d /var/lib/myapp -M myapp

-r表示创建系统用户,UID会落在系统保留区间;-s /sbin/nologin禁止该用户登录shell;-M不创建家目录。如果服务需要写日志,再单独创建目录并授权:

mkdir -p /var/log/myapp
chown myapp:myapp /var/log/myapp
chmod 750 /var/log/myapp

不要给服务用户设置密码,也不要把它加入wheel组。每个服务一个用户,避免一个服务被攻破后横向影响其他服务的数据文件。

收紧服务配置文件与数据目录权限

服务用户对配置文件的权限应该只读,对数据目录按需读写,对日志目录可写。常见的错误是配置文件644,数据目录755,日志目录777。以Nginx为例,配置文件属于root,权限640即可,Nginx主进程以root启动读取配置后,worker进程会切换到nginx用户运行,所以配置里要明确指定:

user nginx;
worker_processes auto;

如果配置里没有user指令,Nginx worker会默认以nobody运行,权限反而不清晰。再看MySQL数据目录,标准权限应该是:

chown -R mysql:mysql /var/lib/mysql
chmod 750 /var/lib/mysql

750意味着同组用户可读可执行,其他用户完全无权限。很多教程让设成755,等于系统上任何本地用户都能读取数据库文件,配合本地提权漏洞就是灾难。

移除服务能力与内核能力边界

CentOS 7及以上的内核支持capabilities机制,可以把root的超级权限拆分成细粒度能力。对于需要绑定低端口(小于1024)的服务,传统做法是必须用root启动,但用setcap可以只授予CAP_NET_BIND_SERVICE能力:

setcap 'cap_net_bind_service=+ep' /usr/local/bin/myapp

这样myapp进程不需要root就能监听80或443端口。验证是否生效:

getcap /usr/local/bin/myapp

输出应包含cap_net_bind_service。如果服务还需要写特定系统目录,再按需添加CAP_DAC_OVERRIDE等能力,但不要直接给CAP_SYS_ADMIN,这个能力几乎等同于root。对于Java、Node这类运行时,如果业务不需要绑定低端口,就不要加任何capability,让它们跑在普通用户下监听高位端口,再用Nginx反向代理到高位端口。

用systemd加固服务运行环境

CentOS 7之后systemd是服务管理标准。与其用nohup或screen手动启动服务,不如写成systemd unit文件,利用其安全指令做隔离。一个最小化的服务unit示例:

[Unit]
Description=My Application Service
After=network.target

[Service]
Type=simple
User=myapp
Group=myapp
ExecStart=/usr/local/bin/myapp --config /etc/myapp/myapp.conf
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/var/lib/myapp /var/log/myapp
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

这里的关键指令:NoNewPrivileges=true阻止服务进程通过setuid或capability提升权限;PrivateTmp=true给服务独立的/tmp目录,防止通过临时文件攻击其他进程;ProtectSystem=full让整个文件系统对服务只读,只有ReadWritePaths列出的目录可写;ProtectHome=true隐藏/home目录。这些指令不需要修改应用代码,却能大幅降低被攻破后的破坏范围。

限制服务可访问的网络范围

权限最小化不只针对文件系统,网络层同样要收紧。数据库、缓存、消息队列这类内部服务,监听地址必须绑定到127.0.0.1或内网IP,不要监听0.0.0.0。以Redis为例,配置文件里:

bind 127.0.0.1
protected-mode yes

如果必须让内网其他机器访问,绑定到具体内网IP,并配合防火墙限制来源IP。CentOS的firewalld可以精确到端口和来源:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" port protocol="tcp" port="6379" accept'
firewall-cmd --reload

这样即使Redis本身没有鉴权,外部攻击者也无法直接连接。对于需要公网访问的服务,只开放80和443,其余端口一律不对外。

定期审计文件权限与SUID/SGID位

系统里遗留的SUID程序是权限提升的常见入口。查找所有带SUID或SGID位的文件:

find / -perm -4000 -o -perm -2000 -type f 2>/dev/null

正常系统里应该有passwd、sudo、mount等少量程序,如果出现/usr/bin/find、/usr/bin/vim这类工具带SUID位,说明有人为设置或系统被篡改。对于不需要SUID的程序,直接去掉:

chmod u-s /usr/bin/someprogram

同时检查服务目录下是否有异常可写文件:

find /var/www /var/lib/mysql /etc/myapp -type f -perm -o+w 2>/dev/null

任何other可写的配置文件或脚本都可能导致服务被注入恶意代码。

日志与监控不能放松

权限最小化不是一次性操作,需要持续监控。用auditd记录关键文件访问:

auditctl -w /etc/myapp/ -p wa -k myapp_config
auditctl -w /var/lib/mysql/ -p wa -k mysql_data

这样任何对配置或数据目录的写操作都会留下审计记录。同时定期检查服务运行用户是否被意外修改:

ps -eo user,cmd | grep -E 'nginx|mysql|redis' | awk '{print $1}' | sort | uniq -c

如果发现某个服务突然以root运行,立即排查是否有人改了启动脚本或systemd unit文件。

针对常见CentOS服务的最小化清单

SSH服务:禁止root直接登录,改用普通用户加sudo。修改/etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Nginx:主进程root仅用于读取配置和绑定端口,worker进程必须指定为nginx用户。站点目录权限750,属主为部署用户,属组为nginx,让nginx只读。

MySQL/MariaDB:只监听127.0.0.1,除非有明确远程访问需求。应用连接数据库使用独立账号,只授予对应库的SELECT、INSERT、UPDATE、DELETE权限,不要给ALL PRIVILEGES。

Redis:设置requirepass强密码,绑定内网IP,禁用危险命令:

rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command EVAL ""

PHP-FPM:每个站点使用独立的pool,每个pool用不同的系统用户运行,避免一个站点被攻破后读取其他站点文件。

权限最小化的本质是假设服务一定会被攻破,然后让攻破后的损失降到最低。CentOS服务器上每多一个以root运行的服务、每多一个0.0.0.0监听、每多一个777目录,都是给攻击者递刀。把上面的步骤逐项落实,比装十个安全插件都管用。