问题描述
我的朋友们一直在使用终端删除我的文件。所以请通过解释如何为rm
命令设置密码来帮助我。
最佳解决方法
没有简单的方法可以在rm
命令本身上设置这样的密码,不是没有很多代码破解,这可能会破坏apt-get
安装软件包和删除文件,并且必须输入密码一千次,或者可能会破坏对需要它的人的访问权限(像你一样,删除你自己的文件)。您可以通过拥有多个用户帐户和多个访问权限集来实现此目的,并限制对不同数据部分的访问,例如您的主目录,以便他们无法访问它。
(另一个选项是每个用户的个人用户帐户,然后是访问控制列表,详见Videonauth发布的其他答案)
这是核心问题 – 你让你的朋友使用你的系统。这有很多安全隐患 – “任何有物理访问权限的人都可以控制系统并执行任何任务”的概念是IT安全Mantra,这就是为什么你没有’share’物理系统访问,除了值得信赖的授权人
唯一真正理智的做法是不让你的朋友访问你的计算机,并给他们一个他们可以使用的’专用的”Guest”系统’,你并不真正关心这些文件。这是保证文件安全的最’secure’方式。
当然,如果这不是一个选项,那么你唯一真正安全的选择是配置多个用户帐户,每个用户一个,具有不同的主文件夹,并且不允许他们访问您自己的主目录或访问任何其他用户的家目录。然后将您不希望他们触摸的所有内容保存在您的主目录中,并且不要给他们sudo
访问权限,root
密码,或者与他们共享您的密码。
这是你如何做到这一点:
假设我的名字是”Foo”,我希望朋友用户”Bar”使用我的系统但不能访问我的文件。第一步是拒绝除了我以外的任何人访问我的主目录。这是为了允许其他用户不删除您的文件,但也阻止其他用户在您的主目录中窥探并查看您在主目录中有哪些类型的内容:
chmod 750 /home/Foo
第二步是为”Bar”创建一个用户帐户(不要在下面的括号中键入内容,仅供参考)。这样,我们可以确保他拥有自己独立的访问权限集:
sudo adduser --create-home --user-group --shell /bin/bash Bar
sudo passwd Bar
(set a temporary password - you will not see characters as you type though)
第三步是限制他们的主目录,这样任何人都无法窥探他们的文件。这只是让事情变得平等。
sudo chmod 750 /home/Bar
洗手,冲洗干净,然后对系统中的许多用户重复这些步骤。他们将无法访问您的文件,并且由于您不会授予他们管理员权限,因此他们无法在不尝试sudo
的情况下删除您的文件 – 因为您不允许这样做,他们可以’触摸你的东西。并且他们也无法在不成为超级用户的情况下看到您的文件,这在此不会发生。
总是记住这一点:通过让某人物理访问机器或一般访问,您将使您的文件和数据处于危险之中。这是IT安全领域的widely-accepted事实,并且仍然是如此。让您的朋友访问您的计算机将始终使您的数据处于危险之中,因此要么让他们自己的系统搞乱,要么只是不让他们访问您的计算机。
只是关于磁盘加密的说明
虽然磁盘加密可以很好地保护您的数据免受第三方的侵害,但存在局限性。
-
如果系统已启用,则磁盘已解密,因此您将面临风险。
-
有些系统破坏了磁盘加密方法。例如,某些Acer系统使用您的密码仅授权加密/解密并使用hard-coded密码,或使用容易破解的弱加密。
-
总是有一些方法可以进入’keys’,或者在系统关闭之后但在RAM数据为’gone’之前尝试从内存中提取它们。 (我不会深入研究这些,但这些风险确实存在)。
-
无论系统是否加密,对机器的物理访问都将使您的数据面临风险。不要向您不希望对系统提供完全访问权限的人员进行物理访问(或远程网络访问)。
虽然磁盘加密无法解决这些问题,但它为威胁行为者带来了额外的麻烦。作为坏人的人可能会放弃,如果它是加密的,或者他们可能会折磨你(排队强制性XKCD Security comic strip)。
因此,如果您的系统是加密的,但是您允许其他用户使用它,则要么他们有密码要解密,要么让您的笔记本电脑解密,这样他们就可以通过SSH进行身份访问或拥有物理访问权限。在这两种情况下,都很糟糕。
也就是说,如果您的系统未加密,则此部分与您无关。
次佳解决方法
这可能与rm
命令无关,因为有一些简单的方法可以在不使用文件的情况下删除文件。如果问题是您的朋友无意中滥用了rm
命令,那么限制使用该命令或使其以不同方式工作的解决方案可能会有所帮助。相反,如果问题是你的朋友故意以你不想要的方式处理你的数据,then you need to implement actual security measures,并且没有专注于rm
命令本身(或任何离散命令集)的解决方案将保证你的安全。
你需要控制访问权限,还是只是防止诚实的错误?
假设您的朋友知道您不希望他们删除您的文件,有两种可能:
-
他们可以故意这样做。在这种情况下,您的朋友故意删除您的文件,您甚至不相信他们会尝试遵守您在使用计算机时如何处理数据的愿望。这个问题的唯一解决方案是使用实际有效的安全措施,正如Thomas Ward详细解释的那样。通常最好的措施是防止他们使用您的计算机。但是让他们使用自己的用户帐户可以提供一些保护。
-
他们可能是错误地做到了。在这种情况下,你的朋友是非常accident-prone,他们继续运行他们希望他们没有的
rm
命令。他们希望尊重你和你的数据,但在实践中这样做真的很糟糕,因为他们继续运行错误的命令,删除错误的文件……或类似的东西。虽然我很高兴相信这就是正在发生的事情,但我提醒你不要假设那些在你告诉他们停止数据后不断删除数据的人没有恶意。此外,即使他们的意图很好,给他们单独的用户帐户仍然是阻止他们删除文件的最简单的方法,除了不允许他们使用您的计算机。
如果情况真的是#2 – 你的朋友不是想删除你的文件而只是需要帮助而不是意外地删除它们,而他们意外删除它们的唯一方法是无意中滥用少量命令(如rm
) )他们在使用时遇到特别麻烦 – 然后the techniques in Videonauth’s答案可能会有所帮助。但您必须了解它们不是安全措施,因为rm
命令只是删除文件的众多简单方法之一。请参阅下文了解详情。
我建议你问自己,“我的情况基本上是否与我使用rm
错误的使用我的计算机的人相比,我的情况基本相同?”
如果答案是否定的,那么这是信息安全问题,您需要阻止您的朋友使用您的用户帐户。如果答案是肯定的,那么如果您误用了rm
,那么您可以使用相同的方法:
-
教育。你的朋友需要知道他们在做什么以及如何避免它。
-
界面变化。在不删除实际删除文件的能力(需要单独的用户帐户)的情况下,您可以通过单独运行
rm file
而不进行任何进一步操作而不小心删除file
,从而使意外删除文件变得更加困难。 Videonauth’s answer给出了一种方法。在这个答案中,我提出另一个。
但即使你的朋友没有尝试做任何错误,你仍然应该考虑让他们使用自己独立的用户帐户。这仍将解决问题 – 保护数据免遭故意破坏的相同安全措施也将保护其免受无意破坏。即使没有恶意,如果有人继续做你不希望他们做的事情,那么你就不能相信他们不要做那件事。
在删除之前进行rm
提示可以帮助防止出现一些错误。
为了帮助人们避免使用rm
意外删除文件,您可以使rm
成为实际运行rm -i
的shell alias。将-i
标志传递给rm
会导致它在删除每个文件之前提示用户(请参阅man rm
)。
您可以通过将alias rm='rm -i'
添加到.bash_aliases
或.bashrc
文件来执行此操作(对于您的用户帐户)。有关详细信息,请参阅如何创建一个永久“alias”?和我如何创建一个永久的Bash别名?。这将对您新打开的bash shell生效。
这没有提供实际的安全性,也没有防止错误的万无一失,因为:
-
出现提示时,他们可以选择继续删除。
-
它们可以通过多种方式绕过别名,包括运行
/bin/rm
或解压缩它(unalias rm
)。 -
There are many situations where alias expansion does not occur,在这些情况下,
rm
将不会与-i
一起运行。 -
他们仍然可以使用任何技术删除文件,这样做不需要
rm
(与Videonauth’s approach一样 – 见下文)。 -
它们仍然可以在不删除任何文件的情况下损坏数据,例如通过覆盖它们或以其他方式更改其内容(Videonauth的方法也是如此)。
但是如果你不需要实际的安全性(见上文),那么这可能就是你要走的路。与阻止您的朋友使用system-provided rm
命令的方法相比:
-
将
rm
别名化为rm -i
在防止错误方面效果较差 – 直到他们继续使用其他技术来删除文件。此时,让他们不使用rm
将完全无效,即使他们没有尝试做任何错误,因为他们可能会使用unlink
(或任何无数其他删除文件的命令)同样没有思想。 -
另一方面,因为别名扩展仅在某些情况下发生 – 粗略地说,shell的普通交互使用 – 你的朋友可能会认为当他们没有真正提示时会被提示(因为命令是在例如,一个脚本,或者从另一个shell发出的脚本)。 Videonauth’s way没有这个问题,这是该方法相对于
alias rm='rm -i'
的客观优势。 -
当脚本运行时,除非故意编写使用别名,否则不会扩展别名。这意味着将
rm
别名化为rm -i
不太可能破坏任何东西。这是alias rm='rm -i'
的客观优势。
rm
无法做任何其他完美普通程序无法做到的事情。
rm
真的没什么特别之处。它是一种方便的self-documenting方式来删除文件,因此限制对它的访问可能会破坏许多依赖它的脚本。但它远不是删除文件的唯一方法 – 它只是一个普通的程序。
一些命令执行一些有限(非root)用户在不运行它们的情况下无法执行的任务。例如,sudo
允许您在检查后以另一个用户身份运行程序,以确保您可以这样做。 passwd
编辑存储用户密码的数据库,但只允许您更改自己的密码(除非您是root用户,在这种情况下您可以更改任何人的密码)。
/usr/bin/sudo
和/usr/bin/passwd
可以这样做,因为它们具有the setuid bit设置,如运行ls -l
时出现在最左列中的s
所示:
ek@Io:~$ type -a sudo passwd rm
sudo is /usr/bin/sudo
passwd is /usr/bin/passwd
rm is /bin/rm
ek@Io:~$ ls -l /usr/bin/sudo /usr/bin/passwd /bin/rm
-rwxr-xr-x 1 root root 60272 Feb 18 2016 /bin/rm
-rwsr-xr-x 1 root root 54256 Mar 29 2016 /usr/bin/passwd
-rwsr-xr-x 1 root root 136808 Aug 17 09:20 /usr/bin/sudo
请注意/bin /rm没有s:它的权限是-rwxr-xr-x,而/usr /bin /passwd和/usr /bin /so则是-rwsr-xr-x。这使得无论谁运行passwd或sudo,它实际上都以root用户身份运行,因为root是可执行文件的所有者。 (还有一个setgid位,当设置时,会使可执行文件与其组所有者的组标识一起运行,而不是与调用者的组标识一起运行。)
除了尚未发现的任何安全漏洞(或已发现但尚未修补的安全漏洞),sudo
和passwd
都是安全的,因为这些实用程序是非常谨慎编写的,因此它们只能执行调用者应该执行的操作被允许做。
/bin/rm
无法正常工作。它不是setuid,因为它不需要。 Directory permissions(和occasionally file permissions)控制用户可以删除的文件,并且不需要成为root用户。为了清楚起见,请不要在rm
上设置setuid位。安全隐患将是灾难性的,从那时起,无论谁运行rm
,它就像root运行它一样! (像sudo
和passwd
这样的实用程序会检查谁正在运行它们并在执行之前检查是否允许某些内容; rm
不会这样做。)
检查是否在可执行文件上设置了setuid(或setgid)位将告诉您是否限制可以运行它的人是否有机会提高安全性。非setuid(或setgid)的可执行文件没有任何特殊状态,任何人都可以简单地复制它们并运行副本,从另一台机器上带来自己的副本,编写执行相同操作的脚本或程序,或者使用另一个程序来做。
删除没有rm
的文件
在Ubuntu中删除没有rm
的文件的明显方法是导航到图形文件浏览器中的位置(Nautilus,如果您使用的是Unity或GNOME Shell)并删除该文件。还有许多命令可用于从终端删除文件,而无需使用rm
。
例如,要删除当前目录中名为foo.txt
的文件,以下命令(在Ubuntu上运行out-of-the-box并且不需要访问rm
)将实现此目的。 (可以肯定的是,在删除/bin/rm
之后,我在仅安装了标准系统实用程序的a 16.04 minimal system上测试了它们。)
-
unlink foo.txt
-
busybox rm foo.txt
-
perl -e 'unlink("foo.txt")'
-
python3 -c 'import os; os.remove("foo.txt")'
(旧版本中python
代替python3
)
当然,这份清单还远未完成。没有完整的此类命令列表。防止文件删除是单独的用户帐户和文件和目录权限存在要实现的事情之一。他们的工作非常好,以防止它。相反,更改rm
命令(使其需要密码或以任何其他方式)或限制对rm
的访问不会完全阻止它。
第三种解决方法
您可以通过以下行更改/bin/rm
命令的权限,这将阻止它在没有sudo访问权限的情况下执行:
sudo chmod 750 /bin/rm
这特别阻止它们使用系统提供的rm
命令。您应该知道它不会阻止它们以其他方式删除文件。
为了防止它们使用rmdir
命令(这是删除目录的常用方法),您可以在其可执行路径上以相同的方式设置权限:
sudo chmod 750 /bin/rmdir
提醒一下,你也只能将此命令与sudo权限一起使用。
如果您不喜欢它或更改其他问题,请使用755
进行chmod
正如@muru指出的那样,上面是一个非常粗糙的解决方案,甚至可能会破坏未在root帐户上运行的系统服务。因此,我在这里添加另一个选项,使用ACL(访问控制列表)来做同样的事情,可能更安全(good to read into as well,你可以跳过启用部分,因为ACL现在通常安装在Ubuntu系统上):
因此,仅针对您想要阻止的用户执行与上述相同的操作
sudo setfacl -m u:<user-name>:- /bin/rm /bin/rmdir
只需将<user-name>
替换为您要阻止使用这些文件的实际用户名。
与chmod
一样,使用setfacl -m
防止特定用户运行rm
和rmdir
仅适用于那些system-provided命令。它不会阻止他们删除Nautilus中的文件和文件夹或使用其他终端命令。
说明:
-
-m
标志表示修改文件ACL。 -
变更的第一部分,
u
代表用户。它可以为用户提供以下值u
,为组提供g
,为所有其他提供o
-
中间部分
<user-name>
可以根据您想要更改的内容来保留实际的用户名或组名。要设置整体更改,请将其留空。 -
第三部分包含您要设置的权限类型。在这个示例中,我们想要设置任何权限,所以我们放置
-
,它也可以包含以下字母r
用于读取权限,w
用于写入权限,x
用于执行。
第四种方法
这是一个非常简单的答案,并会在不提供密码的情况下随意使用rm命令阻止某人。它不是一个安全的解决方案,您应该在其他答案中提出一些替代建议。
但是,您可以使用别名来更改rm命令的行为方式。尝试:
alias rm="sudo -l >/dev/null && rm"
这样做的是当有人输入rm命令时,它运行sudo -l命令。此命令强制用户输入其密码。如果他们做对了,它会列出他们的权限(我们丢弃这个输出)并以状态0退出,如果他们弄错了,就会出现错误。
然后我们使用”&&”跟随sudo命令,该命令退出以下命令 – 在这种情况下,只有当前一个命令以状态0退出时才显示”rm” – 即他们获得了正确的密码。
要使其永久化,请在~/.bashrc
中包含别名命令。
请注意,这很容易被击败(例如,他们可以简单地键入/bin/rm
。
第五种方法
有时它不是我们的朋友,我们是我们自己最坏的敌人
我已经编写了一个脚本来密码保护rm
就像请求的OP一样,但也进行了编辑以防止你意外删除:
-
/
-
/家
-
/箱
编辑:2017年3月5日 – 更改检查是否在终端中运行的方法。
创建脚本
使用gksu gedit /usr/local/bin/rm
并复制以下行:
#!/bin/bash
tty -s;
if [ "0" == "$?" ]; then Terminal="Y"; else Terminal="N"; fi
if [ $Terminal == "Y" ] ; then
# Running from terminal don't allow delete of / or /toplevel directory even if sudo
for i in ${@:1}
do
# Skip options -i -r -v -d
if [[ ${i:0:1} != "-" ]] ; then
# if parameter doesn't begin with '-' it's file or directory, so get real path.
fullname=$(realpath "$i" 2>&1) # No error messages if file doens't exist
# We must have at least two `/` in the full path
levels=$(echo "$fullname" | tr -cd '/' | wc -c)
if (( $levels == 1 )); then # Test for 1, will be zero when file doesn't exist.
echo "Attempting to remove top level directory '$fullname'"
echo "Use 'sudo /bin/rm $@' instead."
exit 1 # error
fi
fi
done
fi
if [[ $(id -u) != 0 ]]; then # Only non-root processes enter password (ie "sudo rm ..." is ok)
if [ $Terminal == "Y" ] ; then
# Only running from a terminal needs password (ie not cron)
# log rm usage to /var/log/syslog
PARENT_COMMAND="$(ps -o comm= $PPID)"
logger "$PARENT_COMMAND"" - rm command was used on file: ""$fullname"
# Get password
Password=$(zenity --password --title="Password for rm")
encryptPassword=$(echo -n "$Password" | md5sum)
echo "md5sum: $encryptPassword" # Comment out after viewing one time and updating line below.
if [[ "$encryptPassword" != "d2c30dc65e59558c852ea30b7338abbe -" ]]; then
echo "Invalid password!"
exit 1
fi
fi # non-terminals can't enter password.
fi # root doesn't need to enter password.
# Call REAL rm command with parameters passed to this wrapper sript
/bin/rm "$@"
exit 0
将密码”WE2U”更改为您喜欢的任何内容并保存文件。
将新的rm
脚本标记为可执行文件
使用以下方法将新rm
脚本标记为可执行文件:
sudo chmod +x /usr/local/bin/rm
这个怎么运作
除非密码是WE2U,否则第一次运行脚本时,您将获得”invalid password”,并显示您输入的密码的加密密钥。将此加密密钥从终端复制并粘贴到脚本中。然后注释掉在终端上显示加密密钥的回显线。
因为列表中的路径/usr/local/bin
比/bin
高,所以命令rm
被调用。获得有效密码后,它会调用/bin/rm
进行实际删除。
正如托马斯·沃德在另一个答案中指出的那样,如果你要做一个sudo apt-get install ...
,你可能会被要求输入密码一千次。该脚本检查是否使用了sudo
并且不要求输入密码。此外,如果从GUI应用程序中调用rm
,则不需要密码。
每次使用终端手动调用rm
时,脚本都会调用logger
进行记录。命令用法记录到/var/log/syslog
。
第六种方法
另一种方法是在non-root用户无权访问的目录中创建任何重要文件的备份副本。您可以使用rsync
或unison
自动同步它们,只需确保备份目标路径中至少有一个目录由root和mode 700拥有。这将导致所有文件都有两个副本。只创建一个guest用户供他们使用会更安全,除非你需要记住在给他们的计算机或让他们无人看管之前总是锁定或注销。
第七种方法
不是你正在寻找的问题的直接答案,但是:
如果您的朋友正在使用rm
命令删除您的文件,那么您的朋友要么不称职,要么是混蛋,要么他们是BOFH想要教你不要让你的会话登录并无人看管。在所有情况下,解决方案都是相同的:不要让您的会话登录并且无人值守。
这样做的好处是,无论何时升级或获取新系统,都不需要记住对系统进行特殊更改,并且还可以防止脚本和您使用的其他依赖于按预期行事的命令以不可预测的方式失败。
它还具有阻止”friends”进入下一步的优势。你是否也想要”password protect” mv
命令,如果他们决定将文件移动到/dev /null,当他们发现一个简单的删除不能做他们想要的东西?当你在这样的游戏中时,唯一的胜利就是不玩。
参考资料