如何防止意外重启Linux(基于systemd)
从 https://access.redhat.com/solutions/1580343 看到的,觉得很有趣,记录一下。
说是有一个 RedHat 的客户提出需求:为了防止意外重启Linux,要求root用户明确地执行某条命令后才允许对Linux进程重启操作。
我们都知道systemd linux中的reboot是基于 reboot.target
来实现的,因此最直观的做法应该就是 mask 掉这个target了.
lujun9972:~/ $ sudo systemctl mask reboot.target [sudo] lujun9972 的密码: Created symlink /etc/systemd/system/reboot.target → /dev/null. lujun9972:~/ $ sudo systemctl reboot Failed to reboot system via logind: Access denied Failed to start reboot.target: Unit reboot.target is masked. lujun9972:~/ $ reboot now Failed to write reboot parameter file: 权限不够 lujun9972:~/ $ sudo reboot now Failed to talk to init daemon.
然后 RedHat 工程师玩出了另一种花样(下面内容摘自于https://access.redhat.com/solutions/1580343):
创建一个 unit 文件
/etc/systemd/system/reboot-guard.service
[Unit] Description=Reboot Guard [Service] ExecStart=/bin/true [Install] RequiredBy=shutdown.target
这一步是核心操作了,由于
/bin/true
执行后立即停止,因此这个被shutdown.target
依赖的单元被显示停止,那么shutdown.target
单元本身也就跟着立即停止了。再创建一个 unit 文件
/etc/systemd/system/start-reboot-guard.service
[Unit] Description=Start Reboot Guard [Service] ExecStart=/bin/systemctl enable reboot-guard [Install] WantedBy=multi-user.target
这一步保证Linux启动后自动enable reboot-guard 服务
- 执行
systemctl daemon-reload
重新加载配置 - 执行
systemctl enable reboot-guard start-reboot-guard
启用新服务 再尝试重启就会失败了
[root]# systemctl reboot Failed to issue method call: Transaction contains conflicting jobs 'stop' and 'start' for reboot.target. Probably contradicting requirement dependencies configured. [root]# shutdown -h now Failed to issue method call: Transaction contains conflicting jobs 'stop' and 'start' for poweroff.target. Probably contradicting requirement dependencies configured. Broadcast message from root@example.com on pts/1 (Mon 2015-08-17 13:37:10 EDT): The system is going down for power-off NOW!
如果需要重启,那么只需要先执行
systemctl disable reboot-guard
禁止 reboot-guard 命令即可[root]# systemctl poweroff Failed to issue method call: Transaction contains conflicting jobs 'stop' and 'start' for poweroff.target. Probably contradicting requirement dependencies configured. [root]# systemctl disable reboot-guard.service rm '/etc/systemd/system/shutdown.target.requires/reboot-guard.service' [root]# systemctl poweroff Broadcast message from root@example.com on pts/1 (Mon 2015-08-17 13:37:50 EDT): The system is going down for system halt NOW! [ OK ] Started Show Plymouth Power Off Screen. [ OK ] Started Restore /run/initramfs. [ OK ] Stopped LSB: Bring up/down networking. Stopping Network Manager... [ OK ] Stopped Network Manager. ... [ OK ] Reached target Unmount All Filesystems. [ OK ] Stopped target Local File Systems (Pre). Stopping Remount Root and Kernel File Systems... [ OK ] Stopped Remount Root and Kernel File Systems. [ OK ] Reached target Shutdown. Cannot finalize remaining file systems and devices, giving up. dracut Warning: Killing all remaining processes Powering off. [ 4653.288570] Power down.