直接使用 root 部署是很多初学者的常见做法,但从安全和合规角度看是绝对不允许的。针对二级等保的要求,我们来详细拆解一下专业的部署做法。
二级等保的核心是 “审计” 和 “最小权限” 。你的所有操作都应该围绕着这两个核心展开。
核心思想:权限最小化与服务化
- 专属用户:为每个服务创建独立的、非登录的系统用户。
- 专属目录:每个服务只能访问它运行所必需的文件和目录,并且这些目录的权限要严格控制。
- 权限分离:运行服务的用户绝不能是
root,也不应拥有超出其功能范围的权限(如 shell 登录、读写其他服务文件等)。
第一步:准备工作(规划与创建)
在开始部署任何服务之前,先做好规划。
1. 创建专属用户和用户组
为每个服务创建一个不能登录的系统用户和一个对应的用户组。通常用户和组同名。
# 创建系统用户组
groupadd -r mysql-group
groupadd -r redis-group
groupadd -r nginx-group
groupadd -r app-group # 为你的Java应用创建
# 创建系统用户,并指定家目录(后续作为其工作目录),并禁止登录
useradd -r -g mysql-group -s /bin/false -d /usr/local/mysql mysql-user
useradd -r -g redis-group -s /bin/false -d /var/lib/redis redis-user
useradd -r -g nginx-group -s /bin/false -d /usr/local/nginx nginx-user
useradd -r -g app-group -s /bin/false -d /opt/your-java-app app-user
-r:创建系统用户。-g:指定所属用户组。-s /bin/false:禁止该用户登录系统(最安全)。-d:指定家目录,这里我们将其作为服务的工作目录。
2. 规划并创建专属目录,并授权
假设你的部署结构如下,请先创建目录并修改所有者为对应的用户。
# MySQL
mkdir -p /usr/local/mysql/{data,logs,conf}
chown -R mysql-user:mysql-group /usr/local/mysql
chmod -R 750 /usr/local/mysql # 所有者可读写执行,组用户只读,其他用户无权限
# Redis
mkdir -p /var/lib/redis /usr/local/redis/{logs,conf}
chown -R redis-user:redis-group /var/lib/redis /usr/local/redis
chmod -R 750 /var/lib/redis /usr/local/redis
# Nginx
mkdir -p /usr/local/nginx/{logs,conf,html,cache}
chown -R nginx-user:nginx-group /usr/local/nginx
chmod -R 750 /usr/local/nginx
# 注意:Nginx的web目录(如html)可能需要755,让nginx进程可以读取静态文件
chmod 755 /usr/local/nginx/html
# Java Application
mkdir -p /opt/your-java-app/{logs,config,data}
chown -R app-user:app-group /opt/your-java-app
chmod -R 750 /opt/your-java-app
第二步:具体服务配置
1. MySQL 部署
-
初始化数据目录:使用
mysqld初始化时,指定运行用户。mysqld --initialize --user=mysql-user --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data -
配置文件 (
my.cnf):在/usr/local/mysql/conf/my.cnf中明确指定用户和路径。[mysqld] user=mysql-user datadir=/usr/local/mysql/data socket=/usr/local/mysql/mysql.sock log-error=/usr/local/mysql/logs/mysqld.log pid-file=/usr/local/mysql/mysqld.pid # 等保要求:禁用本地文件读取、限制权限等 local-infile=0 # 等保要求:开启二进制日志用于审计和恢复 log-bin=/usr/local/mysql/logs/mysql-bin -
启动:使用
systemd管理,在 service 文件中指定User和Group。/usr/lib/systemd/system/mysqld.service[Unit] Description=MySQL Server [Service] User=mysql-user Group=mysql-group Type=notify ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/usr/local/mysql/conf/my.cnf ... [Install] WantedBy=multi-user.target
2. Redis 部署
- 配置文件 (
redis.conf):这是关键!以非 root 用户运行 Redis 必须通过配置完成。
修改# 复制默认配置文件到你的conf目录 cp /path/to/redis.conf /usr/local/redis/conf/ chown redis-user:redis-group /usr/local/redis/conf/redis.conf/usr/local/redis/conf/redis.conf:# 以守护进程运行 daemonize no # 如果使用systemd,建议设为no,让systemd管理进程 # 指定运行用户(重要!) user redis-user on >somepassword ~* +@all # 绑定IP,等保要求不能监听0.0.0.0 bind 127.0.0.1 # 或者你的内网IP # 保护模式,等保要求开启 protected-mode yes # 设置密码,等保强制要求 requirepass your_strong_password_here # 修改数据目录和日志目录 dir /var/lib/redis logfile "/usr/local/redis/logs/redis.log" # 等保要求:禁用或重命名危险命令 rename-command FLUSHALL "" rename-command CONFIG "" # 以非root用户运行时,无法使用1024以下端口,所以用默认6379即可 port 6379 - 启动:使用
systemd。
/usr/lib/systemd/system/redis.service[Unit] Description=Redis In-Memory Data Store [Service] User=redis-user Group=redis-group ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf ExecStop=/usr/local/redis/bin/redis-cli shutdown Restart=always [Install] WantedBy=multi-user.target
3. Nginx 部署
- 编译安装(可选):如果在编译时指定用户和组,会更规范。
./configure --user=nginx-user --group=nginx-group --prefix=/usr/local/nginx ... make && make install - 配置文件 (
nginx.conf):# 在main部分指定用户 user nginx-user nginx-group; # 修改进程pid和错误日志路径 pid /usr/local/nginx/logs/nginx.pid; error_log /usr/local/nginx/logs/error.log; http { # 其他http配置... access_log /usr/local/nginx/logs/access.log; server { # 你的服务配置... } } - 启动:使用
systemd。注意:Nginx 主进程需要root用户来绑定 80/443 端口,但 Worker 进程会降权到nginx-user运行。这是标准且可接受的做法。
/usr/lib/systemd/system/nginx.service[Unit] Description=nginx [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true # 这里不指定User=root,因为nginx.conf里已经指定了worker进程的用户 [Install] WantedBy=multi-user.target
4. Java Jar 应用部署
这是最灵活的部分,核心思想不变。
- 放置 Jar 包和配置文件:将你的
app.jar和application.yml/properties放到/opt/your-java-app/下,并确保所有者是app-user。chown app-user:app-group /opt/your-java-app/app.jar chown app-user:app-group /opt/your-java-app/config/application.yml - 使用 Systemd 管理:这是最专业的方式。
/usr/lib/systemd/system/your-app.service[Unit] Description=Your Java Application After=network.target mysql.service redis.service # 定义依赖关系 [Service] Type=simple User=app-user Group=app-group # 指定工作目录,这样日志、临时文件都会生成在这里 WorkingDirectory=/opt/your-java-app ExecStart=/usr/bin/java -jar /opt/your-java-app/app.jar # 或者使用 nohup 或指定日志输出 # ExecStart=/usr/bin/java -jar /opt/your-java-app/app.jar --spring.config.location=/opt/your-java-app/config/application.yml ExecStop=/bin/kill -15 $MAINPID Restart=on-failure RestartSec=10 # 等保要求:限制权限 NoNewPrivileges=yes # 限制可以访问的目录 ReadWritePaths=/opt/your-java-app/logs /opt/your-java-app/data [Install] WantedBy=multi-user.target
第三步:二级等保的其他关键要求
除了上述部署规范,你还需要注意:
- 口令策略:为所有服务的账户(MySQL root, Redis requirepass, 应用自身数据库密码等)设置强口令,并定期更换。
- 日志审计:
- 确保所有服务都开启了访问日志和错误日志。
- 将日志集中收集(如 ELK Stack)并长期保存(>= 6个月)。
- 系统本身的操作系统日志(
auditd)也需要配置和审计。
- 网络安全:
- 防火墙(
iptables/firewalld)必须开启,只开放必要的服务端口(如 80, 443, SSH)。 - 数据库(MySQL, Redis)严禁对公网开放,只监听内网 IP 或本地回环地址
127.0.0.1。
- 防火墙(
- 系统安全:
- 定期更新系统和软件补丁。
- 配置 SSH 禁用 root 登录和使用密钥对认证。
- 安装主机入侵检测系统(如 OSSEC, Wazuh)。
- 数据安全:
- 对 MySQL 的敏感数据考虑加密存储。
- 对重要配置文件进行权限控制(600 或 640)。
总结:专业部署清单
- ✅ 创建专属的非登录系统用户和组。
- ✅ 规划并创建专属目录,使用
chown和chmod严格授权。 - ✅ 修改各服务配置文件,指定运行用户、数据目录、日志目录、绑定IP等。
- ✅ 为每个服务创建
systemd单元文件,在其中指定User和Group。 - ✅ 配置强密码、防火墙、日志审计等二级等保的通用要求。
遵循以上步骤,你的服务部署就已经达到了一个非常专业和符合二级等保基础要求的水准。记住,安全是一个过程,而不是一个结果,持续的监控和维护同样重要。