9 个 危险的 Bash 命令

我依然记得第一次学会使用命令行工具的感觉:只要在黑乎乎的窗口里敲几个字母,就可以访问任何文件、执行任何程序、完全控制整个系统,仿佛上帝视角,无所不能。同时还记得那随之而来的恐惧,万一犯错的话会造成无法挽回的结果。

我并不是一个系统管理员,但是多年来,我使用过很多基于 Linux/UNIX 的系统,我不止一次遇到这样的情况:在按回车键之前,我犹豫再三,不断重新考虑将要执行的操作。

接下来我想分享一些你根本不应该使用的命令,或者至少是应该非常小心使用的命令。如果你是 bash 命令的新手,我希望你能学到一些新东西。如果你是 bash 专业人员,可以将本文作为练习,在阅读解释之前先预测下结果。

说明:其中一些命令是我自己费了好大的周折才学会的,但大多数都是我不经意间学到的,比如在这篇旧文中提到的。

在开始之前,最后一次警告:

不要在重要的系统上执行这些命令!

1 破坏性的目录切换

我决定不从经典的 rm -rf 说起,而是先说它的一个变种:

alias cd='rm -rf'

命令详解

  • alias 用于声明命令的别名或快捷方式。语法是 alias alias_name="command_to_run"

  • cd 是别名的名称

  • rm -rf 是实际执行的命令。它可不是 "read mail, -realfast" 这么温柔,而是 "不做询问,删除指定目录及里面的所有内容"。

因此,当你离开电脑时,如果一个心怀不轨的人在你的 bash窗口上添加了这个别名,然后你通过文件系统进行 cd 操作,你很快就会发现哪里不对劲了……

幸运的是,alias 只在当前 shell 会话期间暂时可用,除非它被添加到终端会话开始时加载的文件之一,即 ~/.bashrc

如何预防

在添加新别名时,避免添加这个别名并复查命令即可。你可以用 alias 命令检查存在哪些别名,并使用unalias alias_name删除别名。

为了防止在不知情的情况下删除文件,你可以将以下别名添加到你的~/.bashrc 文件中:

alias rm='rm -i'

这会让 bash 在删除某些内容之前总是询问你,即使 rm 命令是作为另一个别名添加的。
提示:在根路径已经不能这么直接用这个命令了,需要加上 --no-preserve-root 参数。

2 吞噬内存

你没看错,下面这个是有效的 bash 命令:

:(){:|: &};:

命令详解

简而言之它是:无终止条件的递归。定义了一个名为 : 的函数,函数在自己的定义中两次调用自己。命令的结尾处开始调用该函数。当我们把它写在单独的行并重新命名,就看得清楚了:

evil () {
  evil|evil &
}
evil

一旦执行,它会快速**自己,耗光你的所有内存和 CPU资源(也称为 fork 炸弹)。它可以搞垮你的整个系统,因此它是一个拒绝服务攻击的例子。令人惊讶的是,这样的攻击竟然可以用一个只有 12 字节的命令来执行!

如何预防

如果你正在使用迭代或递归的 bash 函数,请务必反复检查是否有适当的终止条件,并使用安全的环境进行测试。

因为“fork 炸弹”启动的进程数量是无限的,所以保护系统的惟一方法是限制本地用户可以运行的进程数量。你可以通过编辑 /etc/security/limits.conf 来做到这一点。一个用户可以同时处理大约 200 - 300 个进程,所以限制到 2000 个进程可以保护你的系统免受 fork 炸弹的攻击,同时又不会过于限制相应的用户。

3 无记忆擦除

dd if=/dev/zero of=/dev/sda

命令详解

  • dd 是将数据从一个文件或设备**到另一个的命令

  • if= 指定源, /dev/zero 是无限制的零字节源文件

  • of= 指定目标位置, /dev/sda 是磁盘驱动或卷

你知道会发生什么。这是擦除整个磁盘内容的一种非常好的方法,也是丢失大量数据的一种非常快的方法。

如何预防

不幸的是,这里不像 rm,它没有 -i 标志,所以我唯一的建议是再次检查你在 dd 命令中指定的设备是否正确。如果对你来说有风险,就不要使用 dd 命令。

你可以用这个别名来彻底禁用 dd 命令:

alias dd='echo "no dd command available"'

现在再在系统里执行 dd 命令,只会打印 no dd command available

4 无法恢复

上面的命令还有如下这种形式:

for i in {1..10};do dd if=/dev/urandom of=/dev/sda;done

命令详解

它将会用随机字节覆盖整个磁盘十次,并将恢复数据的可能性降至最低。

如何预防

由于这也使用了 dd 命令,请参考前面一节的建议。

5 丢失未提交的更改

git reset --hard

命令详解

  • git reset 将 git 仓库的当前 HEAD 重置到最后一次(或指定某个)提交的状态

  • --hard 重置索引和工作区。自最后一次提交以来对工作区中被跟踪文件的任何更改都会被丢弃。

换句话说:它会丢弃所有未提交的更改。因为 git 不跟踪它们,所以无法恢复。

如何预防

简单来说就是不要使用 --hard 标志。如果一定要这么做:在重置之前,务必再次检查是否有想保留的任何本地更改。我建议只在 git status 的输出为空,或者你百分比确定要清除所有未提交的数据时才进行硬重置。

6 压缩不慎,文件尽毁

tar -czvf /path/to/file archive.tgz

# 正确写法
tar -czvf archive.tgz /path/to/file

命令详解

  • tar -czvf 命令用于压缩文件,使用 gzip,显示详细文件列表,并使用指定存档文件。

  • archive.tgz 是要创建的存档文件的名称

  • /path/to/file 要压缩的文件的路径

这里文件的顺序很重要。如果第一个文件是你想要压缩的文件,那么它将被完全破坏,因为 tar 通过覆盖第一个给定的文件开始创建归档,然后才发现第二个给定的文件不存在。如果你想备份一个文件,并且使用了错误的参数顺序,那就杯具了……

如何预防

不要把所有标识参数都放在一起,你可以分开 -f 标识,使用全名来提醒自己,哪个才是归档文件,像这样:

tar -czv --file archive.tgz /path/to/file/to/compress

7 权限错配

chmod -R 777 /

# 正确用法
chmod -R 777 ./

命令详解

  • chmod -R 递归地设置文件权限

  • 777 权限模式值(允许所有操作)

  • ./ 目标路径或文件

如果你没注意目标路径,而无意中选择了根目录而不是当前目录,那么你会搞乱整个系统的所有权限,从而无法使用。

如何预防

为了避免上述拼写错误造成的后果,你可以用下面这个别名:

alias chmod='chmod --preserve-root'

这样就会始终拒绝对根目录进行递归更改。

8 小心 root 权限

这同样适用于对所有者的更改:

chown -R root:root /

# 正确用法
chown -R root:root ./

命令详解

  • chown -R 递归地设置新所有者

  • root:root 新的所有者:组

  • ./ 目标路径或文件

同样,这也会搞乱所有文件,最后可能要重装系统。

如何预防

chmod 类似,也可以给 chown 设置别名:

alias chown='chown --preserve-root'

这也会拒绝对根目录进行递归更改。

9 加密导致的损坏

fsck -y /dev/sda

命令详解

  • fsck 执行文件系统检查

  • -y 这个标志表示始终尝试自动修复检测到的文件系统损坏

  • /dev/sda 要检查的磁盘卷

这通常不会出问题,除非你的磁盘卷被加密。在这种情况下,尝试通过 fsck 修复会完全破坏它。文件系统只有在解密后才能检查。

如何预防

仅对普通的未加密卷时使用 fsck 命令。为了防止由于尝试自动修复错误而造成的损坏,请不要使用 -y 标志。


总结

我们看到了,通过输入一个简单的命令来销毁数据或使整个系统变得不可用,非常容易。

最后我发现,最好的保护措施就是 知道你输入了什么执行前再次检查 是否有拼写错误!永远不要只是**和粘贴代码——尤其是对于 bash 命令!还有:经常备份。

上面的大多数命令都需要 root 权限才能执行。所以作为 root 用户,一定要小心!

如果你还知道一些其他的危险命令,也请在评论区分享给大家。


免责声明:尝试以上命令对系统造成的损害,本人概不负责。请使用虚拟机等安全环境进行测试。我已经警告过你了。


Practice makes perfect.

讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!