Java 中的 Redis 未授权访问问题深度解析
一、未授权访问漏洞的本质
1.1 漏洞定义
未授权访问 指 Redis 服务未启用认证机制或配置不当,导致攻击者无需密码即可访问并执行高危操作。核心问题:
- 默认配置未设置密码(
requirepass
) - 绑定公网IP(
bind 0.0.0.0
) - 未禁用高危命令(FLUSHALL、CONFIG等)
1.2 攻击路径
二、Java 应用中的风险场景
2.1 不安全配置示例
// 无密码直连Redis
JedisPool pool = new JedisPool("123.45.67.89", 6379);
// 配置文件明文存储密码(application.yml)
spring:
redis:
host: public-redis.com
password: admin123 # 明文暴露
2.2 典型攻击案例
# 攻击者通过Java应用写入SSH公钥
redis-cli -h 123.45.67.89
> config set dir /root/.ssh/
> config set dbfilename authorized_keys
> set x "\n\nssh-rsa AAAAB3NzaC...\n\n"
> save
三、漏洞检测与验证
3.1 手动检测方法
# 尝试无认证连接
redis-cli -h <target-ip> -p 6379
> info # 成功获取信息说明存在漏洞
# 检查敏感配置
> config get requirepass
> config get bind
> config get protected-mode
3.2 自动化扫描工具
// 使用Nmap脚本扫描
Process process = Runtime.getRuntime().exec("nmap -p 6379 --script redis-info <target>");
// 集成漏洞扫描SDK
VulnScanner scanner = new RedisScanner()
.setTarget("123.45.67.89")
.scan();
四、Java 应用防护方案
4.1 安全连接配置
// 正确配置密码和SSL
JedisPoolConfig config = new JedisPoolConfig();
URI uri = URI.create("rediss://:password@redis-host:6379/0"); // SSL+密码
JedisPool pool = new JedisPool(config, uri);
4.2 敏感信息加密
// 使用Jasypt加密配置文件
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
StringEncryptor encryptor = new StandardPBEStringEncryptor();
((StandardPBEStringEncryptor)encryptor).setPassword("jasypt-master-key");
EncryptablePropertySourcesPlaceholderConfigurer configurer =
new EncryptablePropertySourcesPlaceholderConfigurer(encryptor);
configurer.setLocation(new ClassPathResource("application.yml"));
return configurer;
}
4.3 网络层防护
// 使用SSH隧道连接
JSch jsch = new JSch();
jsch.addIdentity("~/.ssh/private_key");
Session session = jsch.getSession("user", "jump-host", 22);
session.connect();
int localPort = 16379;
session.setPortForwardingL(localPort, "redis-host", 6379);
JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost", localPort);
五、Redis 服务端加固
5.1 基础安全配置
# redis.conf 核心配置
requirepass T7m$p9sV&YqZ # 强密码
bind 127.0.0.1 # 仅本地访问
protected-mode yes # 保护模式
rename-command FLUSHALL "" # 禁用高危命令
5.2 防火墙规则
# 仅允许应用服务器访问
iptables -A INPUT -p tcp -s 192.168.1.100 --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP
5.3 权限控制
# 创建低权限用户
useradd -r -s /bin/false redisuser
chown -R redisuser:redisuser /var/lib/redis
六、攻击应急响应
6.1 入侵检测步骤
- 检查异常登录:
lastb
和/var/log/auth.log
- Redis日志分析:
cat /var/log/redis/redis-server.log | grep -E 'CONFIG|SAVE'
- SSH公钥检查:
ls -la /root/.ssh/authorized_keys
6.2 数据恢复流程
# 停止Redis服务
systemctl stop redis
# 回滚到安全备份
cp dump.rdb.bak dump.rdb
# 检查文件完整性
sha256sum dump.rdb
6.3 Java应用检查点
- 验证连接池配置是否使用加密密码
- 扫描代码库中的明文凭证
- 审计所有Redis操作日志
七、安全开发规范
7.1 代码审查清单
检查项 | 安全标准 |
---|---|
连接密码是否硬编码 | 必须使用加密配置 |
是否使用SSL/TLS | 生产环境必须启用 |
高危命令是否禁用 | 禁止使用FLUSHALL、CONFIG等 |
错误日志是否泄露敏感信息 | 屏蔽Redis服务器地址和认证信息 |
7.2 安全测试用例
@Test
public void testUnauthorizedAccess() {
// 尝试无密码连接
try (Jedis jedis = new Jedis("redis-host", 6379)) {
jedis.ping();
fail("应抛出认证异常");
} catch (Exception e) {
assertTrue(e.getMessage().contains("NOAUTH"));
}
}
@Test
public void testDangerousCommandsDisabled() {
Jedis jedis = getAuthedJedis();
try {
jedis.configSet("dir", "/tmp");
fail("CONFIG命令应被禁用");
} catch (Exception e) {
assertTrue(e.getMessage().contains("unknown command"));
}
}
八、进阶防护方案
8.1 动态口令认证
// 使用一次性令牌
public class OTPService {
public String generateToken() {
return new Totp("base32Secret").now();
}
}
// Redis连接时验证动态口令
public Jedis getJedisWithOTP() {
String token = otpService.generateToken();
return new Jedis(new HostAndPort("redis-host", 6379),
new DefaultJedisClientConfig.Builder()
.user("admin")
.password(token)
.build());
}
8.2 基于角色的访问控制
-- 自定义权限校验脚本
local key = KEYS[1]
local cmd = ARGV[1]
local role = redis.call('GET', 'user_role:'..key)
if cmd == 'SET' and role ~= 'write' then
return redis.error_reply('permission denied')
end
-- 执行原命令
return redis.call(cmd, unpack(ARGV))
8.3 网络层加密
# 使用WireGuard建立加密隧道
wg-quick up wg0
# Redis监听WireGuard虚拟IP
bind 10.8.0.1
port 6379
通过多维度安全策略的实施,可将Redis未授权访问风险降至最低。建议结合自动化安全扫描工具(如Trivy、Anchore)定期检测,并建立安全运维SOP(标准操作流程)。关键点总结:
- 认证必启用:生产环境必须配置强密码
- 网络必隔离:禁止公网暴露Redis端口
- 命令必控制:禁用非必要高危操作
- 审计必执行:定期检查日志和配置
更多资源:
http://sj.ysok.net/jydoraemon 访问码:JYAM