运行 shell 脚本时,如何防止其覆盖或截断文件?
如果应用程序运行时它使用的共享库之一被写入或截断,则应用程序将崩溃。移动文件或使用“rm”批量删除它不会导致崩溃,因为操作系统(在本例中为 Solaris,但我认为在 Linux 和其他 *nix 上也是如此)足够聪明,不会删除与当任何进程打开该文件时。
我有一个执行共享库安装的 shell 脚本。有时,它可用于重新安装已安装的共享库的版本,而无需先卸载。由于应用程序可能正在使用已安装的共享库,因此脚本足够智能以 rm 文件或将它们移开(例如,当我们知道没有应用程序时 cron 可能会清空的“已删除”文件夹),这一点很重要将运行),然后再安装新的,这样它们就不会被覆盖或截断。
不幸的是,最近有一个应用程序在安装后就崩溃了。巧合?很难说。这里真正的解决方案是切换到比旧的巨大 shell 脚本更强大的安装方法,但在切换之前最好有一些额外的保护。有没有什么方法可以包装 shell 脚本以防止其覆盖或截断文件(理想情况下会大声失败),但仍允许移动或 rm'd?
标准 UNIX 文件权限不起作用,因为您无法区分移动/删除与覆盖/截断。别名可以工作,但我不确定哪些命令需要别名。我想象类似 truss/strace 的东西,除了在每个操作之前它会检查过滤器是否真正执行它。我不需要一个即使针对故意恶意脚本也能工作的完美解决方案。
If while an application is running one of the shared libraries it uses is written to or truncated, then the application will crash. Moving the file or removing it wholesale with 'rm' will not cause a crash, because the OS (Solaris in this case but I assume this is true on Linux and other *nix as well) is smart enough to not delete the inode associated with the file while any process has it open.
I have a shell script that performs installation of shared libraries. Sometimes, it may be used to reinstall versions of shared libraries that were already installed, without an uninstall first. Because applications may be using the already installed shared libraries, it's important the the script is smart enough to rm the files or move them out of the way (e.g. to a 'deleted' folder that cron could empty at a time when we know no applications will be running) before installing the new ones so that they're not overwritten or truncated.
Unfortunately, recently an application crashed just after an install. Coincidence? It's difficult to tell. The real solution here is to switch over to a more robust installation method than an old gigantic shell script, but it'd be nice to have some extra protection until the switch is made. Is there any way to wrap a shell script to protect it from overwriting or truncating files (and ideally failing loudly), but still allowing them to be moved or rm'd?
Standard UNIX file permissions won't do the trick because you can't distinguish moving/removing from overwriting/truncating. Aliases could work but I'm not sure what entirety of commands need to be aliased. I imagine something like truss/strace except before each action it checks against a filter whether to actually do it. I don't need a perfect solution that would work even against an intentionally malicious script.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以通过 I/O 重定向来防止脚本被覆盖,方法是
通过
cp
防止覆盖等更难。我的倾向是重置脚本的PATH
以便使用仅包含一个条目的PATH
运行,这是一个“有福的”目录,您可以在其中放置您知道安全的命令。例如,这可能意味着您的cp
版本始终使用--remove-destination
选项(可能是 GNU 主义)。无论如何,您都可以安排脚本仅执行受祝福的目录中的命令。然后,您可以单独审查每个此类命令。如果您可以阻止脚本通过绝对路径名执行命令,那就太好了,但我不知道该怎么做。如果您在常规目录中进行安装,
chroot
监狱可能没有帮助,除非您进行大量环回安装以使这些目录可见。如果您要安装的目录包含危险命令,我不知道如何才能完全保护自己免受它们的侵害。顺便说一句,我尝试了解
install(1)
是否在安装前删除了目标,但没有成功。学习起来会很有趣。You can prevent a script from overwriting through I/O redirection by
Preventing overwriting by
cp
and the like is harder. My inclination would be to reset thePATH
for the script to run withPATH
containing just a single entry, a "blessed" directory where you place commands that you know are safe. This might mean, for example, that your version ofcp
is arranged always to use the--remove-destination
option (probably a GNU-ism). In any case, you arrange for the script to execute only commands from the blessed directory. You can then vet each such command individually.It would be good if you could prevent a script from executing a command by absolute pathname, but I don't know how to do that. If you are doing installations in your regular directories, a
chroot
jail probably does not help unless you do a lot of loopback mounting to make those directories visible. And if the directories into which you're installing contain dangerous commands, I don't see how you can protect yourself against them completely.Incidentally, I tried and failed to learn if
install(1)
removes the desitination before installing. It would be interseting to learn.我猜是 Bash 脚本?剧本很长吗?如果没有,您可以手动执行此操作:
但我认为您正在寻求一种方法来将其包装在脚本中。您当然可以使用 strace 监视文件写入,但据我所知,它没有中断它们的功能,除非您使用规则等设置某种入侵检测系统。
但说实话,除非它是一个巨大的脚本,否则可能会更多麻烦大于其价值
Bash script I presume? Is the script very long? If not, you can do this manually:
But I think you're asking for a way to wrap this around the script. You can certainly monitor the file writes with strace but AFAIK it doesn't have the functionality to interrupt them, unless you set up some sort of Intrusion Detection System with rules etc.
But to be honest, unless it's a huge script, that's probably more trouble than it's worth
编写您自己的 safe_install() 函数并确保它们是唯一使用的方法。如果您确实需要确定,请运行两个进程。一个将有权进行更改,而另一个将提前放弃所有权限并告诉另一个脚本执行实际的磁盘工作。
Write your own safe_install() functions and make sure they're the only methods used. If you really need to be sure, run two processes. One would have permissions to make changes and the other would drop all privileges early and tell the other script to do the actual disk work.