redis安全架构考虑事项

下面罗列出于安全需要考虑的一些事项

1.禁止一些高危命令

修改 redis.conf 文件,添加一下命令来禁用远程修改 DB 文件地址

rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command SHUTDOWN ""
rename-command CONFIG   ""
rename-command EVAL     ""

2.以低权限运行 Redis 服务

为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆

创建一个redis账户,然后通过该账户启动redis,命令如下:
su - redis -c " /redis/bin/redis-server /redis/etc/redis.conf"

使用进程查看ps aux|grep redis-server可见进程以redis运行

redis 3384 0.8 0.1 137440 4168 ? Ssl 17:43 0:00 /redis/bin/redis-server 192.168.196.133:6379

3.为 Redis 添加密码验证

修改 redis.conf 文件,添加

requirepass mypassword

4.禁止外网访问 Redis

修改 redis.conf 文件,添加或修改

bind 192.168.255.111 #本机ip

注:bind的意思不是绑定外部服务器的IP,而是绑定本机可以接受访问的IP

最好使用防火墙来开放固定ip

#例如只允许192.168.1.*这一段C类地址访问,其他IP地址禁止访问:

#只允许192.168.255.112访问 tcp 6379端口
firewall-cmd --zone=public --add-rich-rule 'rule family="ipv4" source address="192.168.255.112" port port=6379 protocol=tcp reject' --permanent
#重启
systemctl restart firewalld.service
#查看配置结果
firewall-cmd --list-all

5.redis可考虑换其他端口不要6739

6.数据加密支持

因为 Redis 不支持加密. 想要在互联网/或不可信网络上实现加密传输, 就需要额外的保护层, 例如SSL代理。我们推荐使用 spiped

7.字符串转义和NoSQL注入

应用程序应该避免将不受信任来源的字符串, 当做Lua脚本来执行。

8.清除历史里的密码:

foo@bar:~$ rm .rediscli_history
foo@bar:~$ ln -s /dev/null .rediscli_history
foo@bar:~$ redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> exit
foo@bar:~$ ls -al .rediscli_history
lrwxrwxrwx 1 foo foo 9 Sep 30 00:19 .rediscli_history -> /dev/null

9.设置Redis最大占用内存

设置maxmemory参数,一般推荐Redis设置内存为最大物理内存的四分之三

[root@localhost redis]# vi redis.conf
#例如:本机自带内存只有1G,所以设置0.75G,换成byte是751619276
# maxmemory <bytes>
maxmemory 751619276

10.主从配置

主数据库可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数据库。而从数据库一般是只读的,并接受主数据库同步过来的数据。

##比如现有如下3台实例
#192.168.255.111 主
#192.168.255.112 从
#192.168.255.113 从

#主节点无需配置slaveof , 修改两个从节点配置文件
[root@localhost redis]# vi redis.conf
#slaveof参数的格式如 masterip主节点ip masterport主节点端口
#slaveof <masterip> <masterport>
slaveof 192.168.255.111 6379
#如果master服务器设置有密码则需要配置masterauth参数。各个节点的密码都必须一致
#masterauth <master-password>
masterauth 123456

#启动
[root@localhost redis]# src/redis-server ./redis.conf

#查看效果
[root@localhost redis]# src/redis-cli -h 192.168.255.111
192.168.255.111:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.255.112,port=6379,state=online,offset=13086250,lag=1
slave1:ip=192.168.255.113,port=6379,state=online,offset=13086250,lag=1
master_replid:dcb0aea47bd9c540a1359c709170f413dfc3e922
master_replid2:bfd7df000877bc0a858e753de571436408718ee5
master_repl_offset:13086250
second_repl_offset:11574
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:12037675
repl_backlog_histlen:1048576

[root@localhost redis]# src/redis-cli -h 192.168.255.113
192.168.255.113:6379> info replication
# Replication
role:slave
master_host:192.168.255.111
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:13078489
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:dcb0aea47bd9c540a1359c709170f413dfc3e922
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:13078489
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:12029914
repl_backlog_histlen:1048576

11.哨兵配置

哨兵的作用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。

##部署三个哨兵三台机器配置一样即可
#要注意的是bind 要改为本机地址

[root@localhost redis]# vi sentinel.conf
#本机地址
port 26379
bind 192.168.255.111   #本机地址
dir "/usr/local/redis/tmp"
sentinel monitor mymaster 192.168.255.111 6379 1  #mymaster是集群的名称可自定义,IP地为集群中master的地址,注意与bind的区别 6379表示端口 1表示 需要1个哨兵同意才能执行故障转移操作
sentinel down-after-milliseconds mymaster 30000  #超过多少毫秒跟一个redis实例断了连接,哨兵就可能认为这个redis实例挂了
sentinel failover-timeout mymaster 60000  #failover转移时间,超出此时间认为master转移失效,重新开始转移
sentinel parallel-syncs mymaster 1          #新的master别切换之后,同时有多少个slave被切换到去连接新master,重新做同步,数字越低,花费的时间越多 
protected-mode yes                       #关闭安全模式,否则会报错 
sentinel auth-pass mymaster 123456   #如果集群设置了密码,需要添加
logfile /usr/local/redis/logs/sentinal.log      #日志路径


#启动哨兵
[root@localhost redis]# src/redis-sentinel ./sentinel.conf &
#查看进程是否启动
[root@localhost redis]# ps -ef|grep redis

12.cluster集群相关

搭建

[root@localhost redis]# vi redis.conf
cluster_enabled true
cluster-config-file /usr/local/redis/logs/nodes-6379.conf  #6379改为各自的端口
cluster-node-timeout 15000



firewall-cmd --zone=public --add-port=17000/tcp --permanent
firewall-cmd --zone=public --add-port=17001/tcp --permanent
firewall-cmd --reload
yum -y install ruby ruby-devel rubygems rpm-build
gem install redis

错误redis requires ruby version >=2.2.2的解决方案
https://blog.csdn.net/saafdgvsdg/article/details/80699952
(1) [root@linux ~]# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB 
  (2) [root@linux ~]# curl -sSL https://get.rvm.io | bash -s stable
    (3) [root@linux ~]# find / -name rvm -print

    (4)[root@linux ~]#  source /usr/local/rvm/scripts/rvm   (路径以上图中最后的为主)
    (5) [root@linux ~]#  rvm list known                     (查看rvm库中已知的ruby版本)
    (6)  [root@linux ~]# rvm install 2.4.1                    (安装一个ruby)
    (7) [root@linux ~]# rvm use 2.4.1                       (使用一个ruby版本:)
    (8) [root@linux ~]# rvm use 2.4.1 --default     (设置ruby2.4.1为默认的ruby)
    (9) [root@linux ~]# ruby --version                   (查看ruby版本)




创建集群
src/redis-trib.rb create --replicas 1 192.168.255.111:6379 192.168.255.111:6380 192.168.255.112:6379 192.168.255.112:6380 192.168.255.113:6379 192.168.255.113:6380


#错误解决办法:ERR Slot 741 is already busy
#用redis-cli登录到每个节点执行flushall和cluster reset就可以了
#redis创建集群失败——can't connect to node 192.168..
#bind 改成本机ip 如192.168.255.113 127.0.0.1
#MOVED 5798 192.168.255.112:6379
#redis/src/redis-cli -p 6379 -c

#错误处理
[ERR] Node 172.168.63.202:7001 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

解决方法:

1)、将需要新增的节点下aof、rdb等本地备份文件删除;

2)、同时将新Node的集群配置文件删除,即:删除你redis.conf里面cluster-config-file所在的文件;

3)、再次添加新节点如果还是报错,则登录新Node,./redis-cli–h x –p对数据库进行清除:

172.168.63.201:7001>  flushdb      #清空当前数据库

 

先把节点都加入到集群中,之后再做加密

##集群密码设置

#方式一:修改所有redis集群中的redis.conf,此方式需要重启所有节点
[root@localhost redis]# vi redis.conf
masterauth 123456
requirepass 123456

#方式一:进入各个实例进行设置,此方式不需要重启
[root@localhost redis]# src/redis-cli -c -h 192.168.156.113 -p 6379-a 123456
192.168.156.113:6379>config set masterauth 123456
192.168.156.113:6379>config set requirepass 123456
192.168.156.113:6379>auth 123456
192.168.156.113:6379>config rewrite

#连接集群节点  要加-c
src/redis-cli -h 192.168.126.7 -p 7000 -a 123456 -c

设置密码之后如果需要使用redis-trib.rb的各种命令

如:redis-trib.rb check 127.0.0.1:7000,则会报错ERR] Sorry, can’t connect to node 127.0.0.1:7000

解决办法:

  修改gem的redis工具下的一个文件client.rb,对应内容如下:

  :password => "123456", #指定redis登录密码

(一般默认路径/usr/lib/ruby/gems/1.8/gems/redis-3.2.1/lib/redis/client.rb,另可通过命令find / -name client.rb进行全盘搜索)

关于集群命令

https://blog.csdn.net/u012099568/article/details/79419422

https://www.cnblogs.com/xlxue/p/7777257.html

13.关于脑裂

概念:某个master所在机器突然脱离了正常的网络,跟其他slave机器不能连接,但是实际上master还运行着

此时哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master

这个时候,集群里就会有两个master

修改redis.conf文件

min-slaves-to-write 3

min-slaves-max-lag 10

要求至少有3个slave,数据复制和同步的延迟不能超过10秒

如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了

上面两个配置可以减少异步复制和脑裂导致的数据丢失

14.缓存降级

服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。

 

15.关于Redis的requirepass和masterauth密码的设置问题

建议redis启用密码时将各个节点的masterauth和requirepass设置为相同的密码,降低运维成本。当然设置为不同也是可以的,注意slave节点masterauth和master节点requirepass的对应关系就行。

16.redis持久化备份及备份恢复

redis有两种持久化策略

①.RDB(默认开启)

优点:启动时间会更短 

缺点:会丢失最后一次快照后的内容

SAVE命令:会阻塞主进程

BGSAVE命令:使用BGSAVE的话redis会fork出一个子进程来执行快照操作,而不影响主进程

默认的redis.conf配置文件说明

[root@localhost redis]# cat redis.conf
save 900 1 # 900秒内有至少1个键被更改则进行快照 
save 300 10 # 300秒内有至少10个键被更改则进行快照 
save 60 10000 # 60秒内有至少10000个键被更改则进行快照

dir "/usr/local/redis"
#定时脚本为
#!/bin/bash
echo "start..."
sdate=$(date "+ %Y-%m-%d %H:%M:%S")
msg=`/usr/local/redis/src/redis-cli -h 192.168.255.111 -p 6379 bgsave`
echo "start bgsave time:$sdate"
result=`/usr/local/redis/src/redis-cli -h 192.168.255.111 -p 6379 info Persistence | grep "rdb_bgsave_in_progress" | awk -F":" '{print $2}'`
while [ `echo ${result} | awk -v tem="0" '{print($2>tem)? "1":"0"}'` -eq "1" ] ; do
    sleep 1
    result=`/usr/local/redis/src/redis-cli -h 192.168.255.111 -p 6379 info Persistence | grep "rdb_bgsave_in_progress" | awk -F":" '{print $2}'`
done
edate=$(date "+ %Y-%m-%d %H:%M:%S")
echo "end bgsave time:$edate"
echo "renaming rdb file..."
date=$(date "+ %Y%m%d")
cp "/usr/local/redis/dump.rdb" "/usr/local/redis/snapshots/${date}.rdb"
echo "finish backup rdb file"
echo "end"

#加入定时任务
0 0 * * *  usr/local/redis/redis-backup.sh >> /usr/local/redis/logs/backup.txt

②AOF持久化

优点:数据一般不会丢失

缺点:持久化文件会变得越来越大,恢复时间较慢

##配置

dir /home/redis/data_6379/
appendonly yes       #启用AOF持久化方式
appendfilename appendonly.aof #AOF文件的名称,默认为appendonly.aof
# appendfsync always #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。
appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。
# appendfsync no     #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。



##恢复

#拷贝 AOF 文件到 Redis 的数据目录
cp appendonly.aof /home/redis/data_6379/
#重启
redis-server redis_6379.conf

③官方建议:
通常,如果你要想提供很高的数据保障性,那么建议你同时使用两种持久化方式。
如果你可以接受灾难带来的几分钟的数据丢失,那么你可以仅使用RDB。
很多用户仅使用了AOF,但是我们建议,既然RDB可以时不时的给数据做个完整的快照,并且提供更快的重启,所以最好还是也使用RDB。

目前比较流行的方案是Master上Snapshot和AOF都不做,来保证Master的读写性能,而Slave上则同时开启Snapshot和AOF来进行持久化,保证数据的安全性,也可以考虑将save中的频率调高一些或者调用一个计划任务来进行定期bgsave的快照存储,来尽可能的保障本地化数据的完整性。

④优先级如下:

1.如果只配置 AOF ,重启时加载 AOF 文件恢复数据;

2.如果同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据;

3.如果只配置 RDB,启动是将加载 dump 文件恢复数据。

17.可用的监控工具

https://github.com/LittlePeng/redis-monitor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值