本文主要介绍的是在默认安装完Redis后,不进行任何配置的情况下直接远程连接redis server时遇到问题的解决办法。
前期准备: 打开redis server所在机器防护墙的6379端口
iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT
service iptables save
五种解决方法:
1. 在redis server端开启一个redis client然后运行'CONFIG SET protected-mode no',这个方法在重启redis server后失效
2. 在redis.conf中设置protected-mode no,默认是protected-mode yes, 这个方法在重启redis server后仍然有效
3. 启动redis server时加上参数 --protected-mode no,这种方法需要再启动时添加参数,比较麻烦而且如果实施人员忘记了会产生production issue
4. 绑定redis server的ip: bind 192.168.17.133
按照Redis关于网络配置的说明,默认情况下bind 127.0.0.1是注释掉的,这时只有redis server本机的client可以访问redis server,因为它运行在保护模式下,这是出于安全考虑的,因为不绑定任何ip意味着将redis server完全暴露在internet上,这是非常危险的,那么现在我们要在保护模式下远程通过redis server这台机器的网卡访问redis server, 所以我们还需要将这个网卡的ip绑定到redis server上,这样除了本机可以访问redis server外,其他机器也可以通过192.168.17.133这个网卡访问redis server, 当然我们也要绑定redis server的本地ip127.0.0.1,否则本地直接执行redis-cli就无法连接到redis server,正确的配置如下:
bind 127.0.0.1 192.168.17.133
5. 在redis.conf中开启密码,我设置的密码是michael123
requirepass michael123
我们知道linux系统是有防火墙的,默认情况下redis server使用的6379端口是关闭状态,所以我们会先遇到无法连接的问题,这时就需要开启端口,root用户执行如下两个命令:
iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT
service iptables save
执行上述命令后,我们执行查看防火墙规则的命令,会看到6379端口已经打开了:
[root@localhost src]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:6379
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
现在我们执行命令redis-server ../redis.conf 启动redis服务, ../redis.conf是原始的文件,我们没有做任何更改:
[root@localhost src]# pwd
/opt/soft/redis-4.0.8/src
[root@localhost src]# ./redis-server ../redis.conf
2750:C 11 Mar 07:06:49.098 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2750:C 11 Mar 07:06:49.098 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=2750, just started
2750:C 11 Mar 07:06:49.098 # Configuration loaded
2750:M 11 Mar 07:06:49.098 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.8 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 2750
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
2750:M 11 Mar 07:06:49.099 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2750:M 11 Mar 07:06:49.099 # Server initialized
2750:M 11 Mar 07:06:49.099 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
2750:M 11 Mar 07:06:49.099 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
2750:M 11 Mar 07:06:49.099 * DB loaded from disk: 0.000 seconds
2750:M 11 Mar 07:06:49.099 * Ready to accept connections
redis server启动成功,我们查看下redis server的ip,
[michael@localhost /]$ ifconfig | grep inet | grep Bcast | awk -F: '{print $2}' | awk '{print $1}'
192.168.17.133
然后使用这个ip:192.168.17.133 远程机访问redis server是会出现如下错误:
[root@localhost src]# ./redis-cli -h 192.168.17.133 -p 6379
192.168.17.133:6379> ping
(error) DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
192.168.17.133:6379>
按照提示,有4种解决办法:
1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent.
在redis server端开启一个redis client然后运行'CONFIG SET protected-mode no', 如下:
[root@localhost src]# pwd
/opt/soft/redis-4.0.8/src
[root@localhost src]# ./redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> CONFIG SET protected-mode no
OK
127.0.0.1:6379>
再次远程连接下ping成功:
[root@localhost src]# ./redis-cli -h 192.168.17.133 -p 6379
192.168.17.133:6379> ping
(error) DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
192.168.17.133:6379> ping
PONG
192.168.17.133:6379>
但是这种方法在redis server重启后会失效,所以不建议这么做,我们接着看第二种方法
2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server.
在redis.conf中设置protected-mode no,默认是protected-mode yes
[root@localhost redis-4.0.8]# pwd
/opt/soft/redis-4.0.8
[root@localhost redis-4.0.8]# vi redis.conf
# are explicitly listed using the "bind" directive.
protected-mode no
"redis.conf" 1308L, 58376C written
重启redis server:
[root@localhost src]# pwd
/opt/soft/redis-4.0.8/src
[root@localhost src]# ./redis-server ../redis.conf
2332:C 11 Mar 05:52:15.570 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2332:C 11 Mar 05:52:15.570 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=2332, just started
2332:C 11 Mar 05:52:15.570 # Configuration loaded
2332:M 11 Mar 05:52:15.571 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.8 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 2332
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
2332:M 11 Mar 05:52:15.572 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2332:M 11 Mar 05:52:15.572 # Server initialized
2332:M 11 Mar 05:52:15.572 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
2332:M 11 Mar 05:52:15.572 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
2332:M 11 Mar 05:52:15.572 * DB loaded from disk: 0.000 seconds
2332:M 11 Mar 05:52:15.572 * Ready to accept connections
再次远程连接下ping成功:
[root@localhost src]# ./redis-cli -h 192.168.17.133 -p 6379
192.168.17.133:6379> ping
PONG
192.168.17.133:6379>
这个方法在重启redis server后仍然有效
3) If you started the server manually just for testing, restart it with the '--protected-mode no' option.
启动redis server时加上参数 --protected-mode no
[root@localhost src]# ./redis-server ../redis.conf --protected-mode no
2337:C 11 Mar 05:55:50.327 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2337:C 11 Mar 05:55:50.327 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=2337, just started
2337:C 11 Mar 05:55:50.328 # Configuration loaded
2337:M 11 Mar 05:55:50.328 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 4.0.8 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 2337
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
2337:M 11 Mar 05:55:50.329 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2337:M 11 Mar 05:55:50.329 # Server initialized
2337:M 11 Mar 05:55:50.329 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
2337:M 11 Mar 05:55:50.329 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
2337:M 11 Mar 05:55:50.329 * DB loaded from disk: 0.000 seconds
2337:M 11 Mar 05:55:50.329 * Ready to accept connections
再次远程连接下ping成功:
[root@localhost src]# ./redis-cli -h 192.168.17.133 -p 6379
192.168.17.133:6379> ping
PONG
192.168.17.133:6379>
这种方法需要再启动时添加参数,比较麻烦而且如果实施人员忘记了会产生production problem,所以不建议这么做,我们接着看第四种方法
4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
其实这里提供了两个方法,绑定一个ip或者添加redis 密码。
绑定redis server的ip: bind 192.168.17.133
[root@localhost src]# vi redis.conf
################################## NETWORK #####################################
# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 lookback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1
上面是Redis关于网络配置的说明,可以看到默认情况下bind 127.0.0.1是注释掉的,这时只有redis server本机的client可以访问redis server,因为它运行在保护模式下,这是出于安全考虑的,因为不绑定任何ip意味着将redis server完全暴露在internet上,这是非常危险的,那么现在我们要在保护模式下远程通过redis server这台机器的网卡访问redis server, 所以我们还需要将这个网卡的ip绑定到redis server上,这样除了本机可以访问redis server外,其他机器也可以通过192.168.17.133这个网卡访问redis server, 当然我们也要绑定redis server的本地ip127.0.0.1,否则本地直接执行redis-cli就无法连接到redis server,正确的配置如下:
bind 127.0.0.1 192.168.17.133
再次远程连接下ping成功:
[root@localhost src]# ./redis-cli -h 192.168.17.133 -p 6379
192.168.17.133:6379> ping
PONG
192.168.17.133:6379>
现在我们看看最后一个方法,也就是加密码,我设置的密码是michael123
################################## SECURITY ###################################
# Require clients to issue AUTH
# commands. This might be useful in environments in which you do not trust
# others with access to the host running redis-server.
#
# This should stay commented out for backward compatibility and because most
# people do not need auth (e.g. they run their own servers).
#
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
requirepass michael123
加上密码参数后再次远程连接下ping成功:
[root@localhost src]# ./redis-cli -h 192.168.17.133 -p 6379 -a michael123
192.168.17.133:6379> ping192.168.17.133:6379>
总结:
基于上述分析,事实上Redis一共给出了5个方案,这里我推荐大家用最后一种,也就是加密码