远程触发SYSRQ获取最新的dmesg信息-一个几乎没有什么用的方案

简介:

本文在前半部分叙述一个听起来十分吸引人且合理的故事,然后紧接着告诉你这个美好的故事事实上几乎不会发生,最后来个总结。在接下来的一篇文章中,我提出一个比较自我的方案。

第一部分:美好的故事

在 xtables-addons中,有一个特别有意思的小模块,那就是xt_SYSRQ,它作为一个iptables的target加载进内核,可以在远程 为本机发送sysrq命令,这个功能可谓强大。在去年的项目中中,我已经将其部署到了实际的产品中,然而今日再看,发现还是有些美中不足,确实需要改进:

1.原版的xt_SYSRQ没有反馈机制

虽然你可以远程触发一个sysrq命令,但是你得不到任何反馈信息,包括,命令执行成功与否,内核环形缓冲区的内容。有的时候,我仅仅是需要看看dmesg的信息而已,而有的时候,我想看看内核stack的dump信息。我要做的并不仅仅是重启机器这么简单的事。

2.原版的xt_SYSRQ的认证机制有点乱

在 addons中,SYSRQ模块实现一个简单的认证机制,即password认证,为了防止有人攻破password,使用了序列号窗口机制。然而你要知 道,这种防护是很容易攻破的,第一,数据包使用UDP传输,第二,内核中实在不便于做强认证,特别是真的panic的情况下。因此,更好的做法是将这种认 证放在外部。
以上是我发现的两个问题,但是解决它们的时候切记要点到为止,这是为什么呢?
        仔细想想,难道真的需要这种方式来获取远程的dmesg信息吗?如果系统还活着,用SSH的方式不是更好吗?因此,正如xtables-addons文档 中所述,这个功能只是在系统死掉的情况下才会是一种选择方式。知识点只有一个,那就是系统挂起以及panic的时候,中断或许还可以继续被响应,而 Netfilter HOOK的执行作为中断后的软中断也会被继续响应。可能有些人会问,为何系统都panic了,还会响应中断。答案在于你把panic想的过于严重 了,panic只是系统处于恐慌而不知所措的状态,并没有死去。导致系统不知所措的原因可能是系统级的操作bug导致了内存混乱或者别的混乱,系统继续运 行下去将会导致不可知的后果,此时最好的办法就是原地不动,这就是panic。由于中断的响应逻辑是封闭的,所以中断是依然可以响应的,然而如果中断处理 相关的内存被破坏,就彻底没有机会了。
        接下来再看一下远程SYSRQ的安全机制,其实作者原生的方式很安全,再次地,没有必要将其向复杂化路线上扩展太多。系统已然挂起,此时的处理应该尽可能 地简单,安全前提是需要保证的。首先网络上没有传输password的明文,而只传输了其摘要值,这种策略在网络认证领域已经烂大街了,其次,为了防止重 放攻击以及防止碰撞密码,采用了窗口机制,也不失为一个小巧的技巧,于是只要加一个反馈机制,就可以了,上面的问题2基本上不是问题。
        正当一切都已经就绪,知道了该做什么不做什么的时候,当你用Sysrq-c故意把系统Crash之后,你会发现一切瞬间停止,网卡中断完全不再响应...到底发生了什么?

第二部分:现实的情况

在《panic与BUG_ON》 那篇文章中,我曾经说“即使panic了,也还是可以从外部ping通这台机器”,但是不得不说,那仅仅是一种“最好的情况”,99%的情况下,中断将会 停止响应,要想理解这个似乎也不难,应为作为一个操作系统,用户态的进程只是它的一种执行流,还有内核线程,中断,中断上下文的中断下半部,线程上下文的 中断下半部等,并且,经由本机forward的数据包以及arp处理数据包几乎全部都是在中断或者软中断中被处理的,另外,很多的软中断都是可以在中断上 下文被处理(硬中断完成的irq_exit中)的,如果任由这些执行流继续下午,那还叫panic吗?因此最好的办法就是停掉所有这一切!似乎复杂性还不 止这些,如果你在一个中断上下文中引发了一个panic,那么很显然,软中断便不会在irq_exit中被执行,因此,即使你没有在panic后停掉所有 的中断响应,软中断也不是每次panic后都会在中断上下文中被执行的,取决于panic是否在中断上下文中被引发。
        如果你想知道panic之后到底发生了什么,也不是特别复杂,事实上,panic之后的序列如下:
1.禁止抢占(如果内核编译时没有打开抢占,相当于什么都没有做);
2.打印信息和堆栈;
3.调用kexec逻辑;
4.通知其它的CPU停止所有工作;
5.调用panic通知链进行善后;
6.如果panic timeout被设置,则等待后重启机器;
7.如果panic timeout没有被设置,则进入"闪灯"状态,直到永远。
其 中最关键的是第4步,这里也是今后系统是否还会处理中断和软中断的关键,在详细解释之前,先说一下为何要通知其它CPU停止工作。因为panic在本 CPU被触发,而在多个CPU间共享的内核数据结构此时可能已经乱掉了,此时就要通知别的CPU在这一瞬间停止。那么停止需要做哪些工作呢?主要集中在和 对应CPU相关的外部总线以及中断控制器操作,典型的说就是关闭掉它们,等于说把这些CPU尽可能和外部事件隔离起来,这也是一种安全的做法,如果一下子 掉电,可能会在热重启后遇到电平不一致的问题,因此采用安全的关闭序列总是要好一些的。那么有没有直接一点的做法呢?当然有!
        如果我们设置机器重启的方式为冷重启(板子几乎都支持),那么就不存在电平不一致的情况了,此时就可以将CPU安全地一下子掉电,因此也就没有必要遵循安 全关闭序列来关闭CPU了,为了更高效,在明知系统马上就会重新启动的前提下(这很重要),根本没有必要关闭中断控制器,而此时的CPU便会继续响应中 断,是否会继续处理软中断取决于panic是否在非中断上下文中被触发。由于已经禁止了抢占且没有任何执行流会返回用户态,因此此时不可能发生task切 换,故而即便是软中断会被处理,也不会在softirqd上下文被处理,而是在irq_exit中的中断上下文被处理。
        一切就是这么惨!
        具体来讲,要想在panic之后还能响应中断,你需要设置一个内核启动参数:reboot=f,c。含义是强制(force)冷(cold)重启,此时不 会执行停止CPU本地APIC中断控制器的操作,要想继续处理软中断,请别在中断上下文panic,这就好像告诉某个人请别死一样,这是无法控制的。即便 能保证中断上下文不会panic,由于无法调度softirqd,在中断上下文中来不及处理(只有MAX_SOFTIRQ_RESTART次机会)的软中 断将会被彻底淹没。另外,非要让系统在panic继续执行中断响应和软中断处理是极其不对的想法,那样会破坏更多的内核数据结构,万一破坏了磁盘 cache/buffer,或者误写了某个地址/寄存器,后果将是不可预料的...一切就是这么惨,只因为内核panic!

第三部分:正确的做法

正 确的做法不是设置一个iptables策略等待外部远程触发SYSRQ,这意味着中断不能被关闭,且软中断必须被处理...正确的做法是在panic之后 尽可能马上重启,而在重启之前需要做点善后操作,当然,如果你配置了kexec,那更好,但是如果你不准备调试它,那就完全没必要。以下是正确的做法:
1.启动时设置reboot=f,c参数,panic后不会禁止中断控制器工作;
2.系统启动后,设置sysctl -w kernel.panic=5,争取马上重启系统;
3.注册一个panic通知链,向外以广播地址封装以太头,广播内核环形缓冲区的内容(包括堆栈等信息)。
为 何采用广播我要说一下,因为我不希望它发送ARP请求然后再等ARP回应,因为那会平添一次交互(由于ARP回应的处理在软中断中进行,既然不能保证 panic不在中断中被触发,就不能保证软中断一定会被执行),再者说,发给谁呢?诚然可以配置一个接收IP地址,但多一个配置不说,这个IP毕竟保存在 内存,只要是使用了多一点的内存,panic之后取到错误数据的可能性就更大,panic之后你要想办法使用最少的信息,虽然“发送数据包”这种事场面已 经够庞大了,但是也是没有办法。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1610428

相关文章
|
7月前
|
Android开发
GB28181设备控制和TeleBoot远程启动命令探究
源设备向目标设备发送设备控制命令,控制命令的类型包括球机/云台控制、远程启动、录像控制、 报警布防/撤防、报警复位、强制关键帧、拉框放大、拉框缩小、看守位控制、设备配置等。
107 0
|
1月前
|
安全 Linux 开发者
⭐⭐⭐⭐⭐Linux C/C++ 进程崩溃诊断以及有效数据收集:解锁代码问题快速定位与修复的方法
⭐⭐⭐⭐⭐Linux C/C++ 进程崩溃诊断以及有效数据收集:解锁代码问题快速定位与修复的方法
77 1
「WGCLOUD」指令下发后需要多长时间执行完成
「WGCLOUD」的指令下发后需要多长时间执行完成
「WGCLOUD」指令下发后需要多长时间执行完成
|
监控 Java 关系型数据库
【收集】【Linux】记录常用的操作指令 不定时更新
【参考资料】: 【1】www.cnblogs.com/fjzhang/p/1… 【2】www.51codefly.com/article/516 【3】www.cnblogs.com/liuchuanfen… 【4】www.cnblogs.com/ftl1012/p/h…
138 0
【收集】【Linux】记录常用的操作指令 不定时更新
H3C设备运行状态查询常用命令(建议收藏)
H3C设备运行状态查询常用命令(建议收藏)
569 0
|
监控 Linux 运维
使用audit工具常规命令监控系统访问文件
audit工具的作用 audit工具可以对文件使用进行监控,可以监控是哪个进程对文件进行读写执行和atrribute属性修改。在常规运维中有很多作用。 audit工具的安装和启动 Ubuntu使用apt-get audit。
2574 0