实验室需要一个新的 redis 服务器,作为内网的公共服务。所以配了个内存 20G 硬盘 15G 的奇葩货。 这货的操作系统为 CentOS, 基本什么都没装, 通过 ISO 捣腾出来后,就用 yum 更新了下,加了个 tmux 和 redis, 一通配置完毕 chkconfig redis on, 然后自嗨了下。

[root@localhost ~]# redis-cli ping
PONG

这种小事做起来毫无压力,写写代码看看俺妹顺便搞定操作系统,三线操作真是毫无压力,收工的时候,顺手测试下远程ping下--本来只是走个程序而已,意外发现居然没有得到需要的 PONG.

[yu@argcv ~]$ redis-cli -h xx.xx.xx.xx
Could not connect to Redis at xx.xx.xx.xx:6379: No route to host
not connected> 

我了个擦,这是毛情况。 redis的.conf 文件中如果有内容如下:

bind 127.0.0.1

那么它就会被配置为仅接受本地的请求,这个是早就知道的,所以在此之前已经设置为

# If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for incoming connections.
#
# bind 127.0.0.1
bind 0.0.0.0

无误,但为什么还是有问题呢? google 很久,大多是一些愚蠢的错误,比如service居然不知道开的什么的。从一地鸡毛中终于找到了一些关键线索: iptables。

iptables 是管理系统 IO 的重要工具,里面一坨坨的规则让系统知道什么地址来了做什么,顺便还有防火墙和 log 记录的功效。CentOS 编译完毕后,预设了一大堆的规则,导致我亲爱的 redis 直接被挡在 VM 里面了。

通过命令

# iptables -L -n

或者

# iptables --list

可以发现了一组 CentOS 预设的规则信息,具体是否某个内容挡道了,不甚了然。 反正在内网,关掉试试先。

RH系列可以通过如下命令搞定

/etc/init.d/iptables save
/etc/init.d/iptables stop

然后再试试,发现搞定了。果然是它的问题。

其它发行版也可以使用下面这组命令 -- 这组命令对RH用户同样有效,大意是删掉所有 iptables 的规则。

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

生效后一般不会出现问题了.

当然,防火墙什么的还是要有的,安全还是不能忽视的。我这个 VM 是在内网中使用,安全稍微随意点,但到了外网,还是要做好工作的,iptables 的设置可以参考 References 之 2.

一般情况下, redis 会开放&监听 6379 端口,我们只需要开放此端口一般就可以了。

iptables -A INPUT -p tcp --dport 6379 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 6379 -j ACCEPT

这样打开 6379 的 IO 就可以了. 然后保存一下。

需要说明的是,CentOS默认使用的已经不是iptables了,所以重启后可能有点奇怪的事情发生,各位可以考虑看看这个配置下。

References

  1. No Route to Host error and solution
  2. redis “No route to host” when pinging a remote redis host
Categories: Code

Yu

Ideals are like the stars: we never reach them, but like the mariners of the sea, we chart our course by them.

6 Comments

vfhky · March 6, 2014 at 19:09

Google Chrome 30.0.1599.101 Google Chrome 30.0.1599.101 Windows 7 x64 Edition Windows 7 x64 Edition

一般service iptables stop把防火墙关了。vsftp端口没配的话就用不了。

    yu · March 6, 2014 at 22:42

    Google Chrome 33.0.1750.146 Google Chrome 33.0.1750.146 GNU/Linux x64 GNU/Linux x64

    @vfhky 并不是所有distribution都支持这样做

    而且砍掉默认的重新自己配端口貌似也不难

      vfhky · March 7, 2014 at 14:15

      Google Chrome 30.0.1599.101 Google Chrome 30.0.1599.101 Windows 7 x64 Edition Windows 7 x64 Edition

      @Yu Jing 看需求吧,生产上可能严格些。平时直接关了。

eliteYang · March 16, 2014 at 14:23

Google Chrome 32.0.1700.107 Google Chrome 32.0.1700.107 Windows 7 x64 Edition Windows 7 x64 Edition

哈哈……欢迎淌雷,我当初因为iptable的问题也查了很久,内外网开放权限不一致,IP也不一样导致了很多问题

enilu · January 20, 2016 at 16:16

Firefox 43.0 Firefox 43.0 GNU/Linux x64 GNU/Linux x64

有用,谢谢,不过我的防火墙配置规则,被前面的覆盖了,所以必须插入到前面:

iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 6379 -j ACCEPT

    yu · January 21, 2016 at 13:02

    Google Chrome 47.0.2526.111 Google Chrome 47.0.2526.111 Mac OS X  10.11.2 Mac OS X 10.11.2

    @enilu
    很高兴能对你有所帮助.

    看了下你的那篇日志. 感觉你的情况和本文描述不太相同.

    • 若 redis server 和 client 都在本机, 一般更加倾向于使用文件形式的 unix sock, 而把 port 置为 0. 这么处理会更加安全. gitlab 的 configure file 里面也是可以设置 sock file 的. 注意 sock file 的需要放在 gitlab 使用的用户能访问的地方. 再次启用服务后, 可能要检查下 SELinux 是否正确放行了.
    • 若 server 和 client 都在本机, 应该加的规则是 -s 127.0.0.1 而不是 –dport 6379, redis 的服务端也应该是 127.0.0.1 而不是 0.0.0.0, 我在本文中设置为 0.0.0.0, 并且放开权限是因为它是一个虚拟机, 仅仅提供 redis 服务, 而 client 是放在内网的其它虚拟机里 . 而你的情况是只有 gitlab 在后端要调用它. 情况是不一样的.

    此外, 若引用了别人的内容, 希望你能加上引用信息. 谢谢.

Leave a Reply

Your email address will not be published. Required fields are marked *