技术解析
楼主的一台 Linode ,运行好好的突然就 kernel panic 了,不能重启,重启有很大概率无法启动——成功的概率大概小于 1%,不要问我怎么计算的,的确进去过一次...
首先说频繁重启肯定是 Lassie 狗的原因,检测到系统没有启动就会尝试 reboot ,这并不是问题
问题在于看到 dmesg 的一瞬间楼主就傻了,贴一小段出来:
Entering non-interactive startup
Calling the system activity data collector (sadc)...
ipset: Loaded with no configuration
ip6tables: Applying firewall rules: [ OK ]^M
iptables: Applying firewall rules: [ OK ]^M
Bringing up loopback interface: [ OK ]^M
Bringing up interface eth0: BUG: unable to handle kernel NULL pointer dereference at 0000000000000030
这是在说 eth0 无法启动啊?不过楼主非常确信没有改过网卡的配置。
于是改为 Single 模式启动, Lish 进去,先检查了一下配置信息,看起来都没什么问题,然后楼主就在拼命回忆之前修改了哪些配置,然并卵,因为很久没重启过了已然记不清了。
没办法,只好先禁用一部分启动项,把和网络有关的都 chkconfig off 掉了,改回正常运行模式,重启,喵了个咪,起来了!
于是非常确定嫌犯就在这些启动项里面,最后逐个排查的结果(点重启点到手断),居然是 iptables 导致的!
于是尝试清空了 iptables 的全部规则,重新 chkconfg iptables on ,重启,没问题!
那么问题必然出在规则上面了!
楼主尝试添加了之前删除的规则,没问题! service iptables save 重启!擦,又特喵的挂了!
那么这几条规则到底是什么呢?还是贴一小部分出来:
-A PREROUTING -p tcp -m multiport --dports 60000:60199 -j REDIRECT --to-ports XXXX
-A PREROUTING -p udp -m multiport --dports 60000:60199 -j REDIRECT --to-ports XXXX
-A PREROUTING -p tcp -m multiport --dports 60200:60399 -j REDIRECT --to-ports XXXX
-A PREROUTING -p udp -m multiport --dports 60200:60399 -j REDIRECT --to-ports XXXX
其实就是个范围端口重定向,看起来很正常啊,不过只要 iptables 启动的时候有这些规则,必死无疑。
想到这里的时候,楼主本来都准备放弃治疗了,干脆启动后动态载入这些规则罢了。
不过奇迹的瞬间就这么来了,楼主最后一次超载了智商,突然想起来,前几天修改过 sysctl 里面的一个参数 net.ipv4.ip_local_port_range
赶紧打开配置文件看,现在是 net.ipv4.ip_local_port_range = 1024 65535
难道是这个端口范围和我的重定向存在冲突?赶紧修改为 1024 59999 ( 60000 以后的楼主都做了重定向),保存全部规则,重启,妥了。
那么问题来了,且问各位看官,端口重定向为何会引发 kernel panic ?
和 ip_local_port_ranged 的冲突又是怎么形成的?