安全配置
生产环境中,RabbitMQ 的安全配置至关重要,包括用户认证、权限控制和通信加密。
🎯 本章目标
- 掌握 RabbitMQ 用户和权限管理
- 学会配置 TLS/SSL 加密通信
- 了解生产环境安全最佳实践
👤 用户管理
用户角色
| 角色 | 权限 | 说明 |
|---|---|---|
| none | 无 | 无法登录管理界面 |
| management | 低 | 查看自己的连接、队列 |
| policymaker | 中 | 管理策略和参数 |
| monitoring | 中 | 查看所有节点信息 |
| administrator | 高 | 完全管理权限 |
用户操作命令
# 添加用户
rabbitmqctl add_user <username> <password>
# 删除用户
rabbitmqctl delete_user <username>
# 修改密码
rabbitmqctl change_password <username> <newpassword>
# 设置用户角色
rabbitmqctl set_user_tags <username> <role>
# 例如:rabbitmqctl set_user_tags admin administrator
# 列出所有用户
rabbitmqctl list_users
# 清除用户密码(禁用密码登录)
rabbitmqctl clear_password <username>
生产环境用户设置
# 1. 删除默认 guest 用户
rabbitmqctl delete_user guest
# 2. 创建管理员用户
rabbitmqctl add_user admin SecureP@ssw0rd!
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
# 3. 创建应用用户(最小权限)
rabbitmqctl add_user order_service OrderSvc123
rabbitmqctl set_user_tags order_service none
rabbitmqctl set_permissions -p /order order_service "^order\." "^order\." "^order\."
# 4. 创建监控用户
rabbitmqctl add_user monitor MonitorP@ss
rabbitmqctl set_user_tags monitor monitoring
rabbitmqctl set_permissions -p / monitor "" "" ".*"
🔐 权限控制
权限模型
权限格式: configure, write, read
- configure: 创建/删除队列、交换机的权限
- write: 发布消息的权限
- read: 消费消息、绑定队列的权限
正则表达式匹配资源名称
".*" = 所有资源
"^order\." = 以 order. 开头的资源
"" = 无权限
权限配置示例
# 完全权限
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
# 只读权限(只能消费,不能发布或创建)
rabbitmqctl set_permissions -p / reader "" "" ".*"
# 只写权限(只能发布,不能消费)
rabbitmqctl set_permissions -p / writer "" ".*" ""
# 特定队列权限
rabbitmqctl set_permissions -p / order_service \
"^order\." "^order\." "^order\."
# 查看权限
rabbitmqctl list_permissions -p /
# 查看用户权限
rabbitmqctl list_user_permissions admin
# 清除权限
rabbitmqctl clear_permissions -p / <username>
虚拟主机隔离
# 创建虚拟主机
rabbitmqctl add_vhost /production
rabbitmqctl add_vhost /staging
rabbitmqctl add_vhost /development
# 为不同环境设置权限
rabbitmqctl set_permissions -p /production prod_user ".*" ".*" ".*"
rabbitmqctl set_permissions -p /staging stage_user ".*" ".*" ".*"
# 删除虚拟主机
rabbitmqctl delete_vhost /development
# 列出虚拟主机
rabbitmqctl list_vhosts
🔒 TLS/SSL 加密
生成证书
# 1. 创建 CA 证书
mkdir -p /etc/rabbitmq/ssl
cd /etc/rabbitmq/ssl
# 生成 CA 私钥
openssl genrsa -out ca.key 4096
# 生成 CA 证书
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
-out ca.crt -subj "/CN=RabbitMQ-CA"
# 2. 生成服务器证书
openssl genrsa -out server.key 2048
# 生成证书签名请求
openssl req -new -key server.key -out server.csr \
-subj "/CN=rabbitmq.example.com"
# 用 CA 签名
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365 -sha256
# 3. 生成客户端证书(可选,用于双向认证)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
-subj "/CN=rabbitmq-client"
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt -days 365 -sha256
# 设置权限
chown -R rabbitmq:rabbitmq /etc/rabbitmq/ssl
chmod 400 /etc/rabbitmq/ssl/*.key
chmod 444 /etc/rabbitmq/ssl/*.crt
RabbitMQ TLS 配置
%% /etc/rabbitmq/rabbitmq.conf
# 禁用非 TLS 端口(可选)
# listeners.tcp = none
# TLS 监听端口
listeners.ssl.default = 5671
# 证书配置
ssl_options.cacertfile = /etc/rabbitmq/ssl/ca.crt
ssl_options.certfile = /etc/rabbitmq/ssl/server.crt
ssl_options.keyfile = /etc/rabbitmq/ssl/server.key
# 验证客户端证书
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = true
# TLS 版本(只允许 TLS 1.2+)
ssl_options.versions.1 = tlsv1.2
ssl_options.versions.2 = tlsv1.3
# 加密套件
ssl_options.ciphers.1 = TLS_AES_256_GCM_SHA384
ssl_options.ciphers.2 = TLS_CHACHA20_POLY1305_SHA256
ssl_options.ciphers.3 = ECDHE-RSA-AES256-GCM-SHA384
# 管理界面 HTTPS
management.ssl.port = 15671
management.ssl.cacertfile = /etc/rabbitmq/ssl/ca.crt
management.ssl.certfile = /etc/rabbitmq/ssl/server.crt
management.ssl.keyfile = /etc/rabbitmq/ssl/server.key
Java 客户端 TLS 配置
package com.example.rabbitmq.config;
import com.rabbitmq.client.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
@Configuration
public class RabbitMQTlsConfig {
@Bean
public ConnectionFactory connectionFactory() throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("rabbitmq.example.com");
factory.setPort(5671); // TLS 端口
factory.setUsername("admin");
factory.setPassword("password");
// 配置 TLS
factory.useSslProtocol(createSSLContext());
// 验证主机名
factory.enableHostnameVerification();
return factory;
}
private SSLContext createSSLContext() throws Exception {
// 加载信任库(CA 证书)
KeyStore trustStore = KeyStore.getInstance("PKCS12");
try (FileInputStream fis = new FileInputStream("/path/to/truststore.p12")) {
trustStore.load(fis, "truststorePassword".toCharArray());
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm()
);
tmf.init(trustStore);
// 加载密钥库(客户端证书,双向认证时需要)
KeyStore keyStore = KeyStore.getInstance("PKCS12");
try (FileInputStream fis = new FileInputStream("/path/to/keystore.p12")) {
keyStore.load(fis, "keystorePassword".toCharArray());
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm()
);
kmf.init(keyStore, "keyPassword".toCharArray());
// 创建 SSLContext
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslContext;
}
}
Spring Boot TLS 配置
spring:
rabbitmq:
host: rabbitmq.example.com
port: 5671
username: admin
password: password
ssl:
enabled: true
key-store: classpath:client.p12
key-store-password: keystorePassword
key-store-type: PKCS12
trust-store: classpath:truststore.p12
trust-store-password: truststorePassword
trust-store-type: PKCS12
verify-hostname: true
🛡️ 安全最佳实践
1. 网络安全
# 使用防火墙限制访问
# 只允许应用服务器访问 RabbitMQ
# iptables 示例
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 5672 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 5671 -j ACCEPT
iptables -A INPUT -p tcp --dport 5672 -j DROP
iptables -A INPUT -p tcp --dport 5671 -j DROP
# 限制管理界面访问
iptables -A INPUT -p tcp -s 10.0.0.100 --dport 15672 -j ACCEPT
iptables -A INPUT -p tcp --dport 15672 -j DROP
2. 配置文件安全
%% rabbitmq.conf
# 禁用 guest 用户远程访问(默认已禁用)
loopback_users.guest = true
# 禁用未加密连接
listeners.tcp = none
# 只监听内部网络
listeners.ssl.default = 5671
listeners.ssl.local = 127.0.0.1:5671
# 设置连接超时
heartbeat = 60
connection_max = 1000
# 限制帧大小
frame_max = 131072
3. 审计日志
%% rabbitmq.conf
# 启用详细日志
log.file.level = info
log.console.level = warning
# 配置日志文件
log.file = /var/log/rabbitmq/rabbit.log
log.file.rotation.date = $D0
log.file.rotation.count = 7
4. 密码策略
// 使用强密码
public class PasswordValidator {
public static boolean isStrong(String password) {
// 至少 12 位
if (password.length() < 12) return false;
// 包含大小写、数字、特殊字符
boolean hasUpper = password.matches(".*[A-Z].*");
boolean hasLower = password.matches(".*[a-z].*");
boolean hasDigit = password.matches(".*\\d.*");
boolean hasSpecial = password.matches(".*[!@#$%^&*(),.?\":{}|<>].*");
return hasUpper && hasLower && hasDigit && hasSpecial;
}
}
5. 定期安全检查
#!/bin/bash
# security-check.sh
echo "=== RabbitMQ 安全检查 ==="
# 检查 guest 用户是否存在
if rabbitmqctl list_users | grep -q "guest"; then
echo "⚠️ 警告: guest 用户仍然存在"
fi
# 检查非 TLS 连接
if netstat -tlnp | grep -q ":5672 "; then
echo "⚠️ 警告: 非加密端口 5672 开放"
fi
# 检查用户权限
echo "📋 用户权限列表:"
rabbitmqctl list_permissions -p /
# 检查连接
echo "📋 当前连接:"
rabbitmqctl list_connections user peer_host peer_port ssl
🔑 外部认证
LDAP 认证
%% rabbitmq.conf
# 启用 LDAP 认证
auth_backends.1 = ldap
# LDAP 服务器配置
auth_ldap.servers.1 = ldap.example.com
auth_ldap.port = 389
auth_ldap.use_ssl = false
# 用户 DN 模式
auth_ldap.user_dn_pattern = cn=${username},ou=users,dc=example,dc=com
# 日志级别
auth_ldap.log = true
OAuth 2.0 认证
%% rabbitmq.conf
# 启用 OAuth 2.0
auth_backends.1 = rabbit_auth_backend_oauth2
# OAuth 配置
auth_oauth2.resource_server_id = rabbitmq
auth_oauth2.additional_scopes_key = scope
📝 本章小结
| 安全领域 | 措施 |
|---|---|
| 用户管理 | 删除 guest,创建最小权限用户 |
| 权限控制 | 使用正则限制资源访问 |
| 网络隔离 | 虚拟主机隔离,防火墙限制 |
| 通信加密 | TLS 1.2+,禁用非加密连接 |
| 审计日志 | 启用详细日志,定期检查 |
| 密码策略 | 强密码,定期更换 |
安全检查清单
- [ ] 删除默认 guest 用户
- [ ] 创建专用应用用户
- [ ] 配置最小权限
- [ ] 启用 TLS 加密
- [ ] 禁用非加密端口
- [ ] 配置防火墙规则
- [ ] 启用审计日志
- [ ] 定期检查和更新
下一步
安全配置完成后,让我们学习 Federation & Shovel 实现跨数据中心复制!
