Security
- 非特权运行
- 文件权限
- 接口绑定
- 更改默认服务端口
- 认证配置
- 禁用特定命令
- 日志记录
- 防范字符串转义和 NoSQL 注入
- 防范由外部客户端精心挑选的输入触发的攻击
- 防火墙限制访问
- 禁止redis中存储敏感的明文数据
- Redis 安全配置总结示例
Redis提供的访问控制、代码安全问题、选择恶意输入可从外部触发的攻击等功能,需要我们运维人员进行相应的配置提高安全性。
- 非特权运行
描述: Redis 不需要 root 权限即可运行,建议以仅用于此目的的非特权redis用户身份运行它,此种方式能最大程度防止CONFIG SET/GET 目录和其他类似运行时配置指令的可能性。
#设置一个单独的redis账户很有必要,redis crackit就利用到了root用户的特性来重置authorized_keys。首先创建一个redis账户,然后通过该账户启动。
$ useradd redis
$ setsid sudo -u redis redis-server /etc/redis.conf
$ ps -elf|grep redis #可以看到是redis用户启动
# 4 S root 9048 1 0 80 0 - 59753 poll_s 19:43 ? 00:00:00 sudo -u redis redis-server /etc redis.conf
# 4 S redis 9049 9048 0 80 0 - 38471 ep_pol 19:43 ? 00:00:00 redis-server
-文件权限
描述: 因为redis密码明文存储在配置文件中,所以我们需要限制redis文件目录访问权限,如设置redis的主目录权限为700(rwx------),如果redis.conf配置文件独立于redis主目录权限修过为600(rw-------)。
# 文件权限
chmod 700 /usr/local/redis/
chmod 600 /etc/redis/6379.conf
# 所属者、组
chown redis:redis /etc/redis/6379.conf
chown redis:redis /usr/local/redis/
- ip绑定
描述: 除了网络中受信任的客户端之外,每个人都应该拒绝访问 Redis 端口,因此运行 Redis 的服务器应该只能由使用 Redis 实现应用程序的计算机直接访问。
假如服务器有两个网络接口(一个A区域、一个B区域),如果只需要A区域的机器访问则只绑定到A区域网络接口中,如服务器自身访问则只绑定到本地回环接口上。
# 通过在redis.conf文件中添加如下一行,可以将 Redis 绑定到单个接口:
bind 127.0.0.1 192.168.1.200
Tips:注意除了您可以绑定IPV4以为你还可绑定IPV6
- 更改默认服务端口
描述: 除了我们可以指定绑定的接口外,我们还可以更改默认的redis服务端口,可以防止黑客针对于默认Redis服务扫描探测。
# 将默认的服务断开从6379变成63791
port 63791
认证配置
描述: 为Redis服务端设置一个认证密码是非常必须,下面讲解 Redis 配置密码认证的几种方式总结:
操作流程:
# 1.通过redis.conf文件中进行配置,此种方式修改后需要重启Redis。
vim /etc/redis.conf
requirepass WeiyiGeek # WeiyiGeek 即认证密码
masterauth WeiyiGeek # 配置主节点认证密码, 注意若master配置了密码则slave也要配置相应的密码参数否则无法进行正常复制的
# 2.通过命令行进行配置,此种方式的优点无需重启Redis。
redis 127.0.0.1:6379[1]> config set requirepass my_redis
OK
redis 127.0.0.1:6379[1]> config get requirepass
1) "requirepass"
2) "my_redis"
- 使用密码验证登陆Redis服务器:
# 方式1:密码明文会被记录到系统命令执行历史中(极其不推荐/不安全)
redis-cli -h 127.0.0.1 -p 6379 -a WeiyiGeek
# 方式2:交互式进行配置
redis-cli -h 127.0.0.1 -p 6379
redis 127.0.0.1:6379> auth WeiyiGeek # OK
非常注意: AUTH 命令与其他所有 Redis 命令一样,以未加密的方式发送,因此它无法防范对网络有足够访问权限以执行窃听的攻击者, 所以对应高敏感的数据建议配置TLS 支持(Redis 在所有通信通道上都可选地支持 TLS)以加密数据与命令传输。
- 禁用特定命令
描述: 我们可以禁用 Redis 中的命令或将它们重命名为不可猜测的名称,以便普通客户端仅限于指定的一组命令,比如漏洞就利用config/save两个命令完成攻击 。
由于redis无用户权限限制,建议将危险的命令使用rename配置项进行禁用或重命名,这样外部不了解重命名规则攻击者,就不能执行这类命令FLUSHDB, FLUSHALL, KEYS, PEXPIRE, DEL, CONFIG, SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM, RENAME, DEBUG, EVAL
例如: 普通用户可能无法调用Redis CONFIG 命令来更改实例的配置,但提供和删除实例的系统应该能够这样做。
# redis.conf 配置文件
# 方式1.CONFIG / FLUSHALL命令被重命名为一个不可猜测的名称
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
rename-command FLUSHALL b840fc02d524045429941cc15f59e41cb7be6c53
# 方式2.通过将其重命名为空字符串来完全禁用它(或任何其他命令)
rename-command CONFIG ""
rename-command FLUSHALL ""
Tips: 注意配置后需要重新redis-server服务。
-日志记录
描述: 为Redis创建访问(或Debug)日志(根据需求设置),在建立Redis蜜罐时,如果有攻击尝试时,就开业及时发现监控redis安全状态, 以及可以监控cmdstat_*指标信息报警;
# 执行info commandstats 看出命令执行的次数、命令耗费的 CPU 时间(单位毫秒)、执行每个命令耗费的平均 CPU 时间(单位毫秒)
cmdstat_get:calls=2,usec=15,usec_per_call=7.50
cmdstat_select:calls=1,usec=9,usec_per_call=9.00
cmdstat_keys:calls=4,usec=1948,usec_per_call=487.00
cmdstat_auth:calls=3123,usec=8291,usec_per_call=2.65
日志记录配置:
logfile "/usr/local/redis/redis.log" #日志文件存放目录
loglevel verbose #记录访问信息
- 防范字符串转义和 NoSQL 注入
描述: Redis 协议没有字符串转义的概念,所以一般情况下使用普通客户端库是不可能注入的, 但有可能会通过EVAL和EVALSHA命令执行的 Lua 脚本来构造恶意脚本。
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
Tips : EVALSHA 通过其 SHA1 摘要评估缓存在服务器端的脚本。脚本使用SCRIPT LOAD命令缓存在服务器端。该命令在其他方面与EVAL相同.
- 防范由外部客户端精心挑选的输入触发的攻击
描述: 有可能攻击者构造恶意的数据结构插入到 Redis 数据库中, 这可能会触发Redis 内部实现的数据结构的病态(最坏情况)算法复杂性。
例如,攻击者可以通过 Web 表单将一组已知散列到同一桶的字符串提供到散列表中,以便将 O(1)预期时间(平均时间)变为O(N )最坏的情况,消耗比预期更多的 CPU,并最终导致拒绝服务。
解决办法: 为了防止这种特定的攻击,Redis 对哈希函数使用了每次执行的伪随机种子。
-防火墙限制访问
描述: 前面针对Redis-server服务层面进行安全配置,此处针对网络层面进行限制,只允许指定的IP地址进行访问,在主机上配置防火墙的优点是防止同一网段的东西流量。
在Linux上系统防火墙设置命令:
iptables -A INPUT -s x.x.x.x -p tcp --dport 6379 -j ACCEPT #如果需要其他机器访问或者设置了slave模式,那就记得加上相应的防火墙设置(Centos6)
firewall-cmd --add-rich-rule="rule family="ipv4" source address="x.x.x.x" port protocol="tcp" port="6379" accept" --permanent #(Centos7)
在Windows上系统防火墙设置命令:
New-NetFirewallRule -Name "redis-server-access" -DisplayName "redis-server" -Description "redis-server 客户端访问规则" -Direction Inbound -LocalPort 6379 -RemoteAddress x.x.x.x -Protocol TCP -Action Allow -Enabled True
Get-NetFirewallRule -Name "redis-server-access" | Format-Table
- 禁止redis中存储敏感的明文数据
描述: Redis设计旨在提供高性能的KV服务,至少目前在权限访问控制和数据持久化方面比较弱化,所以从应用层面上,不建议使用Redis来存储敏感信息,例如鉴权的密码。
Redis 安全配置总结示例
# 配置文件 vim /etc/redis/redis.conf
# 1.信任的内网运行,尽量避免有公网访问(如果存在内网中其他固定IP则需要设置防火墙)
bind 127.0.0.1
# 2.绑定redis监听的网络接口(通过redis配置项bind,可同时绑定多个IP), 把6379改为其他得端口(或者采用unix管道进行数据管理)
port 63791
# 3.开启redis密码认证,并设置高复杂度密码设置,因查询效率高,auth这种命令每秒能处理10w次以上(所以需要增加强度)
# echo -e "weiyigeek"|sha256sum
requirepass 097575a79efcd7ea7b1efa2bcda78a4fc7cbd0820736b2f2708e72c3d21f8b61
# 4.日志文件存放目录以及记录redis访问信息。
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably) 默认
# warning (only very important / critical messages are logged)
logfile "/usr/local/redis/redis.log"
loglevel verbose
# 5.默认情况下,启用保护模式。只有在以下情况下才应禁用(no)它
# - 您确定希望其他主机的客户端连接到Redis
# - 即使没有配置身份验证,也没有特定的接口集
# - 使用“bind”指令显式列出。
protected-mode yes
# 6.重命名特殊命令(根据需求)
# `FLUSHDB, FLUSHALL, KEYS, PEXPIRE, DEL, CONFIG, SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM, RENAME, DEBUG, EVAL`
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
rename-command FLUSHDB b840fc02d524045429941cc15f59e41cb7be6c53
rename-command FLUSHALL b840fc02d524045429941cc15f59e41cb7be6c54
rename-command EVAL b840fc02d524045429941cc15f59e41cb7be6c55
rename-command DEBUG b840fc02d524045429941cc15f59e41cb7be6c56
rename-command SHUTDOWN b840fc02d524045429941cc15f59e41cb7be6c7
网友评论