在 CentOS/Ubuntu 服务器上安全共存安装 MySQL、Redis 和 RabbitMQ
一、总体架构与安全原则
┌─────────────────────────────────────────────┐
│ Linux Server │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ MySQL │ │ Redis │ │ RabbitMQ │ │
│ │ :3306 │ │ :6379 │ │ :5672 │ │
│ │ │ │ │ │ :15672 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌────▼─────────────▼─────────────▼────┐ │
│ │ Firewall / iptables │ │
│ │ (仅开放必要端口,绑定 localhost) │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
核心安全原则
- 最小权限原则:每个服务以独立用户运行
- 网络隔离:默认绑定
127.0.0.1,外部访问通过防火墙控制 - 强密码策略:所有服务使用高强度密码
- 定期更新:保持软件包最新
- 日志审计:启用并监控日志
二、前置准备(通用)
1. 系统初始化
# Ubuntu
sudo apt update && sudo apt upgrade -y
sudo ufw enable
sudo ufw default deny incoming
sudo ufw default allow outgoing
# CentOS
sudo yum update -y
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
2. 创建专用用户(可选但推荐)
# 为每个服务创建独立系统用户
sudo useradd --system --no-create-home --shell /bin/false mysql
sudo useradd --system --no-create-home --shell /bin/false redis
sudo useradd --system --no-create-home --shell /bin/false rabbitmq
三、MySQL 安装与配置
Ubuntu (APT)
# 安装 MySQL 8.0
sudo apt install mysql-server -y
# 安全加固脚本
sudo mysql_secure_installation
CentOS (YUM/RPM)
# 添加 MySQL YUM 仓库
sudo yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
sudo yum install -y mysql-community-server
# 启动服务
sudo systemctl start mysqld
sudo systemctl enable mysqld
# 获取临时密码并修改
sudo grep 'temporary password' /var/log/mysqld.log
mysql -u root -p # 输入临时密码后执行以下 SQL
MySQL 安全配置 (/etc/mysql/my.cnf 或 /etc/my.cnf)
[mysqld]
# 网络绑定:仅监听本地
bind-address = 127.0.0.1
# 禁用远程 root 登录
local-infile = 0
# 限制最大连接数
max_connections = 100
# 启用 SSL
ssl-ca = /etc/mysql/ssl/ca-cert.pem
ssl-cert = /etc/mysql/ssl/server-cert.pem
ssl-key = /etc/mysql/ssl/server-key.pem
# 日志
log_error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
MySQL 初始安全设置(SQL)
-- 创建应用专用账户(非 root)
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'StrongP@ssw0rd!2024';
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;
-- 删除匿名用户
DROP USER ''@'localhost';
DROP USER ''@'%';
-- 移除测试数据库
DROP DATABASE IF EXISTS test;
-- 检查权限
SHOW GRANTS FOR 'app_user'@'localhost';
防火墙规则
# Ubuntu (UFW)
sudo ufw allow from 127.0.0.1 to any port 3306
# 如需远程访问特定IP:
sudo ufw allow from 192.168.1.100 to any port 3306
# CentOS (firewalld)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="3306" accept'
sudo firewall-cmd --reload
四、Redis 安装与配置
Ubuntu (APT)
sudo apt install redis-server -y
sudo systemctl enable redis-server
sudo systemctl start redis-server
CentOS (EPEL + Remi 或源码编译)
# 方法1:EPEL
sudo yum install -y epel-release
sudo yum install -y redis
sudo systemctl enable redis
sudo systemctl start redis
# 方法2:源码编译(推荐生产环境)
cd /tmp
wget http://download.redis.io/releases/redis-7.2.4.tar.gz
tar xzf redis-7.2.4.tar.gz
cd redis-7.2.4
make PREFIX=/usr/local/redis install
cp redis.conf /etc/redis.conf
Redis 安全配置 (/etc/redis/redis.conf)
# ===== 网络绑定 =====
bind 127.0.0.1
protected-mode yes
port 6379
# ===== 认证 =====
requirepass StrongRedisP@ssw0rd!2024
# ===== 重命名危险命令(防止滥用)=====
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command DEBUG ""
rename-command SHUTDOWN ""
# ===== 内存管理 =====
maxmemory 256mb
maxmemory-policy allkeys-lru
# ===== 持久化 =====
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
# ===== 日志 =====
logfile /var/log/redis/redis.log
loglevel notice
# ===== 用户权限(Redis 6+)=====
user default on >StrongRedisP@ssw0rd!2024 ~* &* +@all -@dangerous
# ===== 进程保护 =====
daemonize yes
pidfile /var/run/redis/redis.pid
Redis 文件权限
sudo chown redis:redis /etc/redis.conf
sudo chmod 640 /etc/redis.conf
sudo mkdir -p /var/lib/redis
sudo chown redis:redis /var/lib/redis
sudo chmod 750 /var/lib/redis
防火墙规则
# UFW
sudo ufw allow from 127.0.0.1 to any port 6379
# firewalld
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="6379" accept'
sudo firewall-cmd --reload
五、RabbitMQ 安装与配置
Ubuntu (APT)
# 添加 Erlang 和 RabbitMQ 仓库
sudo apt install gnupg wget apt-transport-https -y
# Erlang
wget -O- https://packages.erlang-solutions.com/ubuntu.sh | sudo bash
sudo apt install erlang-nox -y
# RabbitMQ
echo "deb https://rabbitmq.github.io/rabbitmq-package-repo/ubuntu/ focal main" |
sudo tee /etc/apt/sources.list.d/rabbitmq.list
sudo apt update
sudo apt install rabbitmq-server -y
sudo systemctl enable rabbitmq-server
sudo systemctl start rabbitmq-server
CentOS (YUM)
# 添加 Erlang 仓库
sudo rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
cat <<EOF | sudo tee /etc/yum.repos.d/rabbitmq_erlang.repo
[rabbitmq_erlang]
name=rabbitmq_erlang
baseurl=https://packagecloud.io/rabbitmq/erlang/el/$(rpm -E%{os_version})/$(arch)
repo_gpgcheck=1
gpgcheck=1
enabled=1
EOF
# 添加 RabbitMQ 仓库
cat <<EOF | sudo tee /etc/yum.repos.d/rabbitmq.repo
[rabbitmq]
name=rabbitmq
baseurl=https://dl.bintray.com/rabbitmq/rabbitmq-server-rpm/el$(rpm -E%{os_version})/$(arch)
repo_gpgcheck=1
gpgcheck=1
enabled=1
EOF
sudo yum install rabbitmq-server -y
sudo systemctl enable rabbitmq-server
sudo systemctl start rabbitmq-server
RabbitMQ 安全配置
1. 管理插件启用
sudo rabbitmq-plugins enable rabbitmq_management
# Web UI: http://<server-ip>:15672
2. 创建专用用户和虚拟主机
# 删除默认 guest 用户(更安全)
sudo rabbitmqctl delete_user guest
# 创建应用用户
sudo rabbitmqctl add_user app_rabbit StrongRabbitP@ssw0rd!2024
sudo rabbitmqctl set_permissions -p / app_rabbit ".*" ".*" ".*"
# 设置标签
sudo rabbitmqctl set_user_tags app_rabbit administrator
# 创建专用 vhost
sudo rabbitmqctl add_vhost app_vhost
sudo rabbitmqctl set_permissions -p app_vhost app_rabbit ".*" ".*" ".*"
3. 配置文件 (/etc/rabbitmq/rabbitmq.conf)
# ===== 网络绑定 =====
listeners.tcp.default = 127.0.0.1:5672
management.listener.ip = 127.0.0.1
management.listener.port = 15672
# ===== TLS/SSL(生产环境强烈推荐)=====
# ssl_options.cacertfile = /etc/rabbitmq/ca-cert.pem
# ssl_options.certfile = /etc/rabbitmq/server-cert.pem
# ssl_options.keyfile = /etc/rabbitmq/server-key.pem
# listeners.ssl.default = 127.0.0.1:5671
# ===== 资源限制 =====
vm_memory_high_watermark.relative = 0.6
disk_free_limit.absolute = 2GB
# ===== 日志 =====
log.file.level = info
log.console = false
# ===== 集群节点名 =====
node.name = rabbit@localhost
# ===== Cookie(用于集群通信,需严格权限)=====
# cookie 文件由 rabbitmq-server 自动管理,确保权限正确
4. 文件权限
sudo chown -R rabbitmq:rabbitmq /etc/rabbitmq/
sudo chmod 640 /etc/rabbitmq/rabbitmq.conf
sudo chmod 640 /etc/rabbitmq/rabbitmq-env.conf
# Erlang cookie(关键!)
sudo cp /var/lib/rabbitmq/.erlang.cookie /home/rabbitmq/.erlang.cookie
sudo chown rabbitmq:rabbitmq /home/rabbitmq/.erlang.cookie
sudo chmod 400 /home/rabbitmq/.erlang.cookie
防火墙规则
# UFW
sudo ufw allow from 127.0.0.1 to any port 5672
sudo ufw allow from 127.0.0.1 to any port 15672
# 如需远程管理(谨慎):
# sudo ufw allow from 192.168.1.100 to any port 15672
# firewalld
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="5672" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="15672" accept'
sudo firewall-cmd --reload
六、综合防火墙配置
Ubuntu (UFW) — 最终规则
# 查看当前状态
sudo ufw status verbose
# 预期输出示例:
# Status: active
# To Action From
# -- ------ ----
# 22/tcp ALLOW IN Anywhere
# 3306/tcp ALLOW IN 127.0.0.1
# 6379/tcp ALLOW IN 127.0.0.1
# 5672/tcp ALLOW IN 127.0.0.1
# 15672/tcp ALLOW IN 127.0.0.1
CentOS (firewalld) — 最终规则
# 列出所有区域和服务
sudo firewall-cmd --list-all
# 确保只允许本地回环访问这些端口
sudo firewall-cmd --permanent --remove-service=mysql
sudo firewall-cmd --permanent --remove-service=redis
sudo firewall-cmd --permanent --remove-service=amqp
# 用 rich rules 精确控制
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="3306" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="6379" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="5672" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="127.0.0.1" port protocol="tcp" port="15672" accept'
sudo firewall-cmd --reload
七、服务健康检查
1. 验证各服务运行状态
# MySQL
sudo systemctl status mysqld
mysql -u app_user -p -e "SELECT 1;"
# Redis
sudo systemctl status redis-server
redis-cli -a StrongRedisP@ssw0rd!2024 ping # 应返回 PONG
# RabbitMQ
sudo systemctl status rabbitmq-server
sudo rabbitmqctl status | head -20
curl -u app_rabbit:StrongRabbitP@ssw0rd!2024 http://127.0.0.1:15672/api/overview
2. 端口监听检查
# 确认只监听在 127.0.0.1
sudo ss -tlnp | grep -E '(3306|6379|5672|15672)'
# 预期输出示例:
# LISTEN 0 80 127.0.0.1:3306 *:* users:(("mysqld",pid=...,fd=...))
# LISTEN 0 128 127.0.0.1:6379 *:* users:(("redis-server",pid=...,fd=...))
# LISTEN 0 128 127.0.0.1:5672 *:* users:(("beam.smp",pid=...,fd=...))
# LISTEN 0 128 127.0.0.1:15672 *:* users:(("beam.smp",pid=...,fd=...))
3. 自动化健康检查脚本
#!/bin/bash
# check_services.sh
RED='33[0;31m'
GREEN='33[0;32m'
NC='33[0m'
check_service() {
local name="$1"
local cmd="$2"
if eval "$cmd" > /dev/null 2>&1; then
echo -e "${GREEN}[OK]${NC} $name"
else
echo -e "${RED}[FAIL]${NC} $name"
return 1
fi
}
echo "=== Service Health Check ==="
check_service "MySQL" "mysqladmin -u app_user -p'StrongP@ssw0rd!2024' ping"
check_service "Redis" "redis-cli -a 'StrongRedisP@ssw0rd!2024' ping"
check_service "RabbitMQ" "rabbitmqctl status >/dev/null 2>&1"
echo "=== Port Binding Check ==="
for port in 3306 6379 5672 15672; do
binding=$(ss -tlnp | grep ":$port " | awk '{print $4}' | cut -d: -f1)
if [ "$binding" = "127.0.0.1" ]; then
echo -e "${GREEN}[OK]${NC} Port $port bound to 127.0.0.1"
else
echo -e "${RED}[WARN]${NC} Port $port bound to $binding (not localhost!)"
fi
done
八、备份策略
MySQL 备份
#!/bin/bash
# backup_mysql.sh
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
MYSQL_USER="root"
MYSQL_PASS="RootStrongP@ss!"
mkdir -p $BACKUP_DIR
mysqldump -u $MYSQL_USER -p$MYSQL_PASS
--single-transaction --routines --triggers
--all-databases | gzip > $BACKUP_DIR/full_backup_$DATE.sql.gz
# 保留最近7天
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
Redis 备份
#!/bin/bash
# backup_redis.sh
BACKUP_DIR="/backup/redis"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# 触发 BGSAVE 并等待完成
redis-cli -a 'StrongRedisP@ssw0rd!2024' BGSAVE
sleep 5
# 复制 RDB 文件
cp /var/lib/redis/dump.rdb $BACKUP_DIR/dump_$DATE.rdb
find $BACKUP_DIR -name "dump_*.rdb" -mtime +7 -delete
RabbitMQ 备份
#!/bin/bash
# backup_rabbitmq.sh
BACKUP_DIR="/backup/rabbitmq"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# 导出配置和用户信息
rabbitmqctl export_permissions > $BACKUP_DIR/permissions_$DATE.txt
rabbitmqctl list_users > $BACKUP_DIR/users_$DATE.txt
rabbitmqctl list_queues > $BACKUP_DIR/queues_$DATE.txt
九、监控与告警建议
| 服务 | 监控指标 | 工具建议 |
|---|---|---|
| MySQL | 连接数、慢查询、InnoDB缓冲池命中率 | Prometheus + mysqld_exporter + Grafana |
| Redis | 内存使用、连接数、命中率、延迟 | redis_exporter + Grafana |
| RabbitMQ | 队列长度、消息速率、连接数 | rabbitmq_prometheus_plugin + Grafana |
# 安装 Prometheus 导出器示例
sudo apt install prometheus-node-exporter -y
# RabbitMQ Prometheus 插件
sudo rabbitmq-plugins enable rabbitmq_prometheus
# 默认暴露 http://127.0.0.1:15692/metrics
十、常见问题排查
# 1. 服务无法启动?
sudo journalctl -u <service-name> -n 50 --no-pager
# 2. 权限被拒绝?
ls -la /var/lib/<service>/
sudo ls -la /etc/<service>/
# 3. 端口冲突?
sudo netstat -tlnp | grep -E '(3306|6379|5672)'
# 4. SELinux 阻止(CentOS)?
sudo getenforce
# 如果 Enforcing,检查上下文:
semanage fcontext -l | grep <service>
restorecon -v /path/to/file
# 5. 防火墙阻止?
sudo iptables -L -n -v | grep -E '(3306|6379|5672)'
总结 checklist
✅ 所有服务绑定到 127.0.0.1
✅ 防火墙仅允许 localhost 访问内部端口
✅ 使用强密码,禁用默认账户
✅ 危险命令重命名/禁用(Redis)
✅ 最小权限原则(数据库用户、RBAC)
✅ 启用日志和慢查询追踪
✅ 配置自动备份
✅ 定期更新补丁
✅ 监控资源使用情况
✅ 测试恢复流程
这套方案确保了三个服务在同一台服务器上的安全共存,同时保持了良好的隔离性和可维护性。对于更高安全性要求的生产环境,建议将这三个服务部署到独立的容器或虚拟机中。
云知识CLOUD