问题

先说下我的单机环境是Ubuntu 16.04,只放了点小应用,一直没升级系统(懒),防火墙规则也是简单地使用iptables来控制。

今天我因需要重启服务器之后,发现突然连不上了,ssh无法连接,ping也不通,我开始慌了。于是我只能进入云服务器商的后台,用网页版登录,不管你是阿里云还是腾讯云还是国外的服务商,现在大多都有这种功能。

进去之后,先任意ping一个公网IP,提示 “Network is unreachable” ,看来这互联网是彻底断了。用ifconfig也能发现本机的公网IP看不见了。

怎么重启一下就这样了呢?

排查

直接检查networking服务状态:

1
systemctl status networking.service

能发现服务运行状态不是Active的,并且提示了是由于iptables规则应用失败,其中可以看见 **“cannot resolve host” **之类的字样,具体现场我没有截图保存,大概是这些内容。

原因基本上就清楚了,因为我前段时间手动禁用了某些IP来做测试:

1
iptables -I INPUT -s xxx.xxx.xxx.xxx -j DROP

并且还将规则保存了下来:

1
iptables-save > /etc/iptables.up.rules

然后现在这些IP已经找不到了,无法解析,才导致了networking服务启动失败。

解决

简单粗暴一点吧,直接重置所有iptables里自定义的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 默认策略设置为ACCEPT,否则后续操作会导致连接断开,无法再次连接
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
# 清空所有规则
iptables -F
iptables -t nat -F
# 删除所有非系统默认的链
iptables -X
iptables -t nat -X
# 保存一下
iptables-save
# 如果之前也持久化了rules,重新保存,避免重启又失效了
iptables-save > /etc/iptables.up.rules

如果涉及IPV6的服务器,上述命令最好换成ip6tables-save再执行一遍。

最后重启网络服务,成功就能联网了:

1
systemctl restart networking.service

后话

总的来说,还是对iptables机制不熟悉导致的问题,没想到Ubuntu 16.04的网络服务必须要先检查iptables并且全部IP解析成功才能运行。此外,iptables在很多新版本的Linux发行版中已经不使用了,有更好的工具取而代之。