如何在CentOS或Ubuntu服务器上安全地共存安装MySQL、Redis和RabbitMQ?

在 CentOS/Ubuntu 服务器上安全共存安装 MySQL、Redis 和 RabbitMQ

一、总体架构与安全原则

┌─────────────────────────────────────────────┐
│              Linux Server                    │
│                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │  MySQL   │  │  Redis   │  │ RabbitMQ │   │
│  │ :3306    │  │ :6379    │  │ :5672    │   │
│  │          │  │          │  │ :15672   │   │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘   │
│       │             │             │           │
│  ┌────▼─────────────▼─────────────▼────┐     │
│  │         Firewall / iptables          │     │
│  │  (仅开放必要端口,绑定 localhost)      │     │
│  └─────────────────────────────────────┘     │
└─────────────────────────────────────────────┘

核心安全原则

  1. 最小权限原则:每个服务以独立用户运行
  2. 网络隔离:默认绑定 127.0.0.1,外部访问通过防火墙控制
  3. 强密码策略:所有服务使用高强度密码
  4. 定期更新:保持软件包最新
  5. 日志审计:启用并监控日志

二、前置准备(通用)

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 » 如何在CentOS或Ubuntu服务器上安全地共存安装MySQL、Redis和RabbitMQ?